You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by dr...@apache.org on 2015/08/17 18:54:42 UTC

[12/27] curator git commit: Reworked the reconfig() APIs to be more like the rest of Curator

Reworked the reconfig() APIs to be more like the rest of Curator


Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/57dbf2e1
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/57dbf2e1
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/57dbf2e1

Branch: refs/heads/CURATOR-215
Commit: 57dbf2e1145d3f11166b89e16fbbeaae09b7ba3e
Parents: 760473d
Author: randgalt <ra...@apache.org>
Authored: Sat May 9 09:13:53 2015 -0500
Committer: Scott Blum <dr...@apache.org>
Committed: Wed Aug 12 17:28:32 2015 -0400

----------------------------------------------------------------------
 .../curator/framework/CuratorFramework.java     |   4 +-
 .../api/AddStatConfigEnsembleable.java          |  32 +
 .../apache/curator/framework/api/Addable.java   |  43 ++
 .../api/BackgroundStatConfigEnsembleable.java   |  24 -
 .../api/BackgroundStatEnsembleable.java         |  24 -
 .../curator/framework/api/Configurable.java     |   6 +-
 .../api/JoinAddStatConfigEnsembleable.java      |  33 ++
 .../JoinBackgroundStatConfigEnsembleable.java   |  30 -
 .../api/JoinLeaveStatConfigEnsembleable.java    |  33 ++
 .../api/JoinStatConfigEnsembleable.java         |  32 +
 .../framework/api/JoinStatConfigurable.java     |  30 +
 .../apache/curator/framework/api/Joinable.java  |  18 +-
 .../api/LeaveAddStatConfigEnsembleable.java     |  32 +
 .../LeaveBackgroundStatConfigEnsembleable.java  |  30 -
 .../api/LeaveStatConfigEnsembleable.java        |  32 +
 .../apache/curator/framework/api/Leaveable.java |  15 +-
 .../curator/framework/api/Memberable.java       |  31 -
 .../api/NonIncrementalReconfigBuilder.java      |  32 -
 .../curator/framework/api/ReconfigBuilder.java  |  10 +-
 .../framework/api/ReconfigBuilderMain.java      |  27 +
 .../framework/api/StatConfigEnsembleable.java   |  26 +
 .../curator/framework/api/StatEnsembleable.java |  26 +
 .../framework/imps/CuratorFrameworkImpl.java    |   6 +-
 .../imps/EnsembleServersAndConfig.java          |  52 --
 .../curator/framework/imps/EnsembleTracker.java | 115 ++--
 .../framework/imps/ReconfigBuilderImpl.java     | 582 ++++++++++++++-----
 .../framework/imps/TestReconfiguration.java     | 240 ++++----
 27 files changed, 1032 insertions(+), 533 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
index 181e4e8..7de49ce 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
@@ -123,13 +123,15 @@ public interface CuratorFramework extends Closeable
 
     /**
      * Start a reconfig builder
+     *
      * @return builder object
      */
     public ReconfigBuilder reconfig();
 
     /**
      * Start a getConfig builder
-     * @return
+     *
+     * @return builder object
      */
     public GetConfigBuilder getConfig();
 

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java
new file mode 100644
index 0000000..16f78a2
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/AddStatConfigEnsembleable.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+/**
+ * An non-incremental reconfiguration builder.
+ * This builder has access only to the non-incremental reconfiguration methods withMembers, so that we prevent
+ * mixing concepts that can't be used together.
+ */
+public interface AddStatConfigEnsembleable extends
+    Addable<StatConfigEnsembleable>,
+    StatConfigEnsembleable
+{
+
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/Addable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/Addable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/Addable.java
new file mode 100644
index 0000000..e908f1e
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/Addable.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+import java.util.List;
+
+public interface Addable<T>
+{
+    /**
+     * Sets one or more members that are meant to be part of the ensemble.
+     * The expected format is server.[id]=[hostname]:[peer port]:[election port]:[type];[client port]
+     *
+     * @param server The server to add as a member of the ensemble.
+     * @return this
+     */
+    T adding(String... server);
+
+    /**
+     * Sets one or more members that are meant to be part of the ensemble.
+     * The expected format is server.[id]=[hostname]:[peer port]:[election port]:[type];[client port]
+     *
+     * @param servers The server to add as a member of the ensemble.
+     * @return this
+     */
+    T adding(List<String> servers);
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatConfigEnsembleable.java
deleted file mode 100644
index f109b0f..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatConfigEnsembleable.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.framework.api;
-
-public interface BackgroundStatConfigEnsembleable<T> extends
-        Configurable<BackgroundStatEnsembleable<T>>,
-        BackgroundStatEnsembleable<T> {
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatEnsembleable.java
deleted file mode 100644
index 62f666d..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/BackgroundStatEnsembleable.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.framework.api;
-
-public interface BackgroundStatEnsembleable<T> extends
-    BackgroundStatable<Ensembleable<T>>,
-    Ensembleable<T> {
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java
index 39e2c0c..2bc0494 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/Configurable.java
@@ -16,14 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.api;
 
-public interface Configurable<T> {
+public interface Configurable
+{
 
     /**
      * Sets the configuration version to use.
      * @param config The version of the configuration.
      * @throws Exception
      */
-    BackgroundStatEnsembleable<byte[]> fromConfig(long config) throws Exception;
+    StatEnsembleable<byte[]> fromConfig(long config) throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
new file mode 100644
index 0000000..a905dd1
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinAddStatConfigEnsembleable.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+/**
+ * An incremental reconfiguration builder.
+ * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
+ * mixing concepts that can't be used together.
+ */
+public interface JoinAddStatConfigEnsembleable extends
+    Joinable<AddStatConfigEnsembleable>,
+    Addable<JoinStatConfigurable>,
+    StatConfigEnsembleable
+{
+
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/JoinBackgroundStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinBackgroundStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinBackgroundStatConfigEnsembleable.java
deleted file mode 100644
index ba45efd..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinBackgroundStatConfigEnsembleable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.framework.api;
-
-/**
- * An incremental reconfiguration builder.
- * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
- * mixing concepts that can't be used together.
- */
-public interface JoinBackgroundStatConfigEnsembleable extends
-        Joinable<BackgroundStatConfigEnsembleable<byte[]>>,
-        BackgroundStatConfigEnsembleable<byte[]> {
-
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
new file mode 100644
index 0000000..9642297
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinLeaveStatConfigEnsembleable.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+/**
+ * An incremental reconfiguration builder.
+ * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
+ * mixing concepts that can't be used together.
+ */
+public interface JoinLeaveStatConfigEnsembleable extends
+    Joinable<LeaveStatConfigEnsembleable>,
+    Leaveable<JoinStatConfigEnsembleable>,
+    StatConfigEnsembleable
+{
+
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
new file mode 100644
index 0000000..5fe7a8c
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigEnsembleable.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+/**
+ * An incremental reconfiguration builder.
+ * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
+ * mixing concepts that can't be used together.
+ */
+public interface JoinStatConfigEnsembleable extends
+    Joinable<StatConfigEnsembleable>,
+    StatConfigEnsembleable
+{
+
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
new file mode 100644
index 0000000..ef17ef4
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/JoinStatConfigurable.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+/**
+ * An incremental reconfiguration builder.
+ * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
+ * mixing concepts that can't be used together.
+ */
+public interface JoinStatConfigurable extends
+    Joinable<Configurable>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/Joinable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/Joinable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/Joinable.java
index dde5b1c..5cebe4d 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/Joinable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/Joinable.java
@@ -16,16 +16,28 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.api;
 
-public interface Joinable<T> {
+import java.util.List;
 
+public interface Joinable<T>
+{
     /**
      * Adds one or more servers to joining the ensemble.
      * The expected format is server.[id]=[hostname]:[peer port]:[election port]:[type];[client port]
-     * @param server The server to joining.
-     * @return this.
+     *
+     * @param server The server joining.
+     * @return this
      */
     T joining(String... server);
 
+    /**
+     * Adds one or more servers to joining the ensemble.
+     * The expected format is server.[id]=[hostname]:[peer port]:[election port]:[type];[client port]
+     *
+     * @param servers The servers joining.
+     * @return this
+     */
+    T joining(List<String> servers);
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
new file mode 100644
index 0000000..7912d45
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveAddStatConfigEnsembleable.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+/**
+ * An non-incremental reconfiguration builder.
+ * This builder has access only to the non-incremental reconfiguration methods withMembers, so that we prevent
+ * mixing concepts that can't be used together.
+ */
+public interface LeaveAddStatConfigEnsembleable extends
+    Leaveable<AddStatConfigEnsembleable>,
+    Addable<LeaveStatConfigEnsembleable>,
+    StatConfigEnsembleable
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveBackgroundStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveBackgroundStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveBackgroundStatConfigEnsembleable.java
deleted file mode 100644
index a6316c1..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveBackgroundStatConfigEnsembleable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.framework.api;
-
-/**
- * An non-incremental reconfiguration builder.
- * This builder has access only to the non-incremental reconfiguration methods withMembers, so that we prevent
- * mixing concepts that can't be used together.
- */
-public interface LeaveBackgroundStatConfigEnsembleable extends
-        Leaveable<BackgroundStatConfigEnsembleable<byte[]>>,
-        BackgroundStatConfigEnsembleable<byte[]> {
-
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
new file mode 100644
index 0000000..ddad854
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/LeaveStatConfigEnsembleable.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+/**
+ * An incremental reconfiguration builder.
+ * This builder has access only to the incremental reconfiguration methods joining and leaving, so that we prevent
+ * mixing concepts that can't be used together.
+ */
+public interface LeaveStatConfigEnsembleable extends
+    Leaveable<StatConfigEnsembleable>,
+    StatConfigEnsembleable
+{
+
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/Leaveable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/Leaveable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/Leaveable.java
index a3c3358..6ec3542 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/Leaveable.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/Leaveable.java
@@ -16,15 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.api;
 
-public interface Leaveable<T> {
+import java.util.List;
 
+public interface Leaveable<T>
+{
     /**
      * Sets one or more servers to leaving the ensemble.
-     * @param server The server ids.
+     *
+     * @param server The server ids
      * @return this
      */
     T leaving(String... server);
 
+    /**
+     * Sets one or more servers to leaving the ensemble.
+     *
+     * @param servers The server ids
+     * @return this
+     */
+    T leaving(List<String> servers);
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/Memberable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/Memberable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/Memberable.java
deleted file mode 100644
index 6ef54c1..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/Memberable.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.framework.api;
-
-
-public interface Memberable<T> {
-
-    /**
-     * Sets one or more members that are meant to be part of the ensemble.
-     * The expected format is server.[id]=[hostname]:[peer port]:[election port]:[type];[client port]
-     * @param server The server to add as a member of the ensemble.
-     * @return this.
-     */
-    T withMembers(String... server);
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/NonIncrementalReconfigBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/NonIncrementalReconfigBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/NonIncrementalReconfigBuilder.java
deleted file mode 100644
index 2f6a9c6..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/NonIncrementalReconfigBuilder.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.framework.api;
-
-/**
- * An non-incremental reconfiguration builder.
- * This builder has access only to the non-incremental reconfiguration methods withMembers, so that we prevent
- * mixing concepts that can't be used together.
- * @param <T>
- */
-public interface NonIncrementalReconfigBuilder<T> extends
-        Memberable<NonIncrementalReconfigBuilder<T>>,
-        DataCallbackable<AsyncReconfigurable>,
-        Statable<SyncReconfigurable> {
-
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java
index f05b99e..438abcf 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilder.java
@@ -16,11 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.api;
 
 public interface ReconfigBuilder extends
-        Joinable<LeaveBackgroundStatConfigEnsembleable>,
-        Leaveable<JoinBackgroundStatConfigEnsembleable>,
-        Memberable<BackgroundStatConfigEnsembleable<byte[]>> {
-
+    Joinable<LeaveAddStatConfigEnsembleable>,
+    Leaveable<JoinAddStatConfigEnsembleable>,
+    Addable<JoinLeaveStatConfigEnsembleable>,
+    Backgroundable<ReconfigBuilderMain>
+{
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java b/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java
new file mode 100644
index 0000000..b86af2d
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/ReconfigBuilderMain.java
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+public interface ReconfigBuilderMain extends
+    Joinable<LeaveAddStatConfigEnsembleable>,
+    Leaveable<JoinAddStatConfigEnsembleable>,
+    Addable<JoinLeaveStatConfigEnsembleable>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigEnsembleable.java
new file mode 100644
index 0000000..4700c8c
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/StatConfigEnsembleable.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+public interface StatConfigEnsembleable extends
+    Configurable,
+    StatEnsembleable<byte[]>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/api/StatEnsembleable.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/StatEnsembleable.java b/curator-framework/src/main/java/org/apache/curator/framework/api/StatEnsembleable.java
new file mode 100644
index 0000000..0993b50
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/StatEnsembleable.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.curator.framework.api;
+
+public interface StatEnsembleable<T> extends
+    Statable<Ensembleable<T>>,
+    Ensembleable<T>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
index b9b9c31..9b96f60 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
@@ -398,12 +398,14 @@ public class CuratorFrameworkImpl implements CuratorFramework
     }
 
     @Override
-    public ReconfigBuilder reconfig() {
+    public ReconfigBuilder reconfig()
+    {
         return new ReconfigBuilderImpl(this);
     }
 
     @Override
-    public GetConfigBuilder getConfig() {
+    public GetConfigBuilder getConfig()
+    {
         return new GetConfigBuilderImpl(this);
     }
 

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleServersAndConfig.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleServersAndConfig.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleServersAndConfig.java
deleted file mode 100644
index df78aa7..0000000
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleServersAndConfig.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.framework.imps;
-
-import java.util.Collections;
-import java.util.List;
-
-class EnsembleServersAndConfig {
-    private final List<String> joiningServers;
-    private final List<String> leavingServers;
-    private final List<String> members;
-    private final long config;
-
-    EnsembleServersAndConfig(List<String> joiningServers, List<String> leavingServers, List<String> members, long config) {
-        this.joiningServers = joiningServers.isEmpty() ? null : Collections.unmodifiableList(joiningServers);
-        this.leavingServers = leavingServers.isEmpty() ? null : Collections.unmodifiableList(leavingServers);
-        this.members = members.isEmpty() ? null : Collections.unmodifiableList(members);
-        this.config = config;
-    }
-
-    public List<String> getJoiningServers() {
-        return joiningServers;
-    }
-
-    public List<String> getLeavingServers() {
-        return leavingServers;
-    }
-
-    public List<String> getMembers() {
-        return members;
-    }
-
-    public long getConfig() {
-        return config;
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java
index a789e42..6688848 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/EnsembleTracker.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.imps;
 
 import com.google.common.base.Function;
@@ -35,7 +36,6 @@ import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
 import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.io.IOException;
@@ -46,65 +46,81 @@ import java.util.concurrent.atomic.AtomicReference;
 /**
  * Tracks changes to the ensemble and notifies registered {@link org.apache.curator.ensemble.EnsembleListener} instances.
  */
-public class EnsembleTracker implements Closeable {
-
+public class EnsembleTracker implements Closeable
+{
     private final Logger log = LoggerFactory.getLogger(getClass());
     private final CuratorFramework client;
     private final AtomicReference<State> state = new AtomicReference<State>(State.LATENT);
     private final ListenerContainer<EnsembleListener> listeners = new ListenerContainer<EnsembleListener>();
     private final AtomicBoolean isConnected = new AtomicBoolean(true);
-    private final ConnectionStateListener connectionStateListener = new ConnectionStateListener() {
+    private final ConnectionStateListener connectionStateListener = new ConnectionStateListener()
+    {
         @Override
-        public void stateChanged(CuratorFramework client, ConnectionState newState) {
-            if ((newState == ConnectionState.CONNECTED) || (newState == ConnectionState.RECONNECTED)) {
-                if (isConnected.compareAndSet(false, true)) {
-                    try {
+        public void stateChanged(CuratorFramework client, ConnectionState newState)
+        {
+            if ( (newState == ConnectionState.CONNECTED) || (newState == ConnectionState.RECONNECTED) )
+            {
+                if ( isConnected.compareAndSet(false, true) )
+                {
+                    try
+                    {
                         reset();
-                    } catch (Exception e) {
+                    }
+                    catch ( Exception e )
+                    {
                         log.error("Trying to reset after reconnection", e);
                     }
                 }
-            } else {
+            }
+            else
+            {
                 isConnected.set(false);
             }
         }
     };
 
-    private final CuratorWatcher watcher = new CuratorWatcher() {
+    private final CuratorWatcher watcher = new CuratorWatcher()
+    {
         @Override
-        public void process(WatchedEvent event) throws Exception {
+        public void process(WatchedEvent event) throws Exception
+        {
             reset();
         }
     };
 
-
-    private enum State {
+    private enum State
+    {
         LATENT,
         STARTED,
         CLOSED
     }
 
-    private final BackgroundCallback backgroundCallback = new BackgroundCallback() {
+    private final BackgroundCallback backgroundCallback = new BackgroundCallback()
+    {
         @Override
-        public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
+        public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
+        {
             processBackgroundResult(event);
         }
     };
 
-
-    public EnsembleTracker(CuratorFramework client) {
+    public EnsembleTracker(CuratorFramework client)
+    {
         this.client = client;
     }
 
-    public void start() throws Exception {
+    public void start() throws Exception
+    {
         Preconditions.checkState(state.compareAndSet(State.LATENT, State.STARTED), "Cannot be started more than once");
         client.getConnectionStateListenable().addListener(connectionStateListener);
         reset();
     }
 
     @Override
-    public void close() throws IOException {
-        if (state.compareAndSet(State.STARTED, State.CLOSED)) {
+    public void close() throws IOException
+    {
+        if ( state.compareAndSet(State.STARTED, State.CLOSED) )
+        {
             listeners.clear();
         }
         client.getConnectionStateListenable().removeListener(connectionStateListener);
@@ -122,27 +138,35 @@ public class EnsembleTracker implements Closeable {
         return listeners;
     }
 
-    private void reset() throws Exception {
+    private void reset() throws Exception
+    {
         client.getConfig().usingWatcher(watcher).inBackground(backgroundCallback).forEnsemble();
     }
 
-    private void processBackgroundResult(CuratorEvent event) throws Exception {
-        switch (event.getType()) {
-            case GET_CONFIG: {
-                if (event.getResultCode() == KeeperException.Code.OK.intValue()) {
-                    processConfigData(event.getData());
-                }
+    private void processBackgroundResult(CuratorEvent event) throws Exception
+    {
+        switch ( event.getType() )
+        {
+        case GET_CONFIG:
+        {
+            if ( event.getResultCode() == KeeperException.Code.OK.intValue() )
+            {
+                processConfigData(event.getData());
             }
         }
+        }
     }
 
-    private void processConfigData(byte[] data) throws Exception {
+    private void processConfigData(byte[] data) throws Exception
+    {
         Properties properties = new Properties();
         properties.load(new ByteArrayInputStream(data));
         QuorumVerifier qv = new QuorumMaj(properties);
         StringBuilder sb = new StringBuilder();
-        for (QuorumPeer.QuorumServer server : qv.getAllMembers().values()) {
-            if (sb.length() != 0) {
+        for ( QuorumPeer.QuorumServer server : qv.getAllMembers().values() )
+        {
+            if ( sb.length() != 0 )
+            {
                 sb.append(",");
             }
             sb.append(server.clientAddr.getAddress().getHostAddress()).append(":").append(server.clientAddr.getPort());
@@ -150,18 +174,23 @@ public class EnsembleTracker implements Closeable {
 
         final String connectionString = sb.toString();
         listeners.forEach
-                (
-                        new Function<EnsembleListener, Void>() {
-                            @Override
-                            public Void apply(EnsembleListener listener) {
-                                try {
-                                    listener.connectionStringUpdated(connectionString);
-                                } catch (Exception e) {
-                                    log.error("Calling listener", e);
-                                }
-                                return null;
-                            }
+            (
+                new Function<EnsembleListener, Void>()
+                {
+                    @Override
+                    public Void apply(EnsembleListener listener)
+                    {
+                        try
+                        {
+                            listener.connectionStringUpdated(connectionString);
+                        }
+                        catch ( Exception e )
+                        {
+                            log.error("Calling listener", e);
                         }
-                );
+                        return null;
+                    }
+                }
+            );
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/57dbf2e1/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
index 5489691..15ed13e 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
@@ -16,201 +16,489 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.imps;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.curator.RetryLoop;
 import org.apache.curator.TimeTrace;
-import org.apache.curator.framework.api.BackgroundCallback;
-import org.apache.curator.framework.api.BackgroundStatConfigEnsembleable;
-import org.apache.curator.framework.api.BackgroundStatEnsembleable;
-import org.apache.curator.framework.api.CuratorEvent;
-import org.apache.curator.framework.api.CuratorEventType;
-import org.apache.curator.framework.api.Ensembleable;
-import org.apache.curator.framework.api.JoinBackgroundStatConfigEnsembleable;
-import org.apache.curator.framework.api.LeaveBackgroundStatConfigEnsembleable;
-import org.apache.curator.framework.api.ReconfigBuilder;
+import org.apache.curator.framework.api.*;
 import org.apache.zookeeper.AsyncCallback;
 import org.apache.zookeeper.data.Stat;
-
+import org.apache.zookeeper.server.DataTree;
 import java.util.Arrays;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executor;
 
-public class ReconfigBuilderImpl implements ReconfigBuilder {
-
+public class ReconfigBuilderImpl implements
+    ReconfigBuilder,
+    ReconfigBuilderMain,
+    StatEnsembleable<byte[]>,
+    Configurable,
+    StatConfigEnsembleable,
+    BackgroundOperation<Void>
+{
     private final CuratorFrameworkImpl client;
 
-    public ReconfigBuilderImpl(CuratorFrameworkImpl client) {
+    private Backgrounding backgrounding;
+    private Stat responseStat;
+    private long fromConfig = -1;
+    private List<String> adding;
+    private List<String> joining;
+    private List<String> leaving;
+
+    public ReconfigBuilderImpl(CuratorFrameworkImpl client)
+    {
         this.client = client;
     }
 
-    private static class ReconfigBuilderBase implements BackgroundStatConfigEnsembleable<byte[]>, Ensembleable<byte[]>, BackgroundOperation<EnsembleServersAndConfig> {
+    @Override
+    public byte[] forEnsemble() throws Exception
+    {
+        if ( backgrounding != null )
+        {
+            client.processBackgroundOperation(new OperationAndData<>(this, null, backgrounding.getCallback(), null, backgrounding.getContext()), null);
+            return new byte[0];
+        }
+        else
+        {
+            return ensembleInForeground();
+        }
+    }
 
-        final CuratorFrameworkImpl client;
-        final List<String> joiningServers = new LinkedList<String>();
-        final List<String> leavingServers = new LinkedList<String>();
-        final List<String> members = new LinkedList<String>();
-        Backgrounding backgrounding;
-        Stat stat;
-        long config;
+    @Override
+    public Ensembleable<byte[]> storingStatIn(Stat stat)
+    {
+        responseStat = stat;
+        return this;
+    }
 
-        private ReconfigBuilderBase(CuratorFrameworkImpl client) {
-            this.client = client;
-            backgrounding = new Backgrounding();
-        }
+    @Override
+    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+    {
+        fromConfig = config;
+        return this;
+    }
 
-        @Override
-        public Ensembleable<byte[]> inBackground() {
-            backgrounding = new Backgrounding();
-            return this;
-        }
+    @Override
+    public JoinLeaveStatConfigEnsembleable adding(String... server)
+    {
+        return adding((server != null) ? Arrays.asList(server) : null);
+    }
 
-        @Override
-        public Ensembleable<byte[]> inBackground(Object context) {
-            backgrounding = new Backgrounding(context);
-            return this;
-        }
+    @Override
+    public JoinLeaveStatConfigEnsembleable adding(List<String> servers)
+    {
+        this.adding = (servers != null) ? ImmutableList.copyOf(servers) : ImmutableList.<String>of();
 
-        @Override
-        public Ensembleable<byte[]> inBackground(BackgroundCallback callback) {
-            backgrounding = new Backgrounding(callback);
-            return this;
-        }
+        return new JoinLeaveStatConfigEnsembleable()
+        {
+            @Override
+            public byte[] forEnsemble() throws Exception
+            {
+                return ReconfigBuilderImpl.this.forEnsemble();
+            }
 
-        @Override
-        public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Object context) {
-            backgrounding = new Backgrounding(callback, context);
-            return this;
-        }
+            @Override
+            public Ensembleable<byte[]> storingStatIn(Stat stat)
+            {
+                return ReconfigBuilderImpl.this.storingStatIn(stat);
+            }
 
-        @Override
-        public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Executor executor) {
-            backgrounding = new Backgrounding(callback, executor);
-            return this;
-        }
+            @Override
+            public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+            {
+                return ReconfigBuilderImpl.this.fromConfig(config);
+            }
 
-        @Override
-        public Ensembleable<byte[]> inBackground(BackgroundCallback callback, Object context, Executor executor) {
-            backgrounding = new Backgrounding(client, callback, context, executor);
-            return this;
-        }
+            @Override
+            public LeaveStatConfigEnsembleable joining(String... server)
+            {
+                return joining((server != null) ? Arrays.asList(server) : null);
+            }
 
-        @Override
-        public BackgroundStatEnsembleable<byte[]> fromConfig(long config) throws Exception {
-            this.config = config;
-            return this;
-        }
+            @Override
+            public LeaveStatConfigEnsembleable joining(List<String> servers)
+            {
+                return new LeaveStatConfigEnsembleable()
+                {
+                    @Override
+                    public byte[] forEnsemble() throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.forEnsemble();
+                    }
 
-        @Override
-        public Ensembleable<byte[]> storingStatIn(Stat stat) {
-            this.stat = stat;
-            return this;
-        }
+                    @Override
+                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    {
+                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                    }
+
+                    @Override
+                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.fromConfig(config);
+                    }
 
-        @Override
-        public byte[] forEnsemble() throws Exception {
-            if (backgrounding.inBackground()) {
-                client.processBackgroundOperation(new OperationAndData<EnsembleServersAndConfig>(this,
-                        new EnsembleServersAndConfig(joiningServers, leavingServers, members, config),
-                        backgrounding.getCallback(), null, backgrounding.getContext()), null);
-                return new byte[0];
-            } else {
-                return ensembleInForeground();
+                    @Override
+                    public StatConfigEnsembleable leaving(List<String> servers)
+                    {
+                        return ReconfigBuilderImpl.this.leaving(servers);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable leaving(String... server)
+                    {
+                        return ReconfigBuilderImpl.this.leaving(server);
+                    }
+                };
             }
-        }
 
-        private byte[] ensembleInForeground() throws Exception {
-            TimeTrace trace = client.getZookeeperClient().startTracer("ReconfigBuilderImpl-Foreground");
-            byte[] responseData = RetryLoop.callWithRetry
-                    (
-                            client.getZookeeperClient(),
-                            new Callable<byte[]>() {
-                                @Override
-                                public byte[] call() throws Exception {
-                                    return client.getZooKeeper().reconfig(
-                                            joiningServers.isEmpty() ? null : joiningServers,
-                                            leavingServers.isEmpty() ? null : leavingServers,
-                                            members.isEmpty() ? null : members,
-                                            config,
-                                            stat
-                                    );
-                                }
-                            }
-                    );
-            trace.commit();
-            return responseData;
-        }
+            @Override
+            public JoinStatConfigEnsembleable leaving(String... server)
+            {
+                return leaving((server != null) ? Arrays.asList(server) : null);
+            }
 
-        @Override
-        public void performBackgroundOperation(final OperationAndData<EnsembleServersAndConfig> operationAndData) throws Exception {
-            final TimeTrace trace = client.getZookeeperClient().startTracer("ReconfigBuilderImpl-Background");
-            AsyncCallback.DataCallback callback = new AsyncCallback.DataCallback() {
-                @Override
-                public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
-                    trace.commit();
-                    CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.RECONFIG, rc, path, null, ctx, stat, data, null, null, null);
-                    client.processBackgroundOperation(operationAndData, event);
-                }
-            };
-            client.getZooKeeper().reconfig(
-                    operationAndData.getData().getJoiningServers(),
-                    operationAndData.getData().getLeavingServers(),
-                    operationAndData.getData().getMembers(),
-                    operationAndData.getData().getConfig(),
-                    callback,
-                    operationAndData.getContext()
-            );
+            @Override
+            public JoinStatConfigEnsembleable leaving(List<String> servers)
+            {
+                return new JoinStatConfigEnsembleable()
+                {
+                    @Override
+                    public byte[] forEnsemble() throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.forEnsemble();
+                    }
 
-        }
+                    @Override
+                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    {
+                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                    }
+
+                    @Override
+                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.fromConfig(config);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable joining(List<String> servers)
+                    {
+                        return ReconfigBuilderImpl.this.joining(servers);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable joining(String... server)
+                    {
+                        return ReconfigBuilderImpl.this.joining(server);
+                    }
+                };
+            }
+        };
     }
 
-    private static class JoinReconfigBuilderConfig extends ReconfigBuilderBase implements JoinBackgroundStatConfigEnsembleable {
+    @Override
+    public ReconfigBuilderMain inBackground()
+    {
+        backgrounding = new Backgrounding();
+        return this;
+    }
 
-        private JoinReconfigBuilderConfig(CuratorFrameworkImpl client) {
-            super(client);
-        }
+    @Override
+    public ReconfigBuilderMain inBackground(Object context)
+    {
+        backgrounding = new Backgrounding(context);
+        return this;
+    }
 
-        @Override
-        public BackgroundStatConfigEnsembleable<byte[]> joining(String... servers) {
-            joiningServers.addAll(Arrays.asList(servers));
-            return this;
-        }
+    @Override
+    public ReconfigBuilderMain inBackground(BackgroundCallback callback)
+    {
+        backgrounding = new Backgrounding(callback);
+        return this;
     }
 
-    private static class LeaveReconfigBuilderConfig extends ReconfigBuilderBase implements LeaveBackgroundStatConfigEnsembleable {
+    @Override
+    public ReconfigBuilderMain inBackground(BackgroundCallback callback, Object context)
+    {
+        backgrounding = new Backgrounding(callback, context);
+        return this;
+    }
 
-        private LeaveReconfigBuilderConfig(CuratorFrameworkImpl client) {
-            super(client);
-        }
+    @Override
+    public ReconfigBuilderMain inBackground(BackgroundCallback callback, Executor executor)
+    {
+        backgrounding = new Backgrounding(callback, executor);
+        return this;
+    }
 
-        @Override
-        public BackgroundStatConfigEnsembleable<byte[]> leaving(String... servers) {
-            leavingServers.addAll(Arrays.asList(servers));
-            return this;
-        }
+    @Override
+    public ReconfigBuilderMain inBackground(BackgroundCallback callback, Object context, Executor executor)
+    {
+        backgrounding = new Backgrounding(client, callback, context, executor);
+        return this;
     }
 
+    @Override
+    public LeaveAddStatConfigEnsembleable joining(String... server)
+    {
+        return joining((server != null) ? Arrays.asList(server) : null);
+    }
 
     @Override
-    public LeaveBackgroundStatConfigEnsembleable joining(String... servers) {
-        LeaveReconfigBuilderConfig builder = new LeaveReconfigBuilderConfig(client);
-        builder.joiningServers.addAll(Arrays.asList(servers));
-        return builder;
+    public LeaveAddStatConfigEnsembleable joining(List<String> servers)
+    {
+        joining = (servers != null) ? ImmutableList.copyOf(servers) : ImmutableList.<String>of();
+
+        return new LeaveAddStatConfigEnsembleable()
+        {
+            @Override
+            public byte[] forEnsemble() throws Exception
+            {
+                return ReconfigBuilderImpl.this.forEnsemble();
+            }
+
+            @Override
+            public Ensembleable<byte[]> storingStatIn(Stat stat)
+            {
+                return ReconfigBuilderImpl.this.storingStatIn(stat);
+            }
+
+            @Override
+            public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+            {
+                return ReconfigBuilderImpl.this.fromConfig(config);
+            }
+
+            @Override
+            public LeaveStatConfigEnsembleable adding(String... server)
+            {
+                return adding((server != null) ? Arrays.asList(server) : null);
+            }
+
+            @Override
+            public LeaveStatConfigEnsembleable adding(List<String> servers)
+            {
+                return new LeaveStatConfigEnsembleable()
+                {
+                    @Override
+                    public byte[] forEnsemble() throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.forEnsemble();
+                    }
+
+                    @Override
+                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    {
+                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                    }
+
+                    @Override
+                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.fromConfig(config);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable leaving(List<String> servers)
+                    {
+                        return ReconfigBuilderImpl.this.leaving(servers);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable leaving(String... server)
+                    {
+                        return ReconfigBuilderImpl.this.leaving(server);
+                    }
+                };
+            }
+
+            @Override
+            public AddStatConfigEnsembleable leaving(String... server)
+            {
+                return leaving((server != null) ? Arrays.asList(server) : null);
+            }
+
+            @Override
+            public AddStatConfigEnsembleable leaving(List<String> servers)
+            {
+                return new AddStatConfigEnsembleable()
+                {
+                    @Override
+                    public byte[] forEnsemble() throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.forEnsemble();
+                    }
+
+                    @Override
+                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    {
+                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                    }
+
+                    @Override
+                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.fromConfig(config);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable adding(List<String> servers)
+                    {
+                        return ReconfigBuilderImpl.this.adding(servers);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable adding(String... server)
+                    {
+                        return ReconfigBuilderImpl.this.adding(server);
+                    }
+                };
+            }
+        };
     }
 
     @Override
-    public JoinBackgroundStatConfigEnsembleable leaving(String... servers) {
-        JoinReconfigBuilderConfig builder = new JoinReconfigBuilderConfig(client);
-        builder.leavingServers.addAll(Arrays.asList(servers));
-        return builder;
+    public JoinAddStatConfigEnsembleable leaving(String... server)
+    {
+        return leaving((server != null) ? Arrays.asList(server) : null);
     }
 
     @Override
-    public BackgroundStatConfigEnsembleable<byte[]> withMembers(String... servers) {
-        ReconfigBuilderBase builder = new ReconfigBuilderBase(client);
-        builder.members.addAll(Arrays.asList(servers));
-        return builder;
+    public JoinAddStatConfigEnsembleable leaving(List<String> servers)
+    {
+        leaving = (servers != null) ? ImmutableList.copyOf(servers) : ImmutableList.<String>of();
+
+        return new JoinAddStatConfigEnsembleable()
+        {
+            @Override
+            public byte[] forEnsemble() throws Exception
+            {
+                return ReconfigBuilderImpl.this.forEnsemble();
+            }
+
+            @Override
+            public Ensembleable<byte[]> storingStatIn(Stat stat)
+            {
+                return ReconfigBuilderImpl.this.storingStatIn(stat);
+            }
+
+            @Override
+            public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+            {
+                return ReconfigBuilderImpl.this.fromConfig(config);
+            }
+
+            @Override
+            public JoinStatConfigurable adding(String... server)
+            {
+                return adding((server != null) ? Arrays.asList(server) : null);
+            }
+
+            @Override
+            public JoinStatConfigurable adding(List<String> servers)
+            {
+                return new JoinStatConfigurable()
+                {
+                    @Override
+                    public Configurable joining(List<String> servers)
+                    {
+                        return ReconfigBuilderImpl.this.joining(servers);
+                    }
+
+                    @Override
+                    public Configurable joining(String... server)
+                    {
+                        return ReconfigBuilderImpl.this.joining(server);
+                    }
+                };
+            }
+
+            @Override
+            public AddStatConfigEnsembleable joining(String... server)
+            {
+                return joining((server != null) ? Arrays.asList(server) : null);
+            }
+
+            @Override
+            public AddStatConfigEnsembleable joining(List<String> servers)
+            {
+                return new AddStatConfigEnsembleable()
+                {
+                    @Override
+                    public byte[] forEnsemble() throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.forEnsemble();
+                    }
+
+                    @Override
+                    public Ensembleable<byte[]> storingStatIn(Stat stat)
+                    {
+                        return ReconfigBuilderImpl.this.storingStatIn(stat);
+                    }
+
+                    @Override
+                    public StatEnsembleable<byte[]> fromConfig(long config) throws Exception
+                    {
+                        return ReconfigBuilderImpl.this.fromConfig(config);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable adding(List<String> servers)
+                    {
+                        return ReconfigBuilderImpl.this.adding(servers);
+                    }
+
+                    @Override
+                    public StatConfigEnsembleable adding(String... server)
+                    {
+                        return ReconfigBuilderImpl.this.adding(server);
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public void performBackgroundOperation(final OperationAndData<Void> data) throws Exception
+    {
+        final TimeTrace trace = client.getZookeeperClient().startTracer("ReconfigBuilderImpl-Background");
+        AsyncCallback.DataCallback callback = new AsyncCallback.DataCallback()
+        {
+            @Override
+            public void processResult(int rc, String path, Object ctx, byte[] bytes, Stat stat)
+            {
+                trace.commit();
+                if ( (responseStat != null) && (stat != null) )
+                {
+                    DataTree.copyStat(stat, responseStat);
+                }
+                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.RECONFIG, rc, path, null, ctx, stat, bytes, null, null, null);
+                client.processBackgroundOperation(data, event);
+            }
+        };
+        client.getZooKeeper().reconfig(joining, leaving, adding, fromConfig, callback, backgrounding.getContext());
+    }
+
+    private byte[] ensembleInForeground() throws Exception
+    {
+        TimeTrace trace = client.getZookeeperClient().startTracer("ReconfigBuilderImpl-Foreground");
+        byte[] responseData = RetryLoop.callWithRetry
+            (
+                client.getZookeeperClient(),
+                new Callable<byte[]>()
+                {
+                    @Override
+                    public byte[] call() throws Exception
+                    {
+                        return client.getZooKeeper().reconfig(joining, leaving, adding, fromConfig, responseStat);
+                    }
+                }
+            );
+        trace.commit();
+        return responseData;
     }
 }