You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2017/02/09 18:36:05 UTC

[06/47] curator git commit: big refactoring

big refactoring


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

Branch: refs/heads/CURATOR-3.0
Commit: 71283320eba76ef6fe02af84ac31bd27a4ef3916
Parents: ea6261e
Author: randgalt <ra...@apache.org>
Authored: Thu Jan 5 14:07:47 2017 -0500
Committer: randgalt <ra...@apache.org>
Committed: Thu Jan 5 14:07:47 2017 -0500

----------------------------------------------------------------------
 .../curator/x/crimps/AsyncPathAndBytesable.java |  23 ----
 .../apache/curator/x/crimps/BackgroundProc.java |   9 --
 .../org/apache/curator/x/crimps/Crimped.java    |  11 --
 .../apache/curator/x/crimps/CrimpedBytes.java   |  11 --
 .../curator/x/crimps/CrimpedBytesImpl.java      |  47 -------
 .../apache/curator/x/crimps/CrimpedImpl.java    |  41 -------
 .../org/apache/curator/x/crimps/Crimps.java     |  90 --------------
 .../curator/x/crimps/async/BackgroundProc.java  |   9 ++
 .../crimps/async/CrimpedBackgroundCallback.java |  22 ++++
 .../x/crimps/async/CrimpedPathAndBytesable.java |   8 ++
 .../curator/x/crimps/async/CrimpedPathable.java |   8 ++
 .../apache/curator/x/crimps/async/Crimps.java   | 120 ++++++++++++++++++
 .../org/apache/curator/x/crimps/TestCrimps.java | 122 -------------------
 .../curator/x/crimps/async/TestCrimps.java      | 122 +++++++++++++++++++
 14 files changed, 289 insertions(+), 354 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/AsyncPathAndBytesable.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/AsyncPathAndBytesable.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/AsyncPathAndBytesable.java
deleted file mode 100644
index 0d5d3a1..0000000
--- a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/AsyncPathAndBytesable.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.apache.curator.x.crimps;
-
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.api.BackgroundCallback;
-import org.apache.curator.framework.api.CuratorEvent;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.BiFunction;
-
-class AsyncPathAndBytesable<T> extends CompletableFuture<T> implements BackgroundCallback
-{
-    private final BackgroundProc<T> resultFunction;
-
-    AsyncPathAndBytesable(BackgroundProc<T> resultFunction)
-    {
-        this.resultFunction = resultFunction;
-    }
-
-    @Override
-    public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
-    {
-        resultFunction.apply(event, this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/BackgroundProc.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/BackgroundProc.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/BackgroundProc.java
deleted file mode 100644
index 1989f43..0000000
--- a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/BackgroundProc.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.apache.curator.x.crimps;
-
-import org.apache.curator.framework.api.CuratorEvent;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.BiFunction;
-
-interface BackgroundProc<T> extends BiFunction<CuratorEvent, CompletableFuture<T>, Void>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/Crimped.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/Crimped.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/Crimped.java
deleted file mode 100644
index 8d18898..0000000
--- a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/Crimped.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.apache.curator.x.crimps;
-
-import org.apache.curator.framework.api.ErrorListenerPathable;
-import org.apache.curator.framework.api.Pathable;
-import java.util.concurrent.CompletionStage;
-
-public interface Crimped<T> extends
-    ErrorListenerPathable<CompletionStage<T>>,
-    Pathable<CompletionStage<T>>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedBytes.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedBytes.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedBytes.java
deleted file mode 100644
index 3ce0b8e..0000000
--- a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedBytes.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.apache.curator.x.crimps;
-
-import org.apache.curator.framework.api.ErrorListenerPathAndBytesable;
-import org.apache.curator.framework.api.PathAndBytesable;
-import java.util.concurrent.CompletionStage;
-
-public interface CrimpedBytes<T> extends
-    ErrorListenerPathAndBytesable<CompletionStage<T>>,
-    PathAndBytesable<CompletionStage<T>>
-{
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedBytesImpl.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedBytesImpl.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedBytesImpl.java
deleted file mode 100644
index 288fdbd..0000000
--- a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedBytesImpl.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.apache.curator.x.crimps;
-
-import org.apache.curator.framework.api.BackgroundPathAndBytesable;
-import org.apache.curator.framework.api.ErrorListenerPathAndBytesable;
-import org.apache.curator.framework.api.PathAndBytesable;
-import org.apache.curator.framework.api.UnhandledErrorListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.util.concurrent.CompletionStage;
-
-class CrimpedBytesImpl<T> implements CrimpedBytes<T>
-{
-    private final Logger log = LoggerFactory.getLogger(getClass());
-    private final BackgroundPathAndBytesable<T> builder;
-    private final BackgroundProc<T> resultFunction;
-    private UnhandledErrorListener unhandledErrorListener;
-
-    CrimpedBytesImpl(BackgroundPathAndBytesable<T> builder, BackgroundProc<T> resultFunction)
-    {
-        this.builder = builder;
-        this.resultFunction = resultFunction;
-        unhandledErrorListener = null;
-    }
-
-    @Override
-    public PathAndBytesable<CompletionStage<T>> withUnhandledErrorListener(UnhandledErrorListener listener)
-    {
-        unhandledErrorListener = listener;
-        return this;
-    }
-
-    @Override
-    public CompletionStage<T> forPath(String path) throws Exception
-    {
-        return forPath(path, null);
-    }
-
-    @Override
-    public CompletionStage<T> forPath(String path, byte[] data) throws Exception
-    {
-        AsyncPathAndBytesable<T> supplier = new AsyncPathAndBytesable<T>(resultFunction);
-        ErrorListenerPathAndBytesable<T> localBuilder = builder.inBackground(supplier);
-        PathAndBytesable<T> finalLocalBuilder = (unhandledErrorListener != null) ? localBuilder.withUnhandledErrorListener(unhandledErrorListener) : localBuilder;
-        finalLocalBuilder.forPath(path, data);
-        return supplier;
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedImpl.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedImpl.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedImpl.java
deleted file mode 100644
index 1537edf..0000000
--- a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/CrimpedImpl.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.apache.curator.x.crimps;
-
-import org.apache.curator.framework.api.BackgroundPathable;
-import org.apache.curator.framework.api.ErrorListenerPathable;
-import org.apache.curator.framework.api.Pathable;
-import org.apache.curator.framework.api.UnhandledErrorListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.util.concurrent.CompletionStage;
-
-class CrimpedImpl<T> implements Crimped<T>
-{
-    private final Logger log = LoggerFactory.getLogger(getClass());
-    private final BackgroundPathable<T> builder;
-    private final BackgroundProc<T> resultFunction;
-    private UnhandledErrorListener unhandledErrorListener;
-
-    CrimpedImpl(BackgroundPathable<T> builder, BackgroundProc<T> resultFunction)
-    {
-        this.builder = builder;
-        this.resultFunction = resultFunction;
-        unhandledErrorListener = null;
-    }
-
-    @Override
-    public Pathable<CompletionStage<T>> withUnhandledErrorListener(UnhandledErrorListener listener)
-    {
-        unhandledErrorListener = listener;
-        return this;
-    }
-
-    @Override
-    public CompletionStage<T> forPath(String path) throws Exception
-    {
-        AsyncPathAndBytesable<T> supplier = new AsyncPathAndBytesable<T>(resultFunction);
-        ErrorListenerPathable<T> localBuilder = builder.inBackground(supplier);
-        Pathable<T> finalLocalBuilder = (unhandledErrorListener != null) ? localBuilder.withUnhandledErrorListener(unhandledErrorListener) : localBuilder;
-        finalLocalBuilder.forPath(path);
-        return supplier;
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/Crimps.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/Crimps.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/Crimps.java
deleted file mode 100644
index 68d99af..0000000
--- a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/Crimps.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.apache.curator.x.crimps;
-
-import org.apache.curator.framework.api.BackgroundPathAndBytesable;
-import org.apache.curator.framework.api.BackgroundPathable;
-import org.apache.curator.framework.api.CuratorEvent;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-import java.util.List;
-import java.util.function.Function;
-
-public class Crimps
-{
-    private static final BackgroundProc<String> nameSupplier = makeSupplier(CuratorEvent::getName);
-    private static final BackgroundProc<String> pathSupplier = makeSupplier(CuratorEvent::getPath);
-    private static final BackgroundProc<Void> voidSupplier = makeSupplier(e -> null);
-    private static final BackgroundProc<byte[]> dataSupplier = makeSupplier(CuratorEvent::getData);
-    private static final BackgroundProc<Stat> statSupplier = makeSupplier(CuratorEvent::getStat);
-    private static final BackgroundProc<List<String>> childrenSupplier = makeSupplier(CuratorEvent::getChildren);
-    private static final BackgroundProc<List<ACL>> aclSupplier = makeSupplier(CuratorEvent::getACLList);
-
-    private static <T> BackgroundProc<T> makeSupplier(Function<CuratorEvent, T> proc)
-    {
-        return (event, future) -> {
-            if ( event.getResultCode() == 0 )
-            {
-                future.complete(proc.apply(event));
-            }
-            else
-            {
-                future.completeExceptionally(KeeperException.create(KeeperException.Code.get(event.getResultCode())));
-            }
-            return null;
-        };
-    }
-
-    public static CrimpedBytes<String> nameInBackground(BackgroundPathAndBytesable<String> builder)
-    {
-        return build(builder, nameSupplier);
-    }
-
-    public static CrimpedBytes<String> pathInBackground(BackgroundPathAndBytesable<String> builder)
-    {
-        return build(builder, pathSupplier);
-    }
-
-    public static Crimped<Void> voidInBackground(BackgroundPathable<Void> builder)
-    {
-        return build(builder, voidSupplier);
-    }
-
-    public static Crimped<byte[]> dataInBackground(BackgroundPathable<byte[]> builder)
-    {
-        return build(builder, dataSupplier);
-    }
-
-    public static Crimped<List<String>> childrenInBackground(BackgroundPathable<List<String>> builder)
-    {
-        return build(builder, childrenSupplier);
-    }
-
-    public static Crimped<Stat> statInBackground(BackgroundPathable<Stat> builder)
-    {
-        return build(builder, statSupplier);
-    }
-
-    public static Crimped<List<ACL>> aclsInBackground(BackgroundPathable<List<ACL>> builder)
-    {
-        return build(builder, aclSupplier);
-    }
-
-    public static CrimpedBytes<Stat> statBytesInBackground(BackgroundPathAndBytesable<Stat> builder)
-    {
-        return build(builder, statSupplier);
-    }
-
-    public static <T> CrimpedBytes<T> build(BackgroundPathAndBytesable<T> builder, BackgroundProc<T> supplier)
-    {
-        return new CrimpedBytesImpl<>(builder, supplier);
-    }
-
-    public static <T> Crimped<T> build(BackgroundPathable<T> builder, BackgroundProc<T> supplier)
-    {
-        return new CrimpedImpl<>(builder, supplier);
-    }
-
-    private Crimps()
-    {
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/BackgroundProc.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/BackgroundProc.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/BackgroundProc.java
new file mode 100644
index 0000000..69167c2
--- /dev/null
+++ b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/BackgroundProc.java
@@ -0,0 +1,9 @@
+package org.apache.curator.x.crimps.async;
+
+import org.apache.curator.framework.api.CuratorEvent;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.BiFunction;
+
+interface BackgroundProc<T> extends BiFunction<CuratorEvent, CompletableFuture<T>, Void>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedBackgroundCallback.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedBackgroundCallback.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedBackgroundCallback.java
new file mode 100644
index 0000000..070e5f8
--- /dev/null
+++ b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedBackgroundCallback.java
@@ -0,0 +1,22 @@
+package org.apache.curator.x.crimps.async;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.api.BackgroundCallback;
+import org.apache.curator.framework.api.CuratorEvent;
+import java.util.concurrent.CompletableFuture;
+
+class CrimpedBackgroundCallback<T> extends CompletableFuture<T> implements BackgroundCallback
+{
+    private final BackgroundProc<T> resultFunction;
+
+    CrimpedBackgroundCallback(BackgroundProc<T> resultFunction)
+    {
+        this.resultFunction = resultFunction;
+    }
+
+    @Override
+    public void processResult(CuratorFramework client, CuratorEvent event) throws Exception
+    {
+        resultFunction.apply(event, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedPathAndBytesable.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedPathAndBytesable.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedPathAndBytesable.java
new file mode 100644
index 0000000..aa90507
--- /dev/null
+++ b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedPathAndBytesable.java
@@ -0,0 +1,8 @@
+package org.apache.curator.x.crimps.async;
+
+import org.apache.curator.framework.api.PathAndBytesable;
+import java.util.concurrent.CompletionStage;
+
+public interface CrimpedPathAndBytesable<T> extends PathAndBytesable<CompletionStage<T>>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedPathable.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedPathable.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedPathable.java
new file mode 100644
index 0000000..49b096a
--- /dev/null
+++ b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/CrimpedPathable.java
@@ -0,0 +1,8 @@
+package org.apache.curator.x.crimps.async;
+
+import org.apache.curator.framework.api.Pathable;
+import java.util.concurrent.CompletionStage;
+
+public interface CrimpedPathable<T> extends Pathable<CompletionStage<T>>
+{
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/Crimps.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/Crimps.java b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/Crimps.java
new file mode 100644
index 0000000..128e195
--- /dev/null
+++ b/curator-x-crimps/src/main/java/org/apache/curator/x/crimps/async/Crimps.java
@@ -0,0 +1,120 @@
+package org.apache.curator.x.crimps.async;
+
+import org.apache.curator.framework.api.BackgroundPathAndBytesable;
+import org.apache.curator.framework.api.BackgroundPathable;
+import org.apache.curator.framework.api.CuratorEvent;
+import org.apache.curator.framework.api.ErrorListenerPathAndBytesable;
+import org.apache.curator.framework.api.ErrorListenerPathable;
+import org.apache.curator.framework.api.PathAndBytesable;
+import org.apache.curator.framework.api.Pathable;
+import org.apache.curator.framework.api.UnhandledErrorListener;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+import java.util.List;
+import java.util.concurrent.CompletionStage;
+import java.util.function.Function;
+
+public class Crimps
+{
+    public static final BackgroundProc<String> nameSupplier = makeSupplier(CuratorEvent::getName);
+    public static final BackgroundProc<String> pathSupplier = makeSupplier(CuratorEvent::getPath);
+    public static final BackgroundProc<Void> voidSupplier = makeSupplier(e -> null);
+    public static final BackgroundProc<byte[]> dataSupplier = makeSupplier(CuratorEvent::getData);
+    public static final BackgroundProc<Stat> statSupplier = makeSupplier(CuratorEvent::getStat);
+    public static final BackgroundProc<List<String>> childrenSupplier = makeSupplier(CuratorEvent::getChildren);
+    public static final BackgroundProc<List<ACL>> aclSupplier = makeSupplier(CuratorEvent::getACLList);
+
+    private static <T> BackgroundProc<T> makeSupplier(Function<CuratorEvent, T> proc)
+    {
+        return (event, future) -> {
+            if ( event.getResultCode() == 0 )
+            {
+                future.complete(proc.apply(event));
+            }
+            else
+            {
+                future.completeExceptionally(KeeperException.create(KeeperException.Code.get(event.getResultCode())));
+            }
+            return null;
+        };
+    }
+
+    public static CrimpedPathAndBytesable<String> nameInBackground(BackgroundPathAndBytesable<String> builder)
+    {
+        return build(builder, null, nameSupplier);
+    }
+
+    public static CrimpedPathAndBytesable<String> pathInBackground(BackgroundPathAndBytesable<String> builder)
+    {
+        return build(builder, null, pathSupplier);
+    }
+
+    public static CrimpedPathable<Void> voidInBackground(BackgroundPathable<Void> builder)
+    {
+        return build(builder, null, voidSupplier);
+    }
+
+    public static CrimpedPathable<byte[]> dataInBackground(BackgroundPathable<byte[]> builder)
+    {
+        return build(builder, null, dataSupplier);
+    }
+
+    public static CrimpedPathable<List<String>> childrenInBackground(BackgroundPathable<List<String>> builder)
+    {
+        return build(builder, null, childrenSupplier);
+    }
+
+    public static CrimpedPathable<Stat> statInBackground(BackgroundPathable<Stat> builder)
+    {
+        return build(builder, null, statSupplier);
+    }
+
+    public static CrimpedPathable<List<ACL>> aclsInBackground(BackgroundPathable<List<ACL>> builder)
+    {
+        return build(builder, null, aclSupplier);
+    }
+
+    public static CrimpedPathAndBytesable<Stat> statBytesInBackground(BackgroundPathAndBytesable<Stat> builder)
+    {
+        return build(builder, null, statSupplier);
+    }
+
+    public static <T> CrimpedPathAndBytesable<T> build(BackgroundPathAndBytesable<T> builder, UnhandledErrorListener unhandledErrorListener, BackgroundProc<T> backgroundProc)
+    {
+        CrimpedBackgroundCallback<T> callback = new CrimpedBackgroundCallback<T>(backgroundProc);
+        ErrorListenerPathAndBytesable<T> localBuilder = builder.inBackground(callback);
+        PathAndBytesable<T> finalLocalBuilder = (unhandledErrorListener != null) ? localBuilder.withUnhandledErrorListener(unhandledErrorListener) : localBuilder;
+        return new CrimpedPathAndBytesable<T>()
+        {
+            @Override
+            public CompletionStage<T> forPath(String path) throws Exception
+            {
+                finalLocalBuilder.forPath(path);
+                return callback;
+            }
+
+            @Override
+            public CompletionStage<T> forPath(String path, byte[] data) throws Exception
+            {
+                finalLocalBuilder.forPath(path, data);
+                return callback;
+            }
+        };
+    }
+
+    public static <T> CrimpedPathable<T> build(BackgroundPathable<T> builder, UnhandledErrorListener unhandledErrorListener, BackgroundProc<T> backgroundProc)
+    {
+        CrimpedBackgroundCallback<T> callback = new CrimpedBackgroundCallback<T>(backgroundProc);
+        ErrorListenerPathable<T> localBuilder = builder.inBackground(callback);
+        Pathable<T> finalLocalBuilder = (unhandledErrorListener != null) ? localBuilder.withUnhandledErrorListener(unhandledErrorListener) : localBuilder;
+        return path -> {
+            finalLocalBuilder.forPath(path);
+            return callback;
+        };
+    }
+
+    private Crimps()
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/test/java/org/apache/curator/x/crimps/TestCrimps.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/test/java/org/apache/curator/x/crimps/TestCrimps.java b/curator-x-crimps/src/test/java/org/apache/curator/x/crimps/TestCrimps.java
deleted file mode 100644
index 20a02c6..0000000
--- a/curator-x-crimps/src/test/java/org/apache/curator/x/crimps/TestCrimps.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package org.apache.curator.x.crimps;
-
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.retry.RetryOneTime;
-import org.apache.curator.test.BaseClassForTests;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.data.Stat;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-import java.util.concurrent.CompletionStage;
-import java.util.concurrent.ExecutionException;
-
-public class TestCrimps extends BaseClassForTests
-{
-    @Test
-    public void testCreateAndSet() throws Exception
-    {
-        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1)) )
-        {
-            client.start();
-            CompletionStage<String> f = Crimps.nameInBackground(client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT_SEQUENTIAL)).forPath("/a/b/c");
-            complete(f.handle((path, e) -> {
-                Assert.assertEquals(path, "/a/b/c0000000000");
-                return null;
-            }));
-
-            f = Crimps.nameInBackground(client.create()).forPath("/foo/bar");
-            assertException(f, KeeperException.Code.NONODE);
-
-            CompletionStage<Stat> statFuture = Crimps.statBytesInBackground(client.setData()).forPath("/a/b/c0000000000", "hey".getBytes());
-            complete(statFuture.handle((stat, e) -> {
-                Assert.assertNotNull(stat);
-                return null;
-            }));
-        }
-    }
-
-    @Test
-    public void testDelete() throws Exception
-    {
-        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1)) )
-        {
-            client.start();
-            client.create().forPath("/test");
-
-            CompletionStage<Void> f = Crimps.voidInBackground(client.delete()).forPath("/test");
-            complete(f.handle((v, e) -> {
-                Assert.assertEquals(v, null);
-                Assert.assertEquals(e, null);
-                return null;
-            }));
-
-            f = Crimps.voidInBackground(client.delete()).forPath("/test");
-            assertException(f, KeeperException.Code.NONODE);
-        }
-    }
-
-    @Test
-    public void testGetData() throws Exception
-    {
-        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1)) )
-        {
-            client.start();
-            client.create().forPath("/test", "foo".getBytes());
-
-            CompletionStage<byte[]> f = Crimps.dataInBackground(client.getData()).forPath("/test");
-            complete(f.handle((data, e) -> {
-                Assert.assertEquals(data, "foo".getBytes());
-                return null;
-            }));
-        }
-    }
-
-    public void assertException(CompletionStage<?> f, KeeperException.Code code) throws Exception
-    {
-        complete(f.handle((value, e) -> {
-            if ( e == null )
-            {
-                Assert.fail(code + " expected");
-            }
-            KeeperException keeperException = unwrap(e);
-            Assert.assertNotNull(keeperException);
-            Assert.assertEquals(keeperException.code(), code);
-            return null;
-        }));
-    }
-
-    private void complete(CompletionStage<?> f) throws Exception
-    {
-        try
-        {
-            f.toCompletableFuture().get();
-        }
-        catch ( InterruptedException e )
-        {
-            Thread.currentThread().interrupt();
-        }
-        catch ( ExecutionException e )
-        {
-            if ( e.getCause() instanceof AssertionError )
-            {
-                throw ((AssertionError)e.getCause());
-            }
-            throw e;
-        }
-    }
-
-    private static KeeperException unwrap(Throwable e)
-    {
-        while ( e != null )
-        {
-            if ( e instanceof KeeperException )
-            {
-                return (KeeperException)e;
-            }
-            e = e.getCause();
-        }
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/71283320/curator-x-crimps/src/test/java/org/apache/curator/x/crimps/async/TestCrimps.java
----------------------------------------------------------------------
diff --git a/curator-x-crimps/src/test/java/org/apache/curator/x/crimps/async/TestCrimps.java b/curator-x-crimps/src/test/java/org/apache/curator/x/crimps/async/TestCrimps.java
new file mode 100644
index 0000000..0bee0cf
--- /dev/null
+++ b/curator-x-crimps/src/test/java/org/apache/curator/x/crimps/async/TestCrimps.java
@@ -0,0 +1,122 @@
+package org.apache.curator.x.crimps.async;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.RetryOneTime;
+import org.apache.curator.test.BaseClassForTests;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.data.Stat;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+
+public class TestCrimps extends BaseClassForTests
+{
+    @Test
+    public void testCreateAndSet() throws Exception
+    {
+        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1)) )
+        {
+            client.start();
+            CompletionStage<String> f = Crimps.nameInBackground(client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT_SEQUENTIAL)).forPath("/a/b/c");
+            complete(f.handle((path, e) -> {
+                Assert.assertEquals(path, "/a/b/c0000000000");
+                return null;
+            }));
+
+            f = Crimps.nameInBackground(client.create()).forPath("/foo/bar");
+            assertException(f, KeeperException.Code.NONODE);
+
+            CompletionStage<Stat> statFuture = Crimps.statBytesInBackground(client.setData()).forPath("/a/b/c0000000000", "hey".getBytes());
+            complete(statFuture.handle((stat, e) -> {
+                Assert.assertNotNull(stat);
+                return null;
+            }));
+        }
+    }
+
+    @Test
+    public void testDelete() throws Exception
+    {
+        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1)) )
+        {
+            client.start();
+            client.create().forPath("/test");
+
+            CompletionStage<Void> f = Crimps.voidInBackground(client.delete()).forPath("/test");
+            complete(f.handle((v, e) -> {
+                Assert.assertEquals(v, null);
+                Assert.assertEquals(e, null);
+                return null;
+            }));
+
+            f = Crimps.voidInBackground(client.delete()).forPath("/test");
+            assertException(f, KeeperException.Code.NONODE);
+        }
+    }
+
+    @Test
+    public void testGetData() throws Exception
+    {
+        try ( CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1)) )
+        {
+            client.start();
+            client.create().forPath("/test", "foo".getBytes());
+
+            CompletionStage<byte[]> f = Crimps.dataInBackground(client.getData()).forPath("/test");
+            complete(f.handle((data, e) -> {
+                Assert.assertEquals(data, "foo".getBytes());
+                return null;
+            }));
+        }
+    }
+
+    public void assertException(CompletionStage<?> f, KeeperException.Code code) throws Exception
+    {
+        complete(f.handle((value, e) -> {
+            if ( e == null )
+            {
+                Assert.fail(code + " expected");
+            }
+            KeeperException keeperException = unwrap(e);
+            Assert.assertNotNull(keeperException);
+            Assert.assertEquals(keeperException.code(), code);
+            return null;
+        }));
+    }
+
+    private void complete(CompletionStage<?> f) throws Exception
+    {
+        try
+        {
+            f.toCompletableFuture().get();
+        }
+        catch ( InterruptedException e )
+        {
+            Thread.currentThread().interrupt();
+        }
+        catch ( ExecutionException e )
+        {
+            if ( e.getCause() instanceof AssertionError )
+            {
+                throw ((AssertionError)e.getCause());
+            }
+            throw e;
+        }
+    }
+
+    private static KeeperException unwrap(Throwable e)
+    {
+        while ( e != null )
+        {
+            if ( e instanceof KeeperException )
+            {
+                return (KeeperException)e;
+            }
+            e = e.getCause();
+        }
+        return null;
+    }
+}