From 454205fc27cac4c5ffe00d559021cb8c8467c208 Mon Sep 17 00:00:00 2001
From: Lloyd Junbong Lee <lloyd@zoyi.co>
Date: Fri, 13 May 2016 15:27:37 +0900
Subject: [PATCH 1/2] Add new SocketOptionBuilder which helps creating
 IO.Option as builder pattern.

---
 src/main/java/io/socket/client/IO.java        |  17 +
 .../io/socket/client/SocketOptionBuilder.java | 200 +++++++++++
 .../client/SocketOptionBuilderTest.java       | 337 ++++++++++++++++++
 3 files changed, 554 insertions(+)
 create mode 100644 src/main/java/io/socket/client/SocketOptionBuilder.java
 create mode 100644 src/test/java/io/socket/client/SocketOptionBuilderTest.java

diff --git a/src/main/java/io/socket/client/IO.java b/src/main/java/io/socket/client/IO.java
index 06912a04..99052528 100644
--- a/src/main/java/io/socket/client/IO.java
+++ b/src/main/java/io/socket/client/IO.java
@@ -94,5 +94,22 @@ public static class Options extends Manager.Options {
          * Whether to enable multiplexing. Default is true.
          */
         public boolean multiplex = true;
+
+        /**
+         * <p>
+         *   Retrieve new builder class that helps creating socket option as builder pattern.
+         *   This method returns exactly same result as :
+         * </p>
+         * <code>
+         * SocketOptionBuilder builder = SocketOptionBuilder.builder();
+         * </code>
+         *
+         * @return builder class that helps creating socket option as builder pattern.
+         * @see SocketOptionBuilder#builder()
+         * @see SocketOptionBuilder#builder(Options)
+         */
+        public static SocketOptionBuilder builder() {
+            return SocketOptionBuilder.builder();
+        }
     }
 }
diff --git a/src/main/java/io/socket/client/SocketOptionBuilder.java b/src/main/java/io/socket/client/SocketOptionBuilder.java
new file mode 100644
index 00000000..a23febe3
--- /dev/null
+++ b/src/main/java/io/socket/client/SocketOptionBuilder.java
@@ -0,0 +1,200 @@
+package io.socket.client;
+
+import javax.net.ssl.HostnameVerifier;
+
+
+/**
+ * Convenient builder class that helps creating
+ * {@link io.socket.client.IO.Options Client Option} object as builder pattern.
+ * Finally, you can get option object with call {@link #build()} method.
+ *
+ * @author junbong
+ */
+public class SocketOptionBuilder {
+  /**
+   * Construct new builder with default preferences.
+   * @return new builder object
+   * @see SocketOptionBuilder#builder(IO.Options)
+   */
+  public static SocketOptionBuilder builder() {
+    return new SocketOptionBuilder();
+  }
+
+
+  /**
+   * Construct this builder from specified option object.
+   * The option that returned from {@link #build()} method
+   * is not equals with given option.
+   * In other words, builder creates new option object
+   * and copy all preferences from given option.
+   *
+   * @param options option object which to copy preferences
+   * @return new builder object
+   */
+  public static SocketOptionBuilder builder(IO.Options options) {
+    return new SocketOptionBuilder(options);
+  }
+
+
+  private final IO.Options options = new IO.Options();
+
+
+  /**
+   * Construct new builder with default preferences.
+   */
+  protected SocketOptionBuilder() {
+    this(null);
+  }
+
+
+  /**
+   * Construct this builder from specified option object.
+   * The option that returned from {@link #build()} method
+   * is not equals with given option.
+   * In other words, builder creates new option object
+   * and copy all preferences from given option.
+   *
+   * @param options option object which to copy preferences. Null-ok.
+   */
+  protected SocketOptionBuilder(IO.Options options) {
+    if (options != null) {
+      this.setForceNew(options.forceNew)
+          .setMultiplex(options.multiplex)
+          .setReconnection(options.reconnection)
+          .setReconnectionAttempts(options.reconnectionAttempts)
+          .setReconnectionDelay(options.reconnectionDelay)
+          .setReconnectionDelayMax(options.reconnectionDelayMax)
+          .setRandomizationFactor(options.randomizationFactor)
+          .setTimeout(options.timeout)
+          .setTransports(options.transports)
+          .setUpgrade(options.upgrade)
+          .setRememberUpgrade(options.rememberUpgrade)
+          .setHost(options.host)
+          .setHostname(options.hostname)
+          .setHostnameVerifier(options.hostnameVerifier)
+          .setPort(options.port)
+          .setPolicyPort(options.policyPort)
+          .setSecure(options.secure)
+          .setQuery(options.query);
+    }
+  }
+
+
+  public SocketOptionBuilder setForceNew(boolean forceNew) {
+    this.options.forceNew = forceNew;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setMultiplex(boolean multiplex) {
+    this.options.multiplex = multiplex;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setReconnection(boolean reconnection) {
+    this.options.reconnection = reconnection;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setReconnectionAttempts(int reconnectionAttempts) {
+    this.options.reconnectionAttempts = reconnectionAttempts;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setReconnectionDelay(long reconnectionDelay) {
+    this.options.reconnectionDelay = reconnectionDelay;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setReconnectionDelayMax(long reconnectionDelayMax) {
+    this.options.reconnectionDelayMax = reconnectionDelayMax;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setRandomizationFactor(double randomizationFactor) {
+    this.options.randomizationFactor = randomizationFactor;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setTimeout(long timeout) {
+    this.options.timeout = timeout;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setTransports(String[] transports) {
+    this.options.transports = transports;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setUpgrade(boolean upgrade) {
+    this.options.upgrade = upgrade;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setRememberUpgrade(boolean rememberUpgrade) {
+    this.options.rememberUpgrade = rememberUpgrade;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setHost(String host) {
+    this.options.host = host;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setHostname(String hostname) {
+    this.options.hostname = hostname;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+    this.options.hostnameVerifier = hostnameVerifier;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setPort(int port) {
+    this.options.port = port;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setPolicyPort(int policyPort) {
+    this.options.policyPort = policyPort;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setQuery(String query) {
+    this.options.query = query;
+    return this;
+  }
+
+
+  public SocketOptionBuilder setSecure(boolean secure) {
+    this.options.secure = secure;
+    return this;
+  }
+
+
+  /**
+   * Finally retrieve {@link io.socket.client.IO.Options} object
+   * from this builder.
+   *
+   * @return option that built from this builder
+   */
+  public IO.Options build() {
+    return this.options;
+  }
+}
diff --git a/src/test/java/io/socket/client/SocketOptionBuilderTest.java b/src/test/java/io/socket/client/SocketOptionBuilderTest.java
new file mode 100644
index 00000000..4fce87d7
--- /dev/null
+++ b/src/test/java/io/socket/client/SocketOptionBuilderTest.java
@@ -0,0 +1,337 @@
+package io.socket.client;
+
+import io.socket.emitter.Emitter;
+import org.junit.Test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+
+/**
+ * This tests are exactly same as {@link ConnectionTest} one
+ * except creating IO.Options.
+ *
+ * @author junbong
+ */
+public class SocketOptionBuilderTest extends ConnectionTest {
+    private Socket socket;
+
+
+    @Override
+    @Test(timeout = TIMEOUT)
+    public void attemptReconnectsAfterAFailedReconnect() throws URISyntaxException, InterruptedException {
+        final BlockingQueue<Object> values = new LinkedBlockingQueue<>();
+
+        final IO.Options opts = SocketOptionBuilder.builder()
+                                                   .setForceNew(true)
+                                                   .setReconnection(true)
+                                                   .setTimeout(0)
+                                                   .setReconnectionAttempts(2)
+                                                   .setReconnectionDelay(10)
+                                                   .build();
+
+        final Manager manager = new Manager(new URI(uri()), opts);
+        socket = manager.socket("/timeout");
+        socket.once(Socket.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
+            @Override
+            public void call(Object... args) {
+                final int[] reconnects = new int[]{0};
+                Emitter.Listener reconnectCb = new Emitter.Listener() {
+                    @Override
+                    public void call(Object... args) {
+                        reconnects[0]++;
+                    }
+                };
+
+                manager.on(Manager.EVENT_RECONNECT_ATTEMPT, reconnectCb);
+                manager.on(Manager.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
+                    @Override
+                    public void call(Object... args) {
+                        values.offer(reconnects[0]);
+                    }
+                });
+                socket.connect();
+            }
+        });
+        socket.connect();
+        assertThat((Integer) values.take(), is(2));
+        socket.close();
+        manager.close();
+    }
+
+
+    @Override
+    @Test(timeout = TIMEOUT)
+    public void reconnectDelayShouldIncreaseEveryTime() throws URISyntaxException, InterruptedException {
+        final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
+        IO.Options opts = SocketOptionBuilder.builder()
+                                             .setForceNew(true)
+                                             .setReconnection(true)
+                                             .setTimeout(0)
+                                             .setReconnectionAttempts(3)
+                                             .setReconnectionDelay(100)
+                                             .setRandomizationFactor(0.2)
+                                             .build();
+
+        final Manager manager = new Manager(new URI(uri()), opts);
+        socket = manager.socket("/timeout");
+
+        final int[] reconnects = new int[] {0};
+        final boolean[] increasingDelay = new boolean[] {true};
+        final long[] startTime = new long[] {0};
+        final long[] prevDelay = new long[] {0};
+
+        socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
+            @Override
+            public void call(Object... args) {
+                startTime[0] = new Date().getTime();
+            }
+        });
+        socket.on(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
+            @Override
+            public void call(Object... args) {
+                reconnects[0]++;
+                long currentTime = new Date().getTime();
+                long delay = currentTime - startTime[0];
+                if (delay <= prevDelay[0]) {
+                    increasingDelay[0] = false;
+                }
+                prevDelay[0] = delay;
+            }
+        });
+        socket.on(Socket.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
+            @Override
+            public void call(Object... args) {
+                values.offer(true);
+            }
+        });
+
+        socket.connect();
+        values.take();
+        assertThat(reconnects[0], is(3));
+        assertThat(increasingDelay[0], is(true));
+        socket.close();
+        manager.close();
+    }
+
+
+    @Override
+    @Test(timeout = TIMEOUT)
+    public void notReconnectWhenForceClosed() throws URISyntaxException, InterruptedException {
+        final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
+        IO.Options opts = SocketOptionBuilder.builder()
+                                             .setForceNew(true)
+                                             .setTimeout(0)
+                                             .setReconnectionDelay(10)
+                                             .build();
+
+        socket = IO.socket(uri() + "/invalid", opts);
+        socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
+            @Override
+            public void call(Object... args) {
+                socket.on(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
+                    @Override
+                    public void call(Object... args) {
+                        values.offer(false);
+                    }
+                });
+                socket.disconnect();
+                new Timer().schedule(new TimerTask() {
+                    @Override
+                    public void run() {
+                        values.offer(true);
+                    }
+                }, 500);
+            }
+        });
+        socket.connect();
+        assertThat((Boolean)values.take(), is(true));
+    }
+
+
+    @Override
+    @Test(timeout = TIMEOUT)
+    public void stopReconnectingWhenForceClosed() throws URISyntaxException, InterruptedException {
+        final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
+        IO.Options opts = SocketOptionBuilder.builder()
+                                             .setForceNew(true)
+                                             .setTimeout(0)
+                                             .setReconnectionDelay(10)
+                                             .build();
+
+        socket = IO.socket(uri() + "/invalid", opts);
+        socket.once(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
+            @Override
+            public void call(Object... args) {
+                socket.on(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
+                    @Override
+                    public void call(Object... args) {
+                        values.offer(false);
+                    }
+                });
+                socket.disconnect();
+                // set a timer to let reconnection possibly fire
+                new Timer().schedule(new TimerTask() {
+                    @Override
+                    public void run() {
+                        values.offer(true);
+                    }
+                }, 500);
+            }
+        });
+        socket.connect();
+        assertThat((Boolean) values.take(), is(true));
+    }
+
+
+    @Override
+    @Test(timeout = TIMEOUT)
+    public void reconnectAfterStoppingReconnection() throws URISyntaxException, InterruptedException {
+        final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
+        IO.Options opts = SocketOptionBuilder.builder()
+                                             .setForceNew(true)
+                                             .setTimeout(0)
+                                             .setReconnectionDelay(10)
+                                             .build();
+
+        socket = client("/invalid", opts);
+        socket.once(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
+            @Override
+            public void call(Object... args) {
+                socket.once(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
+                    @Override
+                    public void call(Object... args) {
+                        values.offer("done");
+                    }
+                });
+                socket.disconnect();
+                socket.connect();
+            }
+        });
+        socket.connect();
+        values.take();
+        socket.disconnect();
+    }
+
+
+    @Override
+    @Test(timeout = TIMEOUT)
+    public void tryToReconnectTwiceAndFailWithIncorrectAddress() throws URISyntaxException, InterruptedException {
+        final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
+        IO.Options opts = SocketOptionBuilder.builder()
+                                             .setForceNew(true)
+                                             .setReconnection(true)
+                                             .setReconnectionAttempts(2)
+                                             .setReconnectionDelay(10)
+                                             .build();
+
+        final Manager manager = new Manager(new URI("http://localhost:3940"), opts);
+        socket = manager.socket("/asd");
+        final int[] reconnects = new int[] {0};
+        Emitter.Listener cb = new Emitter.Listener() {
+            @Override
+            public void call(Object... objects) {
+                reconnects[0]++;
+            }
+        };
+
+        manager.on(Manager.EVENT_RECONNECT_ATTEMPT, cb);
+
+        manager.on(Manager.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
+            @Override
+            public void call(Object... objects) {
+                values.offer(reconnects[0]);
+            }
+        });
+
+        socket.open();
+        assertThat((Integer)values.take(), is(2));
+        socket.close();
+        manager.close();
+    }
+
+
+    @Override
+    @Test(timeout = TIMEOUT)
+    public void tryToReconnectTwiceAndFailWithImmediateTimeout() throws URISyntaxException, InterruptedException {
+        final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
+        IO.Options opts = SocketOptionBuilder.builder()
+                                             .setForceNew(true)
+                                             .setTimeout(0)
+                                             .setReconnection(true)
+                                             .setReconnectionAttempts(2)
+                                             .setReconnectionDelay(10)
+                                             .build();
+
+        final Manager manager = new Manager(new URI(uri()), opts);
+
+        final int[] reconnects = new int[] {0};
+        Emitter.Listener reconnectCb = new Emitter.Listener() {
+            @Override
+            public void call(Object... objects) {
+                reconnects[0]++;
+            }
+        };
+
+        manager.on(Manager.EVENT_RECONNECT_ATTEMPT, reconnectCb);
+        manager.on(Manager.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
+            @Override
+            public void call(Object... objects) {
+                socket.close();
+                manager.close();
+                values.offer(reconnects[0]);
+            }
+        });
+
+        socket = manager.socket("/timeout");
+        socket.open();
+        assertThat((Integer)values.take(), is(2));
+    }
+
+
+    @Override
+    @Test(timeout = TIMEOUT)
+    public void notTryToReconnectWithIncorrectPortWhenReconnectionDisabled() throws URISyntaxException, InterruptedException {
+        final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
+        IO.Options opts = SocketOptionBuilder.builder()
+                                             .setForceNew(true)
+                                             .setReconnection(false)
+                                             .build();
+
+        final Manager manager = new Manager(new URI("http://localhost:9823"), opts);
+        Emitter.Listener cb = new Emitter.Listener() {
+            @Override
+            public void call(Object... objects) {
+                socket.close();
+                throw new RuntimeException();
+            }
+        };
+        manager.on(Manager.EVENT_RECONNECT_ATTEMPT, cb);
+        manager.on(Manager.EVENT_CONNECT_ERROR, new Emitter.Listener() {
+            @Override
+            public void call(Object... objects) {
+                Timer timer = new Timer();
+                timer.schedule(new TimerTask() {
+                    @Override
+                    public void run() {
+                        socket.close();
+                        manager.close();
+                        values.offer("done");
+                    }
+                }, 1000);
+            }
+        });
+
+        socket = manager.socket("/invalid");
+        socket.open();
+        values.take();
+    }
+}

From d799a73930d3668d9e0513a56e2bb0263fc4d3f9 Mon Sep 17 00:00:00 2001
From: Lloyd Junbong Lee <lloyd@zoyi.co>
Date: Fri, 13 May 2016 15:27:37 +0900
Subject: [PATCH 2/2] Add new SocketOptionBuilder which helps creating
 IO.Option as builder pattern.

---
 .../io/socket/client/SocketOptionBuilder.java | 300 +++++++++---------
 1 file changed, 154 insertions(+), 146 deletions(-)

diff --git a/src/main/java/io/socket/client/SocketOptionBuilder.java b/src/main/java/io/socket/client/SocketOptionBuilder.java
index a23febe3..91afbb80 100644
--- a/src/main/java/io/socket/client/SocketOptionBuilder.java
+++ b/src/main/java/io/socket/client/SocketOptionBuilder.java
@@ -11,190 +11,198 @@
  * @author junbong
  */
 public class SocketOptionBuilder {
-  /**
-   * Construct new builder with default preferences.
-   * @return new builder object
-   * @see SocketOptionBuilder#builder(IO.Options)
-   */
-  public static SocketOptionBuilder builder() {
-    return new SocketOptionBuilder();
-  }
-
-
-  /**
-   * Construct this builder from specified option object.
-   * The option that returned from {@link #build()} method
-   * is not equals with given option.
-   * In other words, builder creates new option object
-   * and copy all preferences from given option.
-   *
-   * @param options option object which to copy preferences
-   * @return new builder object
-   */
-  public static SocketOptionBuilder builder(IO.Options options) {
-    return new SocketOptionBuilder(options);
-  }
-
-
-  private final IO.Options options = new IO.Options();
-
-
-  /**
-   * Construct new builder with default preferences.
-   */
-  protected SocketOptionBuilder() {
-    this(null);
-  }
+    /**
+     * Construct new builder with default preferences.
+     *
+     * @return new builder object
+     * @see SocketOptionBuilder#builder(IO.Options)
+     */
+    public static SocketOptionBuilder builder() {
+        return new SocketOptionBuilder();
+    }
+
+
+    /**
+     * Construct this builder from specified option object.
+     * The option that returned from {@link #build()} method
+     * is not equals with given option.
+     * In other words, builder creates new option object
+     * and copy all preferences from given option.
+     *
+     * @param options option object which to copy preferences
+     * @return new builder object
+     */
+    public static SocketOptionBuilder builder(IO.Options options) {
+        return new SocketOptionBuilder(options);
+    }
+
+
+    private final IO.Options options = new IO.Options();
+
+
+    /**
+     * Construct new builder with default preferences.
+     */
+    protected SocketOptionBuilder() {
+        this(null);
+    }
+
+
+    /**
+     * Construct this builder from specified option object.
+     * The option that returned from {@link #build()} method
+     * is not equals with given option.
+     * In other words, builder creates new option object
+     * and copy all preferences from given option.
+     *
+     * @param options option object which to copy preferences. Null-ok.
+     */
+    protected SocketOptionBuilder(IO.Options options) {
+        if (options != null) {
+            this.setForceNew(options.forceNew)
+                .setMultiplex(options.multiplex)
+                .setReconnection(options.reconnection)
+                .setReconnectionAttempts(options.reconnectionAttempts)
+                .setReconnectionDelay(options.reconnectionDelay)
+                .setReconnectionDelayMax(options.reconnectionDelayMax)
+                .setRandomizationFactor(options.randomizationFactor)
+                .setTimeout(options.timeout)
+                .setTransports(options.transports)
+                .setUpgrade(options.upgrade)
+                .setRememberUpgrade(options.rememberUpgrade)
+                .setHost(options.host)
+                .setHostname(options.hostname)
+                .setHostnameVerifier(options.hostnameVerifier)
+                .setPort(options.port)
+                .setPolicyPort(options.policyPort)
+                .setSecure(options.secure)
+                .setPath(options.path)
+                .setQuery(options.query);
+        }
+    }
 
-
-  /**
-   * Construct this builder from specified option object.
-   * The option that returned from {@link #build()} method
-   * is not equals with given option.
-   * In other words, builder creates new option object
-   * and copy all preferences from given option.
-   *
-   * @param options option object which to copy preferences. Null-ok.
-   */
-  protected SocketOptionBuilder(IO.Options options) {
-    if (options != null) {
-      this.setForceNew(options.forceNew)
-          .setMultiplex(options.multiplex)
-          .setReconnection(options.reconnection)
-          .setReconnectionAttempts(options.reconnectionAttempts)
-          .setReconnectionDelay(options.reconnectionDelay)
-          .setReconnectionDelayMax(options.reconnectionDelayMax)
-          .setRandomizationFactor(options.randomizationFactor)
-          .setTimeout(options.timeout)
-          .setTransports(options.transports)
-          .setUpgrade(options.upgrade)
-          .setRememberUpgrade(options.rememberUpgrade)
-          .setHost(options.host)
-          .setHostname(options.hostname)
-          .setHostnameVerifier(options.hostnameVerifier)
-          .setPort(options.port)
-          .setPolicyPort(options.policyPort)
-          .setSecure(options.secure)
-          .setQuery(options.query);
+
+    public SocketOptionBuilder setForceNew(boolean forceNew) {
+        this.options.forceNew = forceNew;
+        return this;
     }
-  }
 
 
-  public SocketOptionBuilder setForceNew(boolean forceNew) {
-    this.options.forceNew = forceNew;
-    return this;
-  }
+    public SocketOptionBuilder setMultiplex(boolean multiplex) {
+        this.options.multiplex = multiplex;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setMultiplex(boolean multiplex) {
-    this.options.multiplex = multiplex;
-    return this;
-  }
+    public SocketOptionBuilder setReconnection(boolean reconnection) {
+        this.options.reconnection = reconnection;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setReconnection(boolean reconnection) {
-    this.options.reconnection = reconnection;
-    return this;
-  }
+    public SocketOptionBuilder setReconnectionAttempts(int reconnectionAttempts) {
+        this.options.reconnectionAttempts = reconnectionAttempts;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setReconnectionAttempts(int reconnectionAttempts) {
-    this.options.reconnectionAttempts = reconnectionAttempts;
-    return this;
-  }
+    public SocketOptionBuilder setReconnectionDelay(long reconnectionDelay) {
+        this.options.reconnectionDelay = reconnectionDelay;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setReconnectionDelay(long reconnectionDelay) {
-    this.options.reconnectionDelay = reconnectionDelay;
-    return this;
-  }
+    public SocketOptionBuilder setReconnectionDelayMax(long reconnectionDelayMax) {
+        this.options.reconnectionDelayMax = reconnectionDelayMax;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setReconnectionDelayMax(long reconnectionDelayMax) {
-    this.options.reconnectionDelayMax = reconnectionDelayMax;
-    return this;
-  }
+    public SocketOptionBuilder setRandomizationFactor(double randomizationFactor) {
+        this.options.randomizationFactor = randomizationFactor;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setRandomizationFactor(double randomizationFactor) {
-    this.options.randomizationFactor = randomizationFactor;
-    return this;
-  }
+    public SocketOptionBuilder setTimeout(long timeout) {
+        this.options.timeout = timeout;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setTimeout(long timeout) {
-    this.options.timeout = timeout;
-    return this;
-  }
+    public SocketOptionBuilder setTransports(String[] transports) {
+        this.options.transports = transports;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setTransports(String[] transports) {
-    this.options.transports = transports;
-    return this;
-  }
+    public SocketOptionBuilder setUpgrade(boolean upgrade) {
+        this.options.upgrade = upgrade;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setUpgrade(boolean upgrade) {
-    this.options.upgrade = upgrade;
-    return this;
-  }
+    public SocketOptionBuilder setRememberUpgrade(boolean rememberUpgrade) {
+        this.options.rememberUpgrade = rememberUpgrade;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setRememberUpgrade(boolean rememberUpgrade) {
-    this.options.rememberUpgrade = rememberUpgrade;
-    return this;
-  }
+    public SocketOptionBuilder setHost(String host) {
+        this.options.host = host;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setHost(String host) {
-    this.options.host = host;
-    return this;
-  }
+    public SocketOptionBuilder setHostname(String hostname) {
+        this.options.hostname = hostname;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setHostname(String hostname) {
-    this.options.hostname = hostname;
-    return this;
-  }
+    public SocketOptionBuilder setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+        this.options.hostnameVerifier = hostnameVerifier;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setHostnameVerifier(HostnameVerifier hostnameVerifier) {
-    this.options.hostnameVerifier = hostnameVerifier;
-    return this;
-  }
+    public SocketOptionBuilder setPort(int port) {
+        this.options.port = port;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setPort(int port) {
-    this.options.port = port;
-    return this;
-  }
+    public SocketOptionBuilder setPolicyPort(int policyPort) {
+        this.options.policyPort = policyPort;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setPolicyPort(int policyPort) {
-    this.options.policyPort = policyPort;
-    return this;
-  }
+    public SocketOptionBuilder setQuery(String query) {
+        this.options.query = query;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setQuery(String query) {
-    this.options.query = query;
-    return this;
-  }
+    public SocketOptionBuilder setSecure(boolean secure) {
+        this.options.secure = secure;
+        return this;
+    }
 
 
-  public SocketOptionBuilder setSecure(boolean secure) {
-    this.options.secure = secure;
-    return this;
-  }
+    public SocketOptionBuilder setPath(String path) {
+        this.options.path = path;
+        return this;
+    }
 
 
-  /**
-   * Finally retrieve {@link io.socket.client.IO.Options} object
-   * from this builder.
-   *
-   * @return option that built from this builder
-   */
-  public IO.Options build() {
-    return this.options;
-  }
+    /**
+     * Finally retrieve {@link io.socket.client.IO.Options} object
+     * from this builder.
+     *
+     * @return option that built from this builder
+     */
+    public IO.Options build() {
+        return this.options;
+    }
 }