http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java
deleted file mode 100644
index a48b9bb..0000000
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledCuratorFrameworkImpl.java
+++ /dev/null
@@ -1,228 +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.x.async.modeled.details;
-
-import com.google.common.collect.Lists;
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.api.transaction.CuratorOp;
-import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
-import org.apache.curator.x.async.AsyncStage;
-import org.apache.curator.x.async.api.CreateOption;
-import org.apache.curator.x.async.modeled.ModelSpec;
-import org.apache.curator.x.async.modeled.ModeledCuratorFramework;
-import org.apache.curator.x.async.modeled.cached.ZNode;
-import org.apache.curator.x.async.modeled.ZPath;
-import org.apache.curator.x.async.modeled.cached.CachedModeledCuratorFramework;
-import org.apache.curator.x.async.modeled.cached.ModeledCache;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.data.Stat;
-import org.apache.zookeeper.server.DataTree;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-class CachedModeledCuratorFrameworkImpl<T> implements 
CachedModeledCuratorFramework<T>
-{
-    private final ModeledCuratorFramework<T> client;
-    private final ModeledCacheImpl<T> cache;
-
-    CachedModeledCuratorFrameworkImpl(ModeledCuratorFramework<T> client)
-    {
-        this(client, new ModeledCacheImpl<>(client.unwrap(), 
client.modelSpec().path(), client.modelSpec().serializer(), 
client.modelSpec().createOptions().contains(CreateOption.compress)));
-    }
-
-    private CachedModeledCuratorFrameworkImpl(ModeledCuratorFramework<T> 
client, ModeledCacheImpl<T> cache)
-    {
-        this.client = client;
-        this.cache = cache;
-    }
-
-    @Override
-    public ModeledCache<T> getCache()
-    {
-        return cache;
-    }
-
-    @Override
-    public void start()
-    {
-        cache.start();
-    }
-
-    @Override
-    public void close()
-    {
-        cache.close();
-    }
-
-    @Override
-    public CachedModeledCuratorFramework<T> cached()
-    {
-        return this;
-    }
-
-    @Override
-    public CuratorFramework unwrap()
-    {
-        return client.unwrap();
-    }
-
-    @Override
-    public ModelSpec<T> modelSpec()
-    {
-        return client.modelSpec();
-    }
-
-    @Override
-    public CachedModeledCuratorFramework<T> at(String child)
-    {
-        return new CachedModeledCuratorFrameworkImpl<>(client.at(child), 
cache);
-    }
-
-    @Override
-    public CachedModeledCuratorFramework<T> at(ZPath path)
-    {
-        return new CachedModeledCuratorFrameworkImpl<>(client.at(path), cache);
-    }
-
-    @Override
-    public CachedModeledCuratorFramework<T> resolved(T model)
-    {
-        return new CachedModeledCuratorFrameworkImpl<>(client.resolved(model), 
cache);
-    }
-
-    @Override
-    public AsyncStage<String> set(T model)
-    {
-        return client.set(model);
-    }
-
-    @Override
-    public AsyncStage<String> set(T model, Stat storingStatIn)
-    {
-        return client.set(model, storingStatIn);
-    }
-
-    @Override
-    public AsyncStage<T> read()
-    {
-        return read(null);
-    }
-
-    @Override
-    public AsyncStage<T> read(Stat storingStatIn)
-    {
-        ZPath path = client.modelSpec().path();
-        Optional<ZNode<T>> data = cache.currentData(path);
-        return data.map(node -> {
-            if ( storingStatIn != null )
-            {
-                DataTree.copyStat(node.stat(), storingStatIn);
-            }
-            return new ModelStage<>(node.model());
-        }).orElseGet(() -> new ModelStage<>(new 
KeeperException.NoNodeException(path.fullPath())));
-    }
-
-    @Override
-    public AsyncStage<Stat> update(T model)
-    {
-        return client.update(model);
-    }
-
-    @Override
-    public AsyncStage<Stat> update(T model, int version)
-    {
-        return client.update(model, version);
-    }
-
-    @Override
-    public AsyncStage<Void> delete()
-    {
-        return client.delete();
-    }
-
-    @Override
-    public AsyncStage<Void> delete(int version)
-    {
-        return client.delete(version);
-    }
-
-    @Override
-    public AsyncStage<Stat> checkExists()
-    {
-        ZPath path = client.modelSpec().path();
-        Optional<ZNode<T>> data = cache.currentData(path);
-        return data.map(node -> new ModelStage<>(node.stat())).orElseGet(() -> 
new ModelStage<>((Stat)null));
-    }
-
-    @Override
-    public AsyncStage<List<ZPath>> children()
-    {
-        Set<ZPath> paths = 
cache.currentChildren(client.modelSpec().path()).keySet();
-        return new ModelStage<>(Lists.newArrayList(paths));
-    }
-
-    @Override
-    public CuratorOp createOp(T model)
-    {
-        return client.createOp(model);
-    }
-
-    @Override
-    public CuratorOp updateOp(T model)
-    {
-        return client.updateOp(model);
-    }
-
-    @Override
-    public CuratorOp updateOp(T model, int version)
-    {
-        return client.updateOp(model, version);
-    }
-
-    @Override
-    public CuratorOp deleteOp()
-    {
-        return client.deleteOp();
-    }
-
-    @Override
-    public CuratorOp deleteOp(int version)
-    {
-        return client.deleteOp(version);
-    }
-
-    @Override
-    public CuratorOp checkExistsOp()
-    {
-        return client.checkExistsOp();
-    }
-
-    @Override
-    public CuratorOp checkExistsOp(int version)
-    {
-        return client.checkExistsOp(version);
-    }
-
-    @Override
-    public AsyncStage<List<CuratorTransactionResult>> 
inTransaction(List<CuratorOp> operations)
-    {
-        return client.inTransaction(operations);
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledFrameworkImpl.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledFrameworkImpl.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledFrameworkImpl.java
new file mode 100644
index 0000000..2f375a9
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/CachedModeledFrameworkImpl.java
@@ -0,0 +1,228 @@
+/**
+ * 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.x.async.modeled.details;
+
+import com.google.common.collect.Lists;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.api.transaction.CuratorOp;
+import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
+import org.apache.curator.x.async.AsyncStage;
+import org.apache.curator.x.async.api.CreateOption;
+import org.apache.curator.x.async.modeled.ModelSpec;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.cached.ZNode;
+import org.apache.curator.x.async.modeled.ZPath;
+import org.apache.curator.x.async.modeled.cached.CachedModeledFramework;
+import org.apache.curator.x.async.modeled.cached.ModeledCache;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.DataTree;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+class CachedModeledFrameworkImpl<T> implements CachedModeledFramework<T>
+{
+    private final ModeledFramework<T> client;
+    private final ModeledCacheImpl<T> cache;
+
+    CachedModeledFrameworkImpl(ModeledFramework<T> client)
+    {
+        this(client, new ModeledCacheImpl<>(client.unwrap(), 
client.modelSpec().path(), client.modelSpec().serializer(), 
client.modelSpec().createOptions().contains(CreateOption.compress)));
+    }
+
+    private CachedModeledFrameworkImpl(ModeledFramework<T> client, 
ModeledCacheImpl<T> cache)
+    {
+        this.client = client;
+        this.cache = cache;
+    }
+
+    @Override
+    public ModeledCache<T> getCache()
+    {
+        return cache;
+    }
+
+    @Override
+    public void start()
+    {
+        cache.start();
+    }
+
+    @Override
+    public void close()
+    {
+        cache.close();
+    }
+
+    @Override
+    public CachedModeledFramework<T> cached()
+    {
+        return this;
+    }
+
+    @Override
+    public CuratorFramework unwrap()
+    {
+        return client.unwrap();
+    }
+
+    @Override
+    public ModelSpec<T> modelSpec()
+    {
+        return client.modelSpec();
+    }
+
+    @Override
+    public CachedModeledFramework<T> at(String child)
+    {
+        return new CachedModeledFrameworkImpl<>(client.at(child), cache);
+    }
+
+    @Override
+    public CachedModeledFramework<T> at(ZPath path)
+    {
+        return new CachedModeledFrameworkImpl<>(client.at(path), cache);
+    }
+
+    @Override
+    public CachedModeledFramework<T> resolved(T model)
+    {
+        return new CachedModeledFrameworkImpl<>(client.resolved(model), cache);
+    }
+
+    @Override
+    public AsyncStage<String> set(T model)
+    {
+        return client.set(model);
+    }
+
+    @Override
+    public AsyncStage<String> set(T model, Stat storingStatIn)
+    {
+        return client.set(model, storingStatIn);
+    }
+
+    @Override
+    public AsyncStage<T> read()
+    {
+        return read(null);
+    }
+
+    @Override
+    public AsyncStage<T> read(Stat storingStatIn)
+    {
+        ZPath path = client.modelSpec().path();
+        Optional<ZNode<T>> data = cache.currentData(path);
+        return data.map(node -> {
+            if ( storingStatIn != null )
+            {
+                DataTree.copyStat(node.stat(), storingStatIn);
+            }
+            return new ModelStage<>(node.model());
+        }).orElseGet(() -> new ModelStage<>(new 
KeeperException.NoNodeException(path.fullPath())));
+    }
+
+    @Override
+    public AsyncStage<Stat> update(T model)
+    {
+        return client.update(model);
+    }
+
+    @Override
+    public AsyncStage<Stat> update(T model, int version)
+    {
+        return client.update(model, version);
+    }
+
+    @Override
+    public AsyncStage<Void> delete()
+    {
+        return client.delete();
+    }
+
+    @Override
+    public AsyncStage<Void> delete(int version)
+    {
+        return client.delete(version);
+    }
+
+    @Override
+    public AsyncStage<Stat> checkExists()
+    {
+        ZPath path = client.modelSpec().path();
+        Optional<ZNode<T>> data = cache.currentData(path);
+        return data.map(node -> new ModelStage<>(node.stat())).orElseGet(() -> 
new ModelStage<>((Stat)null));
+    }
+
+    @Override
+    public AsyncStage<List<ZPath>> children()
+    {
+        Set<ZPath> paths = 
cache.currentChildren(client.modelSpec().path()).keySet();
+        return new ModelStage<>(Lists.newArrayList(paths));
+    }
+
+    @Override
+    public CuratorOp createOp(T model)
+    {
+        return client.createOp(model);
+    }
+
+    @Override
+    public CuratorOp updateOp(T model)
+    {
+        return client.updateOp(model);
+    }
+
+    @Override
+    public CuratorOp updateOp(T model, int version)
+    {
+        return client.updateOp(model, version);
+    }
+
+    @Override
+    public CuratorOp deleteOp()
+    {
+        return client.deleteOp();
+    }
+
+    @Override
+    public CuratorOp deleteOp(int version)
+    {
+        return client.deleteOp(version);
+    }
+
+    @Override
+    public CuratorOp checkExistsOp()
+    {
+        return client.checkExistsOp();
+    }
+
+    @Override
+    public CuratorOp checkExistsOp(int version)
+    {
+        return client.checkExistsOp(version);
+    }
+
+    @Override
+    public AsyncStage<List<CuratorTransactionResult>> 
inTransaction(List<CuratorOp> operations)
+    {
+        return client.inTransaction(operations);
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java
index 1ce7134..fb1b888 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModelSpecImpl.java
@@ -25,16 +25,16 @@ import org.apache.curator.framework.schema.SchemaValidator;
 import org.apache.curator.framework.schema.SchemaViolation;
 import org.apache.curator.x.async.api.CreateOption;
 import org.apache.curator.x.async.api.DeleteOption;
-import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSerializer;
+import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ZPath;
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.data.ACL;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Function;
 
 public class ModelSpecImpl<T> implements ModelSpec<T>, SchemaValidator
 {
@@ -45,9 +45,8 @@ public class ModelSpecImpl<T> implements ModelSpec<T>, 
SchemaValidator
     private final Set<CreateOption> createOptions;
     private final Set<DeleteOption> deleteOptions;
     private final AtomicReference<Schema> schema = new AtomicReference<>();
-    private final Function<T, String> nodeName;
 
-    public ModelSpecImpl(ZPath path, ModelSerializer<T> serializer, CreateMode 
createMode, List<ACL> aclList, Set<CreateOption> createOptions, 
Set<DeleteOption> deleteOptions, Function<T, String> nodeName)
+    public ModelSpecImpl(ZPath path, ModelSerializer<T> serializer, CreateMode 
createMode, List<ACL> aclList, Set<CreateOption> createOptions, 
Set<DeleteOption> deleteOptions)
     {
         this.path = Objects.requireNonNull(path, "path cannot be null");
         this.serializer = Objects.requireNonNull(serializer, "serializer 
cannot be null");
@@ -55,7 +54,6 @@ public class ModelSpecImpl<T> implements ModelSpec<T>, 
SchemaValidator
         this.aclList = ImmutableList.copyOf(Objects.requireNonNull(aclList, 
"aclList cannot be null"));
         this.createOptions = 
ImmutableSet.copyOf(Objects.requireNonNull(createOptions, "createOptions cannot 
be null"));
         this.deleteOptions = 
ImmutableSet.copyOf(Objects.requireNonNull(deleteOptions, "deleteOptions cannot 
be null"));
-        this.nodeName = Objects.requireNonNull(nodeName, "nodeName cannot be 
null");
     }
 
     @Override
@@ -67,13 +65,13 @@ public class ModelSpecImpl<T> implements ModelSpec<T>, 
SchemaValidator
     @Override
     public ModelSpec<T> resolved(T model)
     {
-        return at(path.at(nodeName.apply(model)));
+        return at(path.at(NodeName.nameFrom(model)));
     }
 
     @Override
     public ModelSpec<T> at(ZPath newPath)
     {
-        return new ModelSpecImpl<>(newPath, serializer, createMode, aclList, 
createOptions, deleteOptions, nodeName);
+        return new ModelSpecImpl<>(newPath, serializer, createMode, aclList, 
createOptions, deleteOptions);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java
deleted file mode 100644
index 202e62f..0000000
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledCuratorFrameworkImpl.java
+++ /dev/null
@@ -1,335 +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.x.async.modeled.details;
-
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.api.CuratorEvent;
-import org.apache.curator.framework.api.UnhandledErrorListener;
-import org.apache.curator.framework.api.transaction.CuratorOp;
-import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
-import org.apache.curator.x.async.AsyncCuratorFramework;
-import org.apache.curator.x.async.AsyncStage;
-import org.apache.curator.x.async.WatchMode;
-import org.apache.curator.x.async.api.AsyncCuratorFrameworkDsl;
-import org.apache.curator.x.async.api.AsyncPathAndBytesable;
-import org.apache.curator.x.async.api.AsyncPathable;
-import org.apache.curator.x.async.api.AsyncTransactionSetDataBuilder;
-import org.apache.curator.x.async.api.CreateOption;
-import org.apache.curator.x.async.api.WatchableAsyncCuratorFramework;
-import org.apache.curator.x.async.modeled.ModelSpec;
-import org.apache.curator.x.async.modeled.ModeledCuratorFramework;
-import org.apache.curator.x.async.modeled.ZPath;
-import org.apache.curator.x.async.modeled.cached.CachedModeledCuratorFramework;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.UnaryOperator;
-import java.util.stream.Collectors;
-
-public class ModeledCuratorFrameworkImpl<T> implements 
ModeledCuratorFramework<T>
-{
-    private final AsyncCuratorFramework client;
-    private final WatchableAsyncCuratorFramework watchableClient;
-    private final ModelSpec<T> modelSpec;
-    private final WatchMode watchMode;
-    private final UnaryOperator<WatchedEvent> watcherFilter;
-    private final UnhandledErrorListener unhandledErrorListener;
-    private final UnaryOperator<CuratorEvent> resultFilter;
-    private final AsyncCuratorFrameworkDsl dslClient;
-
-    public static <T> ModeledCuratorFrameworkImpl<T> build(CuratorFramework 
client, ModelSpec<T> model, WatchMode watchMode, UnaryOperator<WatchedEvent> 
watcherFilter, UnhandledErrorListener unhandledErrorListener, 
UnaryOperator<CuratorEvent> resultFilter)
-    {
-        boolean localIsWatched = (watchMode != null);
-
-        Objects.requireNonNull(client, "client cannot be null");
-        Objects.requireNonNull(model, "model cannot be null");
-
-        watchMode = (watchMode != null) ? watchMode : 
WatchMode.stateChangeAndSuccess;
-
-        AsyncCuratorFramework asyncClient = AsyncCuratorFramework.wrap(client);
-        AsyncCuratorFrameworkDsl dslClient = asyncClient.with(watchMode, 
unhandledErrorListener, resultFilter, watcherFilter);
-        WatchableAsyncCuratorFramework watchableClient = localIsWatched ? 
dslClient.watched() : dslClient;
-
-        return new ModeledCuratorFrameworkImpl<>(
-            asyncClient,
-            dslClient,
-            watchableClient,
-            model,
-            watchMode,
-            watcherFilter,
-            unhandledErrorListener,
-            resultFilter
-        );
-    }
-
-    private ModeledCuratorFrameworkImpl(AsyncCuratorFramework client, 
AsyncCuratorFrameworkDsl dslClient, WatchableAsyncCuratorFramework 
watchableClient, ModelSpec<T> modelSpec, WatchMode watchMode, 
UnaryOperator<WatchedEvent> watcherFilter, UnhandledErrorListener 
unhandledErrorListener, UnaryOperator<CuratorEvent> resultFilter)
-    {
-        this.client = client;
-        this.dslClient = dslClient;
-        this.watchableClient = watchableClient;
-        this.modelSpec = modelSpec;
-        this.watchMode = watchMode;
-        this.watcherFilter = watcherFilter;
-        this.unhandledErrorListener = unhandledErrorListener;
-        this.resultFilter = resultFilter;
-    }
-
-    @Override
-    public CachedModeledCuratorFramework<T> cached()
-    {
-        return new CachedModeledCuratorFrameworkImpl<>(this);
-    }
-
-    @Override
-    public ModelSpec<T> modelSpec()
-    {
-        return modelSpec;
-    }
-
-    @Override
-    public CuratorFramework unwrap()
-    {
-        return client.unwrap();
-    }
-
-    @Override
-    public AsyncStage<String> set(T item)
-    {
-        return set(item, null);
-    }
-
-    @Override
-    public AsyncStage<String> set(T item, Stat storingStatIn)
-    {
-        byte[] bytes = modelSpec.serializer().serialize(item);
-        return dslClient.create().withOptions(modelSpec.createOptions(), 
modelSpec.createMode(), fixAclList(modelSpec.aclList()), 
storingStatIn).forPath(modelSpec.path().fullPath(), bytes);
-    }
-
-    private List<ACL> fixAclList(List<ACL> aclList)
-    {
-        return (aclList.size() > 0) ? aclList : null;   // workaround for old, 
bad design. empty list not accepted
-    }
-
-    @Override
-    public AsyncStage<T> read()
-    {
-        return read(null);
-    }
-
-    @Override
-    public AsyncStage<T> read(Stat storingStatIn)
-    {
-        AsyncPathable<AsyncStage<byte[]>> next;
-        if ( isCompressed() )
-        {
-            next = (storingStatIn != null) ? 
watchableClient.getData().decompressedStoringStatIn(storingStatIn) : 
watchableClient.getData().decompressed();
-        }
-        else
-        {
-            next = (storingStatIn != null) ? 
watchableClient.getData().storingStatIn(storingStatIn) : 
watchableClient.getData();
-        }
-        AsyncStage<byte[]> asyncStage = 
next.forPath(modelSpec.path().fullPath());
-        ModelStage<T> modelStage = new ModelStage<>(asyncStage.event());
-        asyncStage.whenComplete((value, e) -> {
-            if ( e != null )
-            {
-                modelStage.completeExceptionally(e);
-            }
-            else
-            {
-                try
-                {
-                    
modelStage.complete(modelSpec.serializer().deserialize(value));
-                }
-                catch ( Exception deserializeException )
-                {
-                    modelStage.completeExceptionally(deserializeException);
-                }
-            }
-        });
-        return modelStage;
-    }
-
-    @Override
-    public AsyncStage<Stat> update(T item)
-    {
-        return update(item, -1);
-    }
-
-    @Override
-    public AsyncStage<Stat> update(T item, int version)
-    {
-        byte[] bytes = modelSpec.serializer().serialize(item);
-        AsyncPathAndBytesable<AsyncStage<Stat>> next = isCompressed() ? 
dslClient.setData().compressedWithVersion(version) : dslClient.setData();
-        return next.forPath(modelSpec.path().fullPath(), bytes);
-    }
-
-    @Override
-    public AsyncStage<Stat> checkExists()
-    {
-        return 
watchableClient.checkExists().forPath(modelSpec.path().fullPath());
-    }
-
-    @Override
-    public AsyncStage<Void> delete()
-    {
-        return delete(-1);
-    }
-
-    @Override
-    public AsyncStage<Void> delete(int version)
-    {
-        return 
dslClient.delete().withVersion(-1).forPath(modelSpec.path().fullPath());
-    }
-
-    @Override
-    public AsyncStage<List<ZPath>> children()
-    {
-        AsyncStage<List<String>> asyncStage = 
watchableClient.getChildren().forPath(modelSpec.path().fullPath());
-        ModelStage<List<ZPath>> modelStage = new 
ModelStage<>(asyncStage.event());
-        asyncStage.whenComplete((children, e) -> {
-            if ( e != null )
-            {
-                modelStage.completeExceptionally(e);
-            }
-            else
-            {
-                modelStage.complete(children.stream().map(child -> 
modelSpec.path().at(child)).collect(Collectors.toList()));
-            }
-        });
-        return modelStage;
-    }
-
-    @Override
-    public ModeledCuratorFramework<T> at(String child)
-    {
-        ModelSpec<T> newModelSpec = modelSpec.at(child);
-        return new ModeledCuratorFrameworkImpl<>(
-            client,
-            dslClient,
-            watchableClient,
-            newModelSpec,
-            watchMode,
-            watcherFilter,
-            unhandledErrorListener,
-            resultFilter
-        );
-    }
-
-    @Override
-    public ModeledCuratorFramework<T> at(ZPath path)
-    {
-        ModelSpec<T> newModelSpec = modelSpec.at(path);
-        return new ModeledCuratorFrameworkImpl<>(
-            client,
-            dslClient,
-            watchableClient,
-            newModelSpec,
-            watchMode,
-            watcherFilter,
-            unhandledErrorListener,
-            resultFilter
-        );
-    }
-
-    @Override
-    public ModeledCuratorFramework<T> resolved(T model)
-    {
-        ModelSpec<T> newModelSpec = modelSpec.resolved(model);
-        return new ModeledCuratorFrameworkImpl<>(
-            client,
-            dslClient,
-            watchableClient,
-            newModelSpec,
-            watchMode,
-            watcherFilter,
-            unhandledErrorListener,
-            resultFilter
-        );
-    }
-
-    public static boolean isCompressed(Set<CreateOption> createOptions)
-    {
-        return createOptions.contains(CreateOption.compress);
-    }
-
-    @Override
-    public CuratorOp createOp(T model)
-    {
-        return client.transactionOp()
-            .create()
-            .withOptions(modelSpec.createMode(), modelSpec.aclList(), 
modelSpec.createOptions().contains(CreateOption.compress))
-            .forPath(modelSpec.path().fullPath(), 
modelSpec.serializer().serialize(model));
-    }
-
-    @Override
-    public CuratorOp updateOp(T model)
-    {
-        return updateOp(model, -1);
-    }
-
-    @Override
-    public CuratorOp updateOp(T model, int version)
-    {
-        AsyncTransactionSetDataBuilder builder = 
client.transactionOp().setData();
-        if ( isCompressed() )
-        {
-            return 
builder.withVersionCompressed(version).forPath(modelSpec.path().fullPath(), 
modelSpec.serializer().serialize(model));
-        }
-        return 
builder.withVersion(version).forPath(modelSpec.path().fullPath(), 
modelSpec.serializer().serialize(model));
-    }
-
-    @Override
-    public CuratorOp deleteOp()
-    {
-        return deleteOp(-1);
-    }
-
-    @Override
-    public CuratorOp deleteOp(int version)
-    {
-        return 
client.transactionOp().delete().withVersion(version).forPath(modelSpec.path().fullPath());
-    }
-
-    @Override
-    public CuratorOp checkExistsOp()
-    {
-        return checkExistsOp(-1);
-    }
-
-    @Override
-    public CuratorOp checkExistsOp(int version)
-    {
-        return 
client.transactionOp().check().withVersion(version).forPath(modelSpec.path().fullPath());
-    }
-
-    @Override
-    public AsyncStage<List<CuratorTransactionResult>> 
inTransaction(List<CuratorOp> operations)
-    {
-        return client.transaction().forOperations(operations);
-    }
-
-    private boolean isCompressed()
-    {
-        return modelSpec.createOptions().contains(CreateOption.compress);
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledFrameworkImpl.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledFrameworkImpl.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledFrameworkImpl.java
new file mode 100644
index 0000000..46e88f5
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/details/ModeledFrameworkImpl.java
@@ -0,0 +1,335 @@
+/**
+ * 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.x.async.modeled.details;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.api.CuratorEvent;
+import org.apache.curator.framework.api.UnhandledErrorListener;
+import org.apache.curator.framework.api.transaction.CuratorOp;
+import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.AsyncStage;
+import org.apache.curator.x.async.WatchMode;
+import org.apache.curator.x.async.api.AsyncCuratorFrameworkDsl;
+import org.apache.curator.x.async.api.AsyncPathAndBytesable;
+import org.apache.curator.x.async.api.AsyncPathable;
+import org.apache.curator.x.async.api.AsyncTransactionSetDataBuilder;
+import org.apache.curator.x.async.api.CreateOption;
+import org.apache.curator.x.async.api.WatchableAsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.ModelSpec;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ZPath;
+import org.apache.curator.x.async.modeled.cached.CachedModeledFramework;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.UnaryOperator;
+import java.util.stream.Collectors;
+
+public class ModeledFrameworkImpl<T> implements ModeledFramework<T>
+{
+    private final AsyncCuratorFramework client;
+    private final WatchableAsyncCuratorFramework watchableClient;
+    private final ModelSpec<T> modelSpec;
+    private final WatchMode watchMode;
+    private final UnaryOperator<WatchedEvent> watcherFilter;
+    private final UnhandledErrorListener unhandledErrorListener;
+    private final UnaryOperator<CuratorEvent> resultFilter;
+    private final AsyncCuratorFrameworkDsl dslClient;
+
+    public static <T> ModeledFrameworkImpl<T> build(CuratorFramework client, 
ModelSpec<T> model, WatchMode watchMode, UnaryOperator<WatchedEvent> 
watcherFilter, UnhandledErrorListener unhandledErrorListener, 
UnaryOperator<CuratorEvent> resultFilter)
+    {
+        boolean localIsWatched = (watchMode != null);
+
+        Objects.requireNonNull(client, "client cannot be null");
+        Objects.requireNonNull(model, "model cannot be null");
+
+        watchMode = (watchMode != null) ? watchMode : 
WatchMode.stateChangeAndSuccess;
+
+        AsyncCuratorFramework asyncClient = AsyncCuratorFramework.wrap(client);
+        AsyncCuratorFrameworkDsl dslClient = asyncClient.with(watchMode, 
unhandledErrorListener, resultFilter, watcherFilter);
+        WatchableAsyncCuratorFramework watchableClient = localIsWatched ? 
dslClient.watched() : dslClient;
+
+        return new ModeledFrameworkImpl<>(
+            asyncClient,
+            dslClient,
+            watchableClient,
+            model,
+            watchMode,
+            watcherFilter,
+            unhandledErrorListener,
+            resultFilter
+        );
+    }
+
+    private ModeledFrameworkImpl(AsyncCuratorFramework client, 
AsyncCuratorFrameworkDsl dslClient, WatchableAsyncCuratorFramework 
watchableClient, ModelSpec<T> modelSpec, WatchMode watchMode, 
UnaryOperator<WatchedEvent> watcherFilter, UnhandledErrorListener 
unhandledErrorListener, UnaryOperator<CuratorEvent> resultFilter)
+    {
+        this.client = client;
+        this.dslClient = dslClient;
+        this.watchableClient = watchableClient;
+        this.modelSpec = modelSpec;
+        this.watchMode = watchMode;
+        this.watcherFilter = watcherFilter;
+        this.unhandledErrorListener = unhandledErrorListener;
+        this.resultFilter = resultFilter;
+    }
+
+    @Override
+    public CachedModeledFramework<T> cached()
+    {
+        return new CachedModeledFrameworkImpl<>(this);
+    }
+
+    @Override
+    public ModelSpec<T> modelSpec()
+    {
+        return modelSpec;
+    }
+
+    @Override
+    public CuratorFramework unwrap()
+    {
+        return client.unwrap();
+    }
+
+    @Override
+    public AsyncStage<String> set(T item)
+    {
+        return set(item, null);
+    }
+
+    @Override
+    public AsyncStage<String> set(T item, Stat storingStatIn)
+    {
+        byte[] bytes = modelSpec.serializer().serialize(item);
+        return dslClient.create().withOptions(modelSpec.createOptions(), 
modelSpec.createMode(), fixAclList(modelSpec.aclList()), 
storingStatIn).forPath(modelSpec.path().fullPath(), bytes);
+    }
+
+    private List<ACL> fixAclList(List<ACL> aclList)
+    {
+        return (aclList.size() > 0) ? aclList : null;   // workaround for old, 
bad design. empty list not accepted
+    }
+
+    @Override
+    public AsyncStage<T> read()
+    {
+        return read(null);
+    }
+
+    @Override
+    public AsyncStage<T> read(Stat storingStatIn)
+    {
+        AsyncPathable<AsyncStage<byte[]>> next;
+        if ( isCompressed() )
+        {
+            next = (storingStatIn != null) ? 
watchableClient.getData().decompressedStoringStatIn(storingStatIn) : 
watchableClient.getData().decompressed();
+        }
+        else
+        {
+            next = (storingStatIn != null) ? 
watchableClient.getData().storingStatIn(storingStatIn) : 
watchableClient.getData();
+        }
+        AsyncStage<byte[]> asyncStage = 
next.forPath(modelSpec.path().fullPath());
+        ModelStage<T> modelStage = new ModelStage<>(asyncStage.event());
+        asyncStage.whenComplete((value, e) -> {
+            if ( e != null )
+            {
+                modelStage.completeExceptionally(e);
+            }
+            else
+            {
+                try
+                {
+                    
modelStage.complete(modelSpec.serializer().deserialize(value));
+                }
+                catch ( Exception deserializeException )
+                {
+                    modelStage.completeExceptionally(deserializeException);
+                }
+            }
+        });
+        return modelStage;
+    }
+
+    @Override
+    public AsyncStage<Stat> update(T item)
+    {
+        return update(item, -1);
+    }
+
+    @Override
+    public AsyncStage<Stat> update(T item, int version)
+    {
+        byte[] bytes = modelSpec.serializer().serialize(item);
+        AsyncPathAndBytesable<AsyncStage<Stat>> next = isCompressed() ? 
dslClient.setData().compressedWithVersion(version) : dslClient.setData();
+        return next.forPath(modelSpec.path().fullPath(), bytes);
+    }
+
+    @Override
+    public AsyncStage<Stat> checkExists()
+    {
+        return 
watchableClient.checkExists().forPath(modelSpec.path().fullPath());
+    }
+
+    @Override
+    public AsyncStage<Void> delete()
+    {
+        return delete(-1);
+    }
+
+    @Override
+    public AsyncStage<Void> delete(int version)
+    {
+        return 
dslClient.delete().withVersion(-1).forPath(modelSpec.path().fullPath());
+    }
+
+    @Override
+    public AsyncStage<List<ZPath>> children()
+    {
+        AsyncStage<List<String>> asyncStage = 
watchableClient.getChildren().forPath(modelSpec.path().fullPath());
+        ModelStage<List<ZPath>> modelStage = new 
ModelStage<>(asyncStage.event());
+        asyncStage.whenComplete((children, e) -> {
+            if ( e != null )
+            {
+                modelStage.completeExceptionally(e);
+            }
+            else
+            {
+                modelStage.complete(children.stream().map(child -> 
modelSpec.path().at(child)).collect(Collectors.toList()));
+            }
+        });
+        return modelStage;
+    }
+
+    @Override
+    public ModeledFramework<T> at(String child)
+    {
+        ModelSpec<T> newModelSpec = modelSpec.at(child);
+        return new ModeledFrameworkImpl<>(
+            client,
+            dslClient,
+            watchableClient,
+            newModelSpec,
+            watchMode,
+            watcherFilter,
+            unhandledErrorListener,
+            resultFilter
+        );
+    }
+
+    @Override
+    public ModeledFramework<T> at(ZPath path)
+    {
+        ModelSpec<T> newModelSpec = modelSpec.at(path);
+        return new ModeledFrameworkImpl<>(
+            client,
+            dslClient,
+            watchableClient,
+            newModelSpec,
+            watchMode,
+            watcherFilter,
+            unhandledErrorListener,
+            resultFilter
+        );
+    }
+
+    @Override
+    public ModeledFramework<T> resolved(T model)
+    {
+        ModelSpec<T> newModelSpec = modelSpec.resolved(model);
+        return new ModeledFrameworkImpl<>(
+            client,
+            dslClient,
+            watchableClient,
+            newModelSpec,
+            watchMode,
+            watcherFilter,
+            unhandledErrorListener,
+            resultFilter
+        );
+    }
+
+    public static boolean isCompressed(Set<CreateOption> createOptions)
+    {
+        return createOptions.contains(CreateOption.compress);
+    }
+
+    @Override
+    public CuratorOp createOp(T model)
+    {
+        return client.transactionOp()
+            .create()
+            .withOptions(modelSpec.createMode(), modelSpec.aclList(), 
modelSpec.createOptions().contains(CreateOption.compress))
+            .forPath(modelSpec.path().fullPath(), 
modelSpec.serializer().serialize(model));
+    }
+
+    @Override
+    public CuratorOp updateOp(T model)
+    {
+        return updateOp(model, -1);
+    }
+
+    @Override
+    public CuratorOp updateOp(T model, int version)
+    {
+        AsyncTransactionSetDataBuilder builder = 
client.transactionOp().setData();
+        if ( isCompressed() )
+        {
+            return 
builder.withVersionCompressed(version).forPath(modelSpec.path().fullPath(), 
modelSpec.serializer().serialize(model));
+        }
+        return 
builder.withVersion(version).forPath(modelSpec.path().fullPath(), 
modelSpec.serializer().serialize(model));
+    }
+
+    @Override
+    public CuratorOp deleteOp()
+    {
+        return deleteOp(-1);
+    }
+
+    @Override
+    public CuratorOp deleteOp(int version)
+    {
+        return 
client.transactionOp().delete().withVersion(version).forPath(modelSpec.path().fullPath());
+    }
+
+    @Override
+    public CuratorOp checkExistsOp()
+    {
+        return checkExistsOp(-1);
+    }
+
+    @Override
+    public CuratorOp checkExistsOp(int version)
+    {
+        return 
client.transactionOp().check().withVersion(version).forPath(modelSpec.path().fullPath());
+    }
+
+    @Override
+    public AsyncStage<List<CuratorTransactionResult>> 
inTransaction(List<CuratorOp> operations)
+    {
+        return client.transaction().forOperations(operations);
+    }
+
+    private boolean isCompressed()
+    {
+        return modelSpec.createOptions().contains(CreateOption.compress);
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
index 8e0f101..6a61f64 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec<M, P1>
 {
     /**

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
index b31aaa5..e6e8be3 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec10.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec10<M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 
p8, P9 p9, P10 p10);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
index 19fed0a..b8d36ea 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec2.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec2<M, P1, P2>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
index 2dc7595..1ee78ff 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec3.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec3<M, P1, P2, P3>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2, P3 p3);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
index d233be5..f15cf8b 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec4.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec4<M, P1, P2, P3, P4>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2, P3 p3, P4 p4);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
index 685cf2c..09fe323 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec5.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec5<M, P1, P2, P3, P4, P5>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
index abe811f..58c0607 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec6.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec6<M, P1, P2, P3, P4, P5, P6>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
index a4e6fdd..2232a88 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec7.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec7<M, P1, P2, P3, P4, P5, P6, P7>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
index 52b2cb4..b99de07 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec8.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec8<M, P1, P2, P3, P4, P5, P6, P7, P8>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 
p8);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
index a1ab075..358e31b 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModelSpec9.java
@@ -3,6 +3,7 @@ package org.apache.curator.x.async.modeled.typed;
 import org.apache.curator.x.async.modeled.ModelSpec;
 import org.apache.curator.x.async.modeled.ModelSpecBuilder;
 
+@FunctionalInterface
 public interface TypedModelSpec9<M, P1, P2, P3, P4, P5, P6, P7, P8, P9>
 {
     ModelSpec<M> resolved(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 
p8, P9 p9);

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java
new file mode 100644
index 0000000..3e14240
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework.java
@@ -0,0 +1,32 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework<M, P1>
+{
+    /**
+     * Resolve into a ModeledFramework using the given parameter
+     *
+     * @param client the curator instance to use
+     * @param p1 the parameter
+     * @return ZPath
+     */
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object)} is called the actual 
ModeledFramework is generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1> TypedModeledFramework<M, P1> 
from(ModeledFrameworkBuilder<M> frameworkBuilder, TypedModelSpec<M, P1> 
modelSpec)
+    {
+        return (client, p1) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java
new file mode 100644
index 0000000..c5f6bdc
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework10.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework10<M, P1, P2, P3, P4, P5, P6, P7, P8, 
P9, P10>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2, P3 p3, 
P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object, Object, Object, 
Object, Object, Object, Object, Object, Object)} is called the actual 
ModeledFramework is generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> 
TypedModeledFramework10<M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> 
from(ModeledFrameworkBuilder<M> frameworkBuilder, TypedModelSpec10<M, P1, P2, 
P3, P4, P5, P6, P7, P8, P9, P10> modelSpec)
+    {
+        return (client, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, 
p3, p4, p5, p6, p7, p8, p9, p10)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java
new file mode 100644
index 0000000..596a869
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework2.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework2<M, P1, P2>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object)} is called the 
actual ModeledFramework is generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2> TypedModeledFramework2<M, P1, P2> 
from(ModeledFrameworkBuilder<M> frameworkBuilder, TypedModelSpec2<M, P1, P2> 
modelSpec)
+    {
+        return (client, p1, p2) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, 
p2)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java
new file mode 100644
index 0000000..647238d
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework3.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework3<M, P1, P2, P3>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2, P3 p3);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object, Object)} is 
called the actual ModeledFramework is generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3> TypedModeledFramework3<M, P1, P2, P3> 
from(ModeledFrameworkBuilder<M> frameworkBuilder, TypedModelSpec3<M, P1, P2, 
P3> modelSpec)
+    {
+        return (client, p1, p2, p3) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, 
p3)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java
new file mode 100644
index 0000000..5f9a069
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework4.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework4<M, P1, P2, P3, P4>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2, P3 p3, 
P4 p4);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object, Object, 
Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4> TypedModeledFramework4<M, P1, P2, P3, P4> 
from(ModeledFrameworkBuilder<M> frameworkBuilder, TypedModelSpec4<M, P1, P2, 
P3, P4> modelSpec)
+    {
+        return (client, p1, p2, p3, p4) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, 
p3, p4)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java
new file mode 100644
index 0000000..723e65a
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework5.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework5<M, P1, P2, P3, P4, P5>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2, P3 p3, 
P4 p4, P5 p5);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object, Object, Object, 
Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5> TypedModeledFramework5<M, P1, P2, P3, P4, 
P5> from(ModeledFrameworkBuilder<M> frameworkBuilder, TypedModelSpec5<M, P1, 
P2, P3, P4, P5> modelSpec)
+    {
+        return (client, p1, p2, p3, p4, p5) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, 
p3, p4, p5)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java
new file mode 100644
index 0000000..2dea518
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework6.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework6<M, P1, P2, P3, P4, P5, P6>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2, P3 p3, 
P4 p4, P5 p5, P6 p6);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object, Object, Object, 
Object, Object)} is called the actual ModeledFramework is generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6> TypedModeledFramework6<M, P1, P2, P3, 
P4, P5, P6> from(ModeledFrameworkBuilder<M> frameworkBuilder, 
TypedModelSpec6<M, P1, P2, P3, P4, P5, P6> modelSpec)
+    {
+        return (client, p1, p2, p3, p4, p5, p6) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, 
p3, p4, p5, p6)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java
new file mode 100644
index 0000000..19a7e67
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework7.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework7<M, P1, P2, P3, P4, P5, P6, P7>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2, P3 p3, 
P4 p4, P5 p5, P6 p6, P7 p7);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object, Object, Object, 
Object, Object, Object)} is called the actual ModeledFramework is generated 
with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7> TypedModeledFramework7<M, P1, P2, 
P3, P4, P5, P6, P7> from(ModeledFrameworkBuilder<M> frameworkBuilder, 
TypedModelSpec7<M, P1, P2, P3, P4, P5, P6, P7> modelSpec)
+    {
+        return (client, p1, p2, p3, p4, p5, p6, p7) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, 
p3, p4, p5, p6, p7)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java
new file mode 100644
index 0000000..50dc248
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework8.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework8<M, P1, P2, P3, P4, P5, P6, P7, P8>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2, P3 p3, 
P4 p4, P5 p5, P6 p6, P7 p7, P8 p8);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object, Object, Object, 
Object, Object, Object, Object)} is called the actual ModeledFramework is 
generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8> TypedModeledFramework8<M, P1, 
P2, P3, P4, P5, P6, P7, P8> from(ModeledFrameworkBuilder<M> frameworkBuilder, 
TypedModelSpec8<M, P1, P2, P3, P4, P5, P6, P7, P8> modelSpec)
+    {
+        return (client, p1, p2, p3, p4, p5, p6, p7, p8) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, 
p3, p4, p5, p6, p7, p8)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java
new file mode 100644
index 0000000..0a2632c
--- /dev/null
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedModeledFramework9.java
@@ -0,0 +1,25 @@
+package org.apache.curator.x.async.modeled.typed;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ModeledFrameworkBuilder;
+
+@FunctionalInterface
+public interface TypedModeledFramework9<M, P1, P2, P3, P4, P5, P6, P7, P8, P9>
+{
+    ModeledFramework<M> resolved(CuratorFramework client, P1 p1, P2 p2, P3 p3, 
P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9);
+
+    /**
+     * Return a new TypedModeledFramework using the given modeled framework 
builder and typed model spec.
+     * When {@link #resolved(CuratorFramework, Object, Object, Object, Object, 
Object, Object, Object, Object, Object)} is called the actual ModeledFramework 
is generated with the
+     * resolved model spec
+     *
+     * @param frameworkBuilder ModeledFrameworkBuilder
+     * @param modelSpec TypedModelSpec
+     * @return new TypedModeledFramework
+     */
+    static <M, P1, P2, P3, P4, P5, P6, P7, P8, P9> TypedModeledFramework9<M, 
P1, P2, P3, P4, P5, P6, P7, P8, P9> from(ModeledFrameworkBuilder<M> 
frameworkBuilder, TypedModelSpec9<M, P1, P2, P3, P4, P5, P6, P7, P8, P9> 
modelSpec)
+    {
+        return (client, p1, p2, p3, p4, p5, p6, p7, p8, p9) -> 
frameworkBuilder.withClient(client).withModelSpec(modelSpec.resolved(p1, p2, 
p3, p4, p5, p6, p7, p8, p9)).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath.java
index 6897980..c76f055 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath.java
@@ -18,6 +18,7 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
@@ -36,6 +37,7 @@ import org.apache.curator.x.async.modeled.ZPath;
  * </pre></code>
  * </p>
  */
+@FunctionalInterface
 public interface TypedZPath<T>
 {
     /**
@@ -65,6 +67,6 @@ public interface TypedZPath<T>
      */
     static <T> TypedZPath<T> from(ZPath path)
     {
-        return path::resolved;
+        return p1 -> path.resolved(NodeName.nameFrom(p1));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath10.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath10.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath10.java
index 2decc50..b289d39 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath10.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath10.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 10 parameters
  */
+@FunctionalInterface
 public interface TypedZPath10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
 {
     ZPath resolved(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 
p9, T10 p10);
@@ -46,6 +48,6 @@ public interface TypedZPath10<T1, T2, T3, T4, T5, T6, T7, T8, 
T9, T10>
      */
     static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> TypedZPath10<T1, T2, T3, 
T4, T5, T6, T7, T8, T9, T10> from(ZPath path)
     {
-        return path::resolved;
+        return (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) -> 
path.resolved(NodeName.nameFrom(p1), NodeName.nameFrom(p2), 
NodeName.nameFrom(p3), NodeName.nameFrom(p4), NodeName.nameFrom(p5), 
NodeName.nameFrom(p6), NodeName.nameFrom(p7), NodeName.nameFrom(p8), 
NodeName.nameFrom(p9), NodeName.nameFrom(p10));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath2.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath2.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath2.java
index 23aad80..6cd6cb3 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath2.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath2.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 2 parameters
  */
+@FunctionalInterface
 public interface TypedZPath2<T1, T2>
 {
     ZPath resolved(T1 p1, T2 p2);
@@ -46,6 +48,6 @@ public interface TypedZPath2<T1, T2>
      */
     static <T1, T2> TypedZPath2<T1, T2> from(ZPath path)
     {
-        return path::resolved;
+        return (p1, p2) -> path.resolved(NodeName.nameFrom(p1), 
NodeName.nameFrom(p2));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath3.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath3.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath3.java
index a3fd53c..507941e 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath3.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath3.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 3 parameters
  */
+@FunctionalInterface
 public interface TypedZPath3<T1, T2, T3>
 {
     ZPath resolved(T1 p1, T2 p2, T3 p3);
@@ -46,6 +48,6 @@ public interface TypedZPath3<T1, T2, T3>
      */
     static <T1, T2, T3> TypedZPath3<T1, T2, T3> from(ZPath path)
     {
-        return path::resolved;
+        return (p1, p2, p3) -> path.resolved(NodeName.nameFrom(p1), 
NodeName.nameFrom(p2), NodeName.nameFrom(p3));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath4.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath4.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath4.java
index 11ac783..1c5a71c 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath4.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath4.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 4 parameters
  */
+@FunctionalInterface
 public interface TypedZPath4<T1, T2, T3, T4>
 {
     ZPath resolved(T1 p1, T2 p2, T3 p3, T4 p4);
@@ -46,6 +48,6 @@ public interface TypedZPath4<T1, T2, T3, T4>
      */
     static <T1, T2, T3, T4> TypedZPath4<T1, T2, T3, T4> from(ZPath path)
     {
-        return path::resolved;
+        return (p1, p2, p3, p4) -> path.resolved(NodeName.nameFrom(p1), 
NodeName.nameFrom(p2), NodeName.nameFrom(p3), NodeName.nameFrom(p4));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath5.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath5.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath5.java
index e238528..e7df047 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath5.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath5.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 5 parameters
  */
+@FunctionalInterface
 public interface TypedZPath5<T1, T2, T3, T4, T5>
 {
     ZPath resolved(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5);
@@ -46,6 +48,6 @@ public interface TypedZPath5<T1, T2, T3, T4, T5>
      */
     static <T1, T2, T3, T4, T5> TypedZPath5<T1, T2, T3, T4, T5> from(ZPath 
path)
     {
-        return path::resolved;
+        return (p1, p2, p3, p4, p5) -> path.resolved(NodeName.nameFrom(p1), 
NodeName.nameFrom(p2), NodeName.nameFrom(p3), NodeName.nameFrom(p4), 
NodeName.nameFrom(p5));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath6.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath6.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath6.java
index 956c544..9f0e5a7 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath6.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath6.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 6 parameters
  */
+@FunctionalInterface
 public interface TypedZPath6<T1, T2, T3, T4, T5, T6>
 {
     ZPath resolved(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6);
@@ -46,6 +48,6 @@ public interface TypedZPath6<T1, T2, T3, T4, T5, T6>
      */
     static <T1, T2, T3, T4, T5, T6> TypedZPath6<T1, T2, T3, T4, T5, T6> 
from(ZPath path)
     {
-        return path::resolved;
+        return (p1, p2, p3, p4, p5, p6) -> 
path.resolved(NodeName.nameFrom(p1), NodeName.nameFrom(p2), 
NodeName.nameFrom(p3), NodeName.nameFrom(p4), NodeName.nameFrom(p5), 
NodeName.nameFrom(p6));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath7.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath7.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath7.java
index 9d9acf1..a4298a4 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath7.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath7.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 7 parameters
  */
+@FunctionalInterface
 public interface TypedZPath7<T1, T2, T3, T4, T5, T6, T7>
 {
     ZPath resolved(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7);
@@ -46,6 +48,6 @@ public interface TypedZPath7<T1, T2, T3, T4, T5, T6, T7>
      */
     static <T1, T2, T3, T4, T5, T6, T7> TypedZPath7<T1, T2, T3, T4, T5, T6, 
T7> from(ZPath path)
     {
-        return path::resolved;
+        return (p1, p2, p3, p4, p5, p6, p7) -> 
path.resolved(NodeName.nameFrom(p1), NodeName.nameFrom(p2), 
NodeName.nameFrom(p3), NodeName.nameFrom(p4), NodeName.nameFrom(p5), 
NodeName.nameFrom(p6), NodeName.nameFrom(p7));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath8.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath8.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath8.java
index f6f2a18..0e774fb 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath8.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath8.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 8 parameters
  */
+@FunctionalInterface
 public interface TypedZPath8<T1, T2, T3, T4, T5, T6, T7, T8>
 {
     ZPath resolved(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8);
@@ -46,6 +48,6 @@ public interface TypedZPath8<T1, T2, T3, T4, T5, T6, T7, T8>
      */
     static <T1, T2, T3, T4, T5, T6, T7, T8> TypedZPath8<T1, T2, T3, T4, T5, 
T6, T7, T8> from(ZPath path)
     {
-        return path::resolved;
+        return (p1, p2, p3, p4, p5, p6, p7, p8) -> 
path.resolved(NodeName.nameFrom(p1), NodeName.nameFrom(p2), 
NodeName.nameFrom(p3), NodeName.nameFrom(p4), NodeName.nameFrom(p5), 
NodeName.nameFrom(p6), NodeName.nameFrom(p7), NodeName.nameFrom(p8));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath9.java
----------------------------------------------------------------------
diff --git 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath9.java
 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath9.java
index 986401a..804574b 100644
--- 
a/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath9.java
+++ 
b/curator-x-async/src/main/java/org/apache/curator/x/async/modeled/typed/TypedZPath9.java
@@ -18,11 +18,13 @@
  */
 package org.apache.curator.x.async.modeled.typed;
 
+import org.apache.curator.x.async.modeled.NodeName;
 import org.apache.curator.x.async.modeled.ZPath;
 
 /**
  * Same as {@link org.apache.curator.x.async.modeled.typed.TypedZPath}, but 
with 9 parameters
  */
+@FunctionalInterface
 public interface TypedZPath9<T1, T2, T3, T4, T5, T6, T7, T8, T9>
 {
     ZPath resolved(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 
p9);
@@ -46,6 +48,6 @@ public interface TypedZPath9<T1, T2, T3, T4, T5, T6, T7, T8, 
T9>
      */
     static <T1, T2, T3, T4, T5, T6, T7, T8, T9> TypedZPath9<T1, T2, T3, T4, 
T5, T6, T7, T8, T9> from(ZPath path)
     {
-        return path::resolved;
+        return (p1, p2, p3, p4, p5, p6, p7, p8, p9) -> 
path.resolved(NodeName.nameFrom(p1), NodeName.nameFrom(p2), 
NodeName.nameFrom(p3), NodeName.nameFrom(p4), NodeName.nameFrom(p5), 
NodeName.nameFrom(p6), NodeName.nameFrom(p7), NodeName.nameFrom(p8), 
NodeName.nameFrom(p9));
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/site/confluence/index.confluence
----------------------------------------------------------------------
diff --git a/curator-x-async/src/site/confluence/index.confluence 
b/curator-x-async/src/site/confluence/index.confluence
index 8788b76..576b5da 100644
--- a/curator-x-async/src/site/confluence/index.confluence
+++ b/curator-x-async/src/site/confluence/index.confluence
@@ -38,7 +38,7 @@ opposed to raw byte arrays. For example:
 
 {code}
 // let "client" be a CuratorFramework instance
-ModeledCuratorFramework<MyModel> modeled = 
ModeledCuratorFramework.wrap(client, path, serializer);
+ModeledFramework<MyModel> modeled = ModeledCuratorFramework.wrap(client, path, 
serializer);
 modeled.create(new MyModel());
 {code}
 

http://git-wip-us.apache.org/repos/asf/curator/blob/1fcb63a5/curator-x-async/src/site/confluence/modeled.confluence
----------------------------------------------------------------------
diff --git a/curator-x-async/src/site/confluence/modeled.confluence 
b/curator-x-async/src/site/confluence/modeled.confluence
index 3623728..8fcddf0 100644
--- a/curator-x-async/src/site/confluence/modeled.confluence
+++ b/curator-x-async/src/site/confluence/modeled.confluence
@@ -5,7 +5,7 @@ opposed to raw byte arrays. For example:
 
 {code}
 // let "client" be a CuratorFramework instance
-ModeledCuratorFramework<MyModel> modeled = 
ModeledCuratorFramework.wrap(client, path, serializer);
+ModeledFramework<MyModel> modeled = ModeledCuratorFramework.wrap(client, path, 
serializer);
 modeled.create(new MyModel());
 {code}
 
@@ -35,7 +35,7 @@ ZooKeeper paths.
 
 h4. Building
 
-You build a {{ModeledCuratorFramework}} instance using either the builder or 
helper wrapper. All
+You build a {{ModeledFramework}} instance using either the builder or helper 
wrapper. All
 options needed to use the ZPath are specified at build time:
 
 * whether and/or how to watch the ZNode
@@ -45,7 +45,7 @@ options needed to use the ZPath are specified at build time:
 * any ACLs
 * etc.
 
-These options are bound into the {{ModeledCuratorFramework}} instance and 
applied as needed.
+These options are bound into the {{ModeledFramework}} instance and applied as 
needed.
 
 h2. Example
 
@@ -75,7 +75,7 @@ public class Person {
 }
 {code}
 
-We can now build a {{ModeledCuratorFramework}} that manages {{Person}} 
instances at a given path:
+We can now build a {{ModeledFramework}} that manages {{Person}} instances at a 
given path:
 
 {code}
 // let "client" be a CuratorFramework instance

Reply via email to