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

[20/27] curator git commit: Initial implementation finished. Uses old transactions internal code for consistency. However, this makes the implementation a bit cumbersome. Old APIs are deprecated. In the future, this can all be cleaned up

Initial implementation finished. Uses old transactions internal code for consistency. However, this makes the implementation a bit cumbersome. Old APIs are deprecated. In the future, this can all be cleaned up


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

Branch: refs/heads/CURATOR-215
Commit: 7df5ab38d6055bfe6439e7337816ea00768a5401
Parents: d1e17eb
Author: randgalt <ra...@apache.org>
Authored: Sat May 9 14:57:28 2015 -0500
Committer: Scott Blum <dr...@apache.org>
Committed: Wed Aug 12 17:29:42 2015 -0400

----------------------------------------------------------------------
 .../curator/framework/CuratorFramework.java     |  10 +-
 .../curator/framework/api/CuratorEvent.java     |   7 +
 .../curator/framework/api/CuratorEventType.java |   5 +
 .../transaction/CuratorMultiTransaction.java    |   5 +-
 .../CuratorMultiTransactionMain.java            |   6 +-
 .../framework/api/transaction/CuratorOp.java    |  28 +++
 .../api/transaction/CuratorTransaction.java     |  11 +-
 .../transaction/CuratorTransactionResult.java   |  11 +-
 .../api/transaction/OperationType.java          |   8 +-
 .../transaction/TransactionCheckBuilder.java    |   6 +-
 .../transaction/TransactionCreateBuilder.java   |  10 +-
 .../transaction/TransactionDeleteBuilder.java   |   6 +-
 .../api/transaction/TransactionOp.java          |  30 +++
 .../transaction/TransactionSetDataBuilder.java  |   8 +-
 .../framework/api/transaction/TypeAndPath.java  |  41 ++++
 .../framework/imps/BackgroundSyncImpl.java      |   2 +-
 .../framework/imps/CreateBuilderImpl.java       |  19 +-
 .../framework/imps/CuratorEventImpl.java        |  35 ++-
 .../framework/imps/CuratorFrameworkImpl.java    |  24 +-
 .../imps/CuratorMultiTransactionImpl.java       |  51 ++++-
 .../imps/CuratorMultiTransactionRecord.java     |  17 +-
 .../framework/imps/CuratorTransactionImpl.java  | 149 +++++++------
 .../framework/imps/DeleteBuilderImpl.java       |  13 +-
 .../framework/imps/ExistsBuilderImpl.java       |   2 +-
 .../framework/imps/ExtractingCuratorOp.java     |  59 +++++
 .../framework/imps/GetACLBuilderImpl.java       |   2 +-
 .../framework/imps/GetChildrenBuilderImpl.java  |   2 +-
 .../framework/imps/GetConfigBuilderImpl.java    |   2 +-
 .../framework/imps/GetDataBuilderImpl.java      |   2 +-
 .../framework/imps/ReconfigBuilderImpl.java     |   2 +-
 .../framework/imps/SetACLBuilderImpl.java       |   2 +-
 .../framework/imps/SetDataBuilderImpl.java      |  23 +-
 .../curator/framework/imps/SyncBuilderImpl.java |   2 +-
 .../framework/imps/TransactionOpImpl.java       |  65 ++++++
 .../framework/imps/TestTransactions.java        | 139 ------------
 .../framework/imps/TestTransactionsNew.java     | 218 +++++++++++++++++++
 .../framework/imps/TestTransactionsOld.java     | 141 ++++++++++++
 37 files changed, 838 insertions(+), 325 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
index f14253f..1bc1535 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/CuratorFramework.java
@@ -23,9 +23,9 @@ import org.apache.curator.CuratorZookeeperClient;
 import org.apache.curator.framework.api.*;
 import org.apache.curator.framework.api.transaction.CuratorMultiTransaction;
 import org.apache.curator.framework.api.transaction.CuratorTransaction;
+import org.apache.curator.framework.api.transaction.TransactionOp;
 import org.apache.curator.framework.imps.CuratorFrameworkState;
 import org.apache.curator.framework.listen.Listenable;
-import org.apache.curator.framework.state.ConnectionState;
 import org.apache.curator.framework.state.ConnectionStateListener;
 import org.apache.curator.utils.EnsurePath;
 import org.apache.zookeeper.Watcher;
@@ -140,6 +140,7 @@ public interface CuratorFramework extends Closeable
      * Start a transaction builder
      *
      * @return builder object
+     * @deprecated use {@link #transaction()} instead
      */
     public CuratorTransaction inTransaction();
 
@@ -151,6 +152,13 @@ public interface CuratorFramework extends Closeable
     public CuratorMultiTransaction transaction();
 
     /**
+     * Allocate an operation that can be used with {@link #transaction()}
+     *
+     * @return operation builder
+     */
+    public TransactionOp transactionOp();
+
+    /**
      * Perform a sync on the given path - syncs are always in the background
      *
      * @param path                    the path

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEvent.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEvent.java b/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEvent.java
index 2a5408c..673613c 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEvent.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEvent.java
@@ -18,6 +18,8 @@
  */
 package org.apache.curator.framework.api;
 
+import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
+import org.apache.zookeeper.OpResult;
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.data.ACL;
 import org.apache.zookeeper.data.Stat;
@@ -80,6 +82,11 @@ public interface CuratorEvent
     public List<ACL> getACLList();
 
     /**
+     * @return any operation results or null
+     */
+    public List<CuratorTransactionResult> getOpResults();
+
+    /**
      * If {@link #getType()} returns {@link CuratorEventType#WATCHED} this will
      * return the WatchedEvent
      *

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java b/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java
index 50e9195..5a2dc56 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/CuratorEventType.java
@@ -69,6 +69,11 @@ public enum CuratorEventType
     SET_ACL,
 
     /**
+     * Corresponds to {@link CuratorFramework#transaction()}
+     */
+    TRANSACTION,
+
+    /**
      * Corresponds to {@link CuratorFramework#getConfig()}
      */
     GET_CONFIG,

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransaction.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransaction.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransaction.java
index 605ad2e..07bf191 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransaction.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransaction.java
@@ -20,7 +20,8 @@ package org.apache.curator.framework.api.transaction;
 
 import org.apache.curator.framework.api.Backgroundable;
 
-public interface CuratorMultiTransaction
-    extends Backgroundable<CuratorMultiTransactionMain>
+public interface CuratorMultiTransaction extends
+    Backgroundable<CuratorMultiTransactionMain>,
+    CuratorMultiTransactionMain
 {
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransactionMain.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransactionMain.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransactionMain.java
index 02c59af..6b4910d 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransactionMain.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorMultiTransactionMain.java
@@ -18,13 +18,11 @@
  */
 package org.apache.curator.framework.api.transaction;
 
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
 import java.util.List;
 
 public interface CuratorMultiTransactionMain
 {
-    List<OpResult> forOperations(Op... operations) throws Exception;
+    List<CuratorTransactionResult> forOperations(CuratorOp... operations) throws Exception;
 
-    List<OpResult> forOperations(List<Op> operations) throws Exception;
+    List<CuratorTransactionResult> forOperations(List<CuratorOp> operations) throws Exception;
 }

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

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransaction.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransaction.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransaction.java
index 3901abf..4f2fb02 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransaction.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransaction.java
@@ -18,6 +18,7 @@
  */
 package org.apache.curator.framework.api.transaction;
 
+import org.apache.curator.framework.CuratorFramework;
 import org.apache.zookeeper.ZooKeeper;
 
 /**
@@ -49,6 +50,8 @@ import org.apache.zookeeper.ZooKeeper;
  *     <b>Important:</b> the operations are not submitted until
  *     {@link CuratorTransactionFinal#commit()} is called.
  * </p>
+ *
+ * @deprecated Use {@link CuratorFramework#transaction()}
  */
 public interface CuratorTransaction
 {
@@ -57,26 +60,26 @@ public interface CuratorTransaction
      *
      * @return builder object
      */
-    public TransactionCreateBuilder create();
+    public TransactionCreateBuilder<CuratorTransactionBridge> create();
 
     /**
      * Start a delete builder in the transaction
      *
      * @return builder object
      */
-    public TransactionDeleteBuilder delete();
+    public TransactionDeleteBuilder<CuratorTransactionBridge> delete();
 
     /**
      * Start a setData builder in the transaction
      *
      * @return builder object
      */
-    public TransactionSetDataBuilder setData();
+    public TransactionSetDataBuilder<CuratorTransactionBridge> setData();
 
     /**
      * Start a check builder in the transaction
      *ChildData
      * @return builder object
      */
-    public TransactionCheckBuilder check();
+    public TransactionCheckBuilder<CuratorTransactionBridge> check();
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransactionResult.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransactionResult.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransactionResult.java
index 03bbca2..8d8dc2d 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransactionResult.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/CuratorTransactionResult.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.api.transaction;
 
 import com.google.common.base.Predicate;
@@ -27,9 +28,9 @@ import org.apache.zookeeper.data.Stat;
 public class CuratorTransactionResult
 {
     private final OperationType type;
-    private final String        forPath;
-    private final String        resultPath;
-    private final Stat          resultStat;
+    private final String forPath;
+    private final String resultPath;
+    private final Stat resultStat;
 
     /**
      * Utility that can be passed to Google Guava to find a particular result. E.g.
@@ -41,7 +42,7 @@ public class CuratorTransactionResult
      * @param forPath path
      * @return predicate
      */
-    public static Predicate<CuratorTransactionResult>       ofTypeAndPath(final OperationType type, final String forPath)
+    public static Predicate<CuratorTransactionResult> ofTypeAndPath(final OperationType type, final String forPath)
     {
         return new Predicate<CuratorTransactionResult>()
         {
@@ -73,7 +74,7 @@ public class CuratorTransactionResult
 
     /**
      * Returns the path that was passed to the operation when added
-     * 
+     *
      * @return operation input path
      */
     public String getForPath()

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/OperationType.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/OperationType.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/OperationType.java
index 56dcd33..c0aec68 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/OperationType.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/OperationType.java
@@ -24,22 +24,22 @@ package org.apache.curator.framework.api.transaction;
 public enum OperationType
 {
     /**
-     * {@link CuratorTransaction#create()}
+     * {@link TransactionOp#create()}
      */
     CREATE,
 
     /**
-     * {@link CuratorTransaction#delete()}
+     * {@link TransactionOp#delete()}
      */
     DELETE,
 
     /**
-     * {@link CuratorTransaction#setData()}
+     * {@link TransactionOp#setData()}
      */
     SET_DATA,
 
     /**
-     * {@link CuratorTransaction#check()}
+     * {@link TransactionOp#check()}
      */
     CHECK
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCheckBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCheckBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCheckBuilder.java
index 2bc13d1..6de675c 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCheckBuilder.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCheckBuilder.java
@@ -21,8 +21,8 @@ package org.apache.curator.framework.api.transaction;
 import org.apache.curator.framework.api.Pathable;
 import org.apache.curator.framework.api.Versionable;
 
-public interface TransactionCheckBuilder extends
-    Pathable<CuratorTransactionBridge>,
-    Versionable<Pathable<CuratorTransactionBridge>>
+public interface TransactionCheckBuilder<T> extends
+    Pathable<T>,
+    Versionable<Pathable<T>>
 {
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCreateBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCreateBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCreateBuilder.java
index 6ac3069..cba0cba 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCreateBuilder.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionCreateBuilder.java
@@ -23,10 +23,10 @@ import org.apache.curator.framework.api.Compressible;
 import org.apache.curator.framework.api.CreateModable;
 import org.apache.curator.framework.api.PathAndBytesable;
 
-public interface TransactionCreateBuilder extends
-    PathAndBytesable<CuratorTransactionBridge>,
-    CreateModable<ACLPathAndBytesable<CuratorTransactionBridge>>,
-    ACLPathAndBytesable<CuratorTransactionBridge>,
-    Compressible<ACLPathAndBytesable<CuratorTransactionBridge>>
+public interface TransactionCreateBuilder<T> extends
+    PathAndBytesable<T>,
+    CreateModable<ACLPathAndBytesable<T>>,
+    ACLPathAndBytesable<T>,
+    Compressible<ACLPathAndBytesable<T>>
 {
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionDeleteBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionDeleteBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionDeleteBuilder.java
index e165394..d977290 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionDeleteBuilder.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionDeleteBuilder.java
@@ -21,8 +21,8 @@ package org.apache.curator.framework.api.transaction;
 import org.apache.curator.framework.api.Pathable;
 import org.apache.curator.framework.api.Versionable;
 
-public interface TransactionDeleteBuilder extends
-    Pathable<CuratorTransactionBridge>,
-    Versionable<Pathable<CuratorTransactionBridge>>
+public interface TransactionDeleteBuilder<T> extends
+    Pathable<T>,
+    Versionable<Pathable<T>>
 {
 }

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

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionSetDataBuilder.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionSetDataBuilder.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionSetDataBuilder.java
index 777537a..2d4d255 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionSetDataBuilder.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TransactionSetDataBuilder.java
@@ -22,9 +22,9 @@ import org.apache.curator.framework.api.Compressible;
 import org.apache.curator.framework.api.PathAndBytesable;
 import org.apache.curator.framework.api.Versionable;
 
-public interface TransactionSetDataBuilder extends
-    PathAndBytesable<CuratorTransactionBridge>,
-    Versionable<PathAndBytesable<CuratorTransactionBridge>>,
-    Compressible<PathAndBytesable<CuratorTransactionBridge>>
+public interface TransactionSetDataBuilder<T> extends
+    PathAndBytesable<T>,
+    Versionable<PathAndBytesable<T>>,
+    Compressible<PathAndBytesable<T>>
 {
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TypeAndPath.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TypeAndPath.java b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TypeAndPath.java
new file mode 100644
index 0000000..b1cea95
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/api/transaction/TypeAndPath.java
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.curator.framework.api.transaction;
+
+public class TypeAndPath
+{
+    private final OperationType type;
+    private final String forPath;
+
+    public TypeAndPath(OperationType type, String forPath)
+    {
+        this.type = type;
+        this.forPath = forPath;
+    }
+
+    public OperationType getType()
+    {
+        return type;
+    }
+
+    public String getForPath()
+    {
+        return forPath;
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/BackgroundSyncImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/BackgroundSyncImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/BackgroundSyncImpl.java
index af8e458..f0994e3 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/BackgroundSyncImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/BackgroundSyncImpl.java
@@ -46,7 +46,7 @@ class BackgroundSyncImpl implements BackgroundOperation<String>
                 public void processResult(int rc, String path, Object ctx)
                 {
                     trace.commit();
-                    CuratorEventImpl event = new CuratorEventImpl(client, CuratorEventType.SYNC, rc, path, null, ctx, null, null, null, null, null);
+                    CuratorEventImpl event = new CuratorEventImpl(client, CuratorEventType.SYNC, rc, path, null, ctx, null, null, null, null, null, null);
                     client.processBackgroundOperation(operationAndData, event);
                 }
             },

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
index 6eef4d4..5432190 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/CreateBuilderImpl.java
@@ -26,7 +26,6 @@ import org.apache.curator.RetryLoop;
 import org.apache.curator.TimeTrace;
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.api.*;
-import org.apache.curator.framework.api.transaction.CuratorTransactionBridge;
 import org.apache.curator.framework.api.transaction.OperationType;
 import org.apache.curator.framework.api.transaction.TransactionCreateBuilder;
 import org.apache.curator.utils.ZKPaths;
@@ -70,39 +69,39 @@ class CreateBuilderImpl implements CreateBuilder, BackgroundOperation<PathAndByt
         protectedId = null;
     }
 
-    TransactionCreateBuilder asTransactionCreateBuilder(final CuratorTransactionImpl curatorTransaction, final CuratorMultiTransactionRecord transaction)
+    <T> TransactionCreateBuilder<T> asTransactionCreateBuilder(final T context, final CuratorMultiTransactionRecord transaction)
     {
-        return new TransactionCreateBuilder()
+        return new TransactionCreateBuilder<T>()
         {
             @Override
-            public PathAndBytesable<CuratorTransactionBridge> withACL(List<ACL> aclList)
+            public PathAndBytesable<T> withACL(List<ACL> aclList)
             {
                 CreateBuilderImpl.this.withACL(aclList);
                 return this;
             }
 
             @Override
-            public ACLPathAndBytesable<CuratorTransactionBridge> withMode(CreateMode mode)
+            public ACLPathAndBytesable<T> withMode(CreateMode mode)
             {
                 CreateBuilderImpl.this.withMode(mode);
                 return this;
             }
             
             @Override
-            public ACLPathAndBytesable<CuratorTransactionBridge> compressed()
+            public ACLPathAndBytesable<T> compressed()
             {
                 CreateBuilderImpl.this.compressed();
                 return this;
             }
             
             @Override
-            public CuratorTransactionBridge forPath(String path) throws Exception
+            public T forPath(String path) throws Exception
             {
                 return forPath(path, client.getDefaultData());
             }
 
             @Override
-            public CuratorTransactionBridge forPath(String path, byte[] data) throws Exception
+            public T forPath(String path, byte[] data) throws Exception
             {               
                 if ( compress )
                 {
@@ -111,7 +110,7 @@ class CreateBuilderImpl implements CreateBuilder, BackgroundOperation<PathAndByt
                 
                 String fixedPath = client.fixForNamespace(path);
                 transaction.add(Op.create(fixedPath, data, acling.getAclList(path), createMode), OperationType.CREATE, path);
-                return curatorTransaction;
+                return context;
             }
         };
     }
@@ -537,7 +536,7 @@ class CreateBuilderImpl implements CreateBuilder, BackgroundOperation<PathAndByt
         path = client.unfixForNamespace(path);
         name = client.unfixForNamespace(name);
 
-        CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.CREATE, rc, path, name, ctx, null, null, null, null, null);
+        CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.CREATE, rc, path, name, ctx, null, null, null, null, null, null);
         client.processBackgroundOperation(operationAndData, event);
     }
 

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorEventImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorEventImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorEventImpl.java
index 929fe6d..4aa125f 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorEventImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorEventImpl.java
@@ -16,11 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.imps;
 
 import com.google.common.collect.ImmutableList;
 import org.apache.curator.framework.api.CuratorEvent;
 import org.apache.curator.framework.api.CuratorEventType;
+import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.data.ACL;
 import org.apache.zookeeper.data.Stat;
@@ -29,16 +31,17 @@ import java.util.List;
 
 class CuratorEventImpl implements CuratorEvent
 {
-    private final CuratorEventType  type;
-    private final int               resultCode;
-    private final String            path;
-    private final String            name;
-    private final List<String>      children;
-    private final Object            context;
-    private final Stat              stat;
-    private final byte[]            data;
-    private final WatchedEvent      watchedEvent;
-    private final List<ACL>         aclList;
+    private final CuratorEventType type;
+    private final int resultCode;
+    private final String path;
+    private final String name;
+    private final List<String> children;
+    private final Object context;
+    private final Stat stat;
+    private final byte[] data;
+    private final WatchedEvent watchedEvent;
+    private final List<ACL> aclList;
+    private final List<CuratorTransactionResult> opResults;
 
     @Override
     public CuratorEventType getType()
@@ -101,6 +104,12 @@ class CuratorEventImpl implements CuratorEvent
     }
 
     @Override
+    public List<CuratorTransactionResult> getOpResults()
+    {
+        return opResults;
+    }
+
+    @Override
     public String toString()
     {
         return "CuratorEventImpl{" +
@@ -114,20 +123,22 @@ class CuratorEventImpl implements CuratorEvent
             ", data=" + Arrays.toString(data) +
             ", watchedEvent=" + watchedEvent +
             ", aclList=" + aclList +
+            ", opResults=" + opResults +
             '}';
     }
 
-    CuratorEventImpl(CuratorFrameworkImpl client, CuratorEventType type, int resultCode, String path, String name, Object context, Stat stat, byte[] data, List<String> children, WatchedEvent watchedEvent, List<ACL> aclList)
+    CuratorEventImpl(CuratorFrameworkImpl client, CuratorEventType type, int resultCode, String path, String name, Object context, Stat stat, byte[] data, List<String> children, WatchedEvent watchedEvent, List<ACL> aclList, List<CuratorTransactionResult> opResults)
     {
         this.type = type;
         this.resultCode = resultCode;
+        this.opResults = (opResults != null) ? ImmutableList.copyOf(opResults) : null;
         this.path = client.unfixForNamespace(path);
         this.name = name;
         this.context = context;
         this.stat = stat;
         this.data = data;
         this.children = children;
-        this.watchedEvent = (watchedEvent != null) ? new NamespaceWatchedEvent(client, watchedEvent) : watchedEvent;
+        this.watchedEvent = (watchedEvent != null) ? new NamespaceWatchedEvent(client, watchedEvent) : null;
         this.aclList = (aclList != null) ? ImmutableList.copyOf(aclList) : null;
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
index 9b96f60..b41d995 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorFrameworkImpl.java
@@ -31,7 +31,9 @@ import org.apache.curator.framework.AuthInfo;
 import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.CuratorFrameworkFactory;
 import org.apache.curator.framework.api.*;
+import org.apache.curator.framework.api.transaction.CuratorMultiTransaction;
 import org.apache.curator.framework.api.transaction.CuratorTransaction;
+import org.apache.curator.framework.api.transaction.TransactionOp;
 import org.apache.curator.framework.listen.Listenable;
 import org.apache.curator.framework.listen.ListenerContainer;
 import org.apache.curator.framework.state.ConnectionState;
@@ -102,7 +104,7 @@ public class CuratorFrameworkImpl implements CuratorFramework
             @Override
             public void process(WatchedEvent watchedEvent)
             {
-                CuratorEvent event = new CuratorEventImpl(CuratorFrameworkImpl.this, CuratorEventType.WATCHED, watchedEvent.getState().getIntValue(), unfixForNamespace(watchedEvent.getPath()), null, null, null, null, null, watchedEvent, null);
+                CuratorEvent event = new CuratorEventImpl(CuratorFrameworkImpl.this, CuratorEventType.WATCHED, watchedEvent.getState().getIntValue(), unfixForNamespace(watchedEvent.getPath()), null, null, null, null, null, watchedEvent, null, null);
                 processEvent(event);
             }
         }, builder.getRetryPolicy(), builder.canBeReadOnly());
@@ -276,7 +278,7 @@ public class CuratorFrameworkImpl implements CuratorFramework
                 @Override
                 public Void apply(CuratorListener listener)
                 {
-                    CuratorEvent event = new CuratorEventImpl(CuratorFrameworkImpl.this, CuratorEventType.CLOSING, 0, null, null, null, null, null, null, null, null);
+                    CuratorEvent event = new CuratorEventImpl(CuratorFrameworkImpl.this, CuratorEventType.CLOSING, 0, null, null, null, null, null, null, null, null, null);
                     try
                     {
                         listener.eventReceived(CuratorFrameworkImpl.this, event);
@@ -418,6 +420,22 @@ public class CuratorFrameworkImpl implements CuratorFramework
     }
 
     @Override
+    public CuratorMultiTransaction transaction()
+    {
+        Preconditions.checkState(getState() == CuratorFrameworkState.STARTED, "instance must be started before calling this method");
+
+        return new CuratorMultiTransactionImpl(this);
+    }
+
+    @Override
+    public TransactionOp transactionOp()
+    {
+        Preconditions.checkState(getState() == CuratorFrameworkState.STARTED, "instance must be started before calling this method");
+
+        return new TransactionOpImpl(this);
+    }
+
+    @Override
     public Listenable<ConnectionStateListener> getConnectionStateListenable()
     {
         return connectionStateManager.getListenable();
@@ -834,7 +852,7 @@ public class CuratorFrameworkImpl implements CuratorFramework
             if ( e instanceof CuratorConnectionLossException )
             {
                 WatchedEvent watchedEvent = new WatchedEvent(Watcher.Event.EventType.None, Watcher.Event.KeeperState.Disconnected, null);
-                CuratorEvent event = new CuratorEventImpl(this, CuratorEventType.WATCHED, KeeperException.Code.CONNECTIONLOSS.intValue(), null, null, operationAndData.getContext(), null, null, null, watchedEvent, null);
+                CuratorEvent event = new CuratorEventImpl(this, CuratorEventType.WATCHED, KeeperException.Code.CONNECTIONLOSS.intValue(), null, null, operationAndData.getContext(), null, null, null, watchedEvent, null, null);
                 if ( checkBackgroundRetry(operationAndData, event) )
                 {
                     queueOperation(operationAndData);

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionImpl.java
index 0ba3dc7..6881fc2 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionImpl.java
@@ -16,26 +16,35 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.imps;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import org.apache.curator.RetryLoop;
 import org.apache.curator.TimeTrace;
+import org.apache.curator.framework.CuratorFramework;
 import org.apache.curator.framework.api.BackgroundCallback;
+import org.apache.curator.framework.api.CuratorEvent;
+import org.apache.curator.framework.api.CuratorEventType;
 import org.apache.curator.framework.api.transaction.CuratorMultiTransaction;
 import org.apache.curator.framework.api.transaction.CuratorMultiTransactionMain;
-import org.apache.zookeeper.Op;
+import org.apache.curator.framework.api.transaction.CuratorOp;
+import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
+import org.apache.zookeeper.AsyncCallback;
 import org.apache.zookeeper.OpResult;
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executor;
 
+/**
+ * @deprecated Use {@link CuratorFramework#transaction()}
+ */
 public class CuratorMultiTransactionImpl implements
     CuratorMultiTransaction,
     CuratorMultiTransactionMain,
-    BackgroundOperation<Void>
+    BackgroundOperation<CuratorMultiTransactionRecord>
 {
     private final CuratorFrameworkImpl client;
     private Backgrounding backgrounding = new Backgrounding();
@@ -88,36 +97,54 @@ public class CuratorMultiTransactionImpl implements
     }
 
     @Override
-    public List<OpResult> forOperations(Op... operations) throws Exception
+    public List<CuratorTransactionResult> forOperations(CuratorOp... operations) throws Exception
     {
-        List<Op> ops = (operations != null) ? Arrays.asList(operations) : Lists.<Op>newArrayList();
+        List<CuratorOp> ops = (operations != null) ? Arrays.asList(operations) : Lists.<CuratorOp>newArrayList();
         return forOperations(ops);
     }
 
     @Override
-    public List<OpResult> forOperations(List<Op> operations) throws Exception
+    public List<CuratorTransactionResult> forOperations(List<CuratorOp> operations) throws Exception
     {
         operations = Preconditions.checkNotNull(operations, "operations cannot be null");
         Preconditions.checkArgument(!operations.isEmpty(), "operations list cannot be empty");
 
+        CuratorMultiTransactionRecord record = new CuratorMultiTransactionRecord();
+        for ( CuratorOp curatorOp : operations )
+        {
+            record.add(curatorOp.get(), curatorOp.getTypeAndPath().getType(), curatorOp.getTypeAndPath().getForPath());
+        }
+
         if ( backgrounding.inBackground() )
         {
-            client.processBackgroundOperation(new OperationAndData<>(this, null, backgrounding.getCallback(), null, backgrounding.getContext()), null);
+            client.processBackgroundOperation(new OperationAndData<>(this, record, backgrounding.getCallback(), null, backgrounding.getContext()), null);
             return null;
         }
         else
         {
-            return forOperationsInForeground(operations);
+            return forOperationsInForeground(record);
         }
     }
 
     @Override
-    public void performBackgroundOperation(OperationAndData<Void> data) throws Exception
+    public void performBackgroundOperation(final OperationAndData<CuratorMultiTransactionRecord> operationAndData) throws Exception
     {
-
+        final TimeTrace trace = client.getZookeeperClient().startTracer("CuratorMultiTransactionImpl-Background");
+        AsyncCallback.MultiCallback callback = new AsyncCallback.MultiCallback()
+        {
+            @Override
+            public void processResult(int rc, String path, Object ctx, List<OpResult> opResults)
+            {
+                trace.commit();
+                List<CuratorTransactionResult> curatorResults = (opResults != null) ? CuratorTransactionImpl.wrapResults(client, opResults, operationAndData.getData()) : null;
+                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.TRANSACTION, rc, path, null, ctx, null, null, null, null, null, curatorResults);
+                client.processBackgroundOperation(operationAndData, event);
+            }
+        };
+        client.getZooKeeper().multi(operationAndData.getData(), callback, backgrounding.getContext());
     }
 
-    private List<OpResult> forOperationsInForeground(final List<Op> operations) throws Exception
+    private List<CuratorTransactionResult> forOperationsInForeground(final CuratorMultiTransactionRecord record) throws Exception
     {
         TimeTrace trace = client.getZookeeperClient().startTracer("CuratorMultiTransactionImpl-Foreground");
         List<OpResult> responseData = RetryLoop.callWithRetry
@@ -128,12 +155,12 @@ public class CuratorMultiTransactionImpl implements
                 @Override
                 public List<OpResult> call() throws Exception
                 {
-                    return client.getZooKeeper().multi(operations);
+                    return client.getZooKeeper().multi(record);
                 }
             }
         );
         trace.commit();
 
-        return responseData;
+        return CuratorTransactionImpl.wrapResults(client, responseData, record);
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java
index 1500d6d..0611df6 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorMultiTransactionRecord.java
@@ -20,6 +20,7 @@ package org.apache.curator.framework.imps;
 
 import com.google.common.collect.Lists;
 import org.apache.curator.framework.api.transaction.OperationType;
+import org.apache.curator.framework.api.transaction.TypeAndPath;
 import org.apache.zookeeper.MultiTransactionRecord;
 import org.apache.zookeeper.Op;
 import java.util.List;
@@ -28,30 +29,18 @@ class CuratorMultiTransactionRecord extends MultiTransactionRecord
 {
     private final List<TypeAndPath>     metadata = Lists.newArrayList();
 
-    static class TypeAndPath
-    {
-        final OperationType type;
-        final String forPath;
-
-        TypeAndPath(OperationType type, String forPath)
-        {
-            this.type = type;
-            this.forPath = forPath;
-        }
-    }
-
     @Override
     public final void add(Op op)
     {
         throw new UnsupportedOperationException();
     }
-    
+
     void add(Op op, OperationType type, String forPath)
     {
         super.add(op);
         metadata.add(new TypeAndPath(type, forPath));
     }
-    
+
     TypeAndPath     getMetadata(int index)
     {
         return metadata.get(index);

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorTransactionImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorTransactionImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorTransactionImpl.java
index 13ffe82..20ec274 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorTransactionImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/CuratorTransactionImpl.java
@@ -16,21 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.curator.framework.imps;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import org.apache.curator.RetryLoop;
 import org.apache.curator.framework.api.Pathable;
-import org.apache.curator.framework.api.transaction.CuratorTransaction;
-import org.apache.curator.framework.api.transaction.CuratorTransactionBridge;
-import org.apache.curator.framework.api.transaction.CuratorTransactionFinal;
-import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
-import org.apache.curator.framework.api.transaction.OperationType;
-import org.apache.curator.framework.api.transaction.TransactionCheckBuilder;
-import org.apache.curator.framework.api.transaction.TransactionCreateBuilder;
-import org.apache.curator.framework.api.transaction.TransactionDeleteBuilder;
-import org.apache.curator.framework.api.transaction.TransactionSetDataBuilder;
+import org.apache.curator.framework.api.transaction.*;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.Op;
 import org.apache.zookeeper.OpResult;
@@ -43,10 +36,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 class CuratorTransactionImpl implements CuratorTransaction, CuratorTransactionBridge, CuratorTransactionFinal
 {
-    private final CuratorFrameworkImpl              client;
-    private final CuratorMultiTransactionRecord     transaction;
+    private final CuratorFrameworkImpl client;
+    private final CuratorMultiTransactionRecord transaction;
 
-    private boolean         isCommitted = false;
+    private boolean isCommitted = false;
 
     CuratorTransactionImpl(CuratorFrameworkImpl client)
     {
@@ -61,49 +54,58 @@ class CuratorTransactionImpl implements CuratorTransaction, CuratorTransactionBr
     }
 
     @Override
-    public TransactionCreateBuilder create()
+    public TransactionCreateBuilder<CuratorTransactionBridge> create()
     {
         Preconditions.checkState(!isCommitted, "transaction already committed");
 
-        return new CreateBuilderImpl(client).asTransactionCreateBuilder(this, transaction);
+        CuratorTransactionBridge asBridge = this;
+        return new CreateBuilderImpl(client).asTransactionCreateBuilder(asBridge, transaction);
     }
 
     @Override
-    public TransactionDeleteBuilder delete()
+    public TransactionDeleteBuilder<CuratorTransactionBridge> delete()
     {
         Preconditions.checkState(!isCommitted, "transaction already committed");
 
-        return new DeleteBuilderImpl(client).asTransactionDeleteBuilder(this, transaction);
+        CuratorTransactionBridge asBridge = this;
+        return new DeleteBuilderImpl(client).asTransactionDeleteBuilder(asBridge, transaction);
     }
 
     @Override
-    public TransactionSetDataBuilder setData()
+    public TransactionSetDataBuilder<CuratorTransactionBridge> setData()
     {
         Preconditions.checkState(!isCommitted, "transaction already committed");
 
-        return new SetDataBuilderImpl(client).asTransactionSetDataBuilder(this, transaction);
+        CuratorTransactionBridge asBridge = this;
+        return new SetDataBuilderImpl(client).asTransactionSetDataBuilder(asBridge, transaction);
     }
 
     @Override
-    public TransactionCheckBuilder check()
+    public TransactionCheckBuilder<CuratorTransactionBridge> check()
     {
         Preconditions.checkState(!isCommitted, "transaction already committed");
 
-        return new TransactionCheckBuilder()
+        CuratorTransactionBridge asBridge = this;
+        return makeTransactionCheckBuilder(client, asBridge, transaction);
+    }
+
+    static <T> TransactionCheckBuilder<T> makeTransactionCheckBuilder(final CuratorFrameworkImpl client, final T context, final CuratorMultiTransactionRecord transaction)
+    {
+        return new TransactionCheckBuilder<T>()
         {
-            private int         version = -1;
+            private int version = -1;
 
             @Override
-            public CuratorTransactionBridge forPath(String path) throws Exception
+            public T forPath(String path) throws Exception
             {
-                String      fixedPath = client.fixForNamespace(path);
+                String fixedPath = client.fixForNamespace(path);
                 transaction.add(Op.check(fixedPath, version), OperationType.CHECK, path);
 
-                return CuratorTransactionImpl.this;
+                return context;
             }
 
             @Override
-            public Pathable<CuratorTransactionBridge> withVersion(int version)
+            public Pathable<T> withVersion(int version)
             {
                 this.version = version;
                 return this;
@@ -118,65 +120,44 @@ class CuratorTransactionImpl implements CuratorTransaction, CuratorTransactionBr
         isCommitted = true;
 
         final AtomicBoolean firstTime = new AtomicBoolean(true);
-        List<OpResult>      resultList = RetryLoop.callWithRetry
-        (
-            client.getZookeeperClient(),
-            new Callable<List<OpResult>>()
-            {
-                @Override
-                public List<OpResult> call() throws Exception
+        List<OpResult> resultList = RetryLoop.callWithRetry
+            (
+                client.getZookeeperClient(),
+                new Callable<List<OpResult>>()
                 {
-                    return doOperation(firstTime);
+                    @Override
+                    public List<OpResult> call() throws Exception
+                    {
+                        return doOperation(firstTime);
+                    }
                 }
-            }
-        );
-        
+            );
+
         if ( resultList.size() != transaction.metadataSize() )
         {
             throw new IllegalStateException(String.format("Result size (%d) doesn't match input size (%d)", resultList.size(), transaction.metadataSize()));
         }
 
-        ImmutableList.Builder<CuratorTransactionResult>     builder = ImmutableList.builder();
-        for ( int i = 0; i < resultList.size(); ++i )
-        {
-            OpResult                                    opResult = resultList.get(i);
-            CuratorMultiTransactionRecord.TypeAndPath   metadata = transaction.getMetadata(i);
-            CuratorTransactionResult                    curatorResult = makeCuratorResult(opResult, metadata);
-            builder.add(curatorResult);
-        }
-
-        return builder.build();
+        return wrapResults(client, resultList, transaction);
     }
 
-    private List<OpResult> doOperation(AtomicBoolean firstTime) throws Exception
+    static List<CuratorTransactionResult> wrapResults(CuratorFrameworkImpl client, List<OpResult> resultList, CuratorMultiTransactionRecord transaction)
     {
-        boolean         localFirstTime = firstTime.getAndSet(false);
-        if ( !localFirstTime )
+        ImmutableList.Builder<CuratorTransactionResult> builder = ImmutableList.builder();
+        for ( int i = 0; i < resultList.size(); ++i )
         {
-
+            OpResult opResult = resultList.get(i);
+            TypeAndPath metadata = transaction.getMetadata(i);
+            CuratorTransactionResult curatorResult = makeCuratorResult(client, opResult, metadata);
+            builder.add(curatorResult);
         }
 
-        List<OpResult>  opResults = client.getZooKeeper().multi(transaction);
-        if ( opResults.size() > 0 )
-        {
-            OpResult        firstResult = opResults.get(0);
-            if ( firstResult.getType() == ZooDefs.OpCode.error )
-            {
-                OpResult.ErrorResult        error = (OpResult.ErrorResult)firstResult;
-                KeeperException.Code        code = KeeperException.Code.get(error.getErr());
-                if ( code == null )
-                {
-                    code = KeeperException.Code.UNIMPLEMENTED;
-                }
-                throw KeeperException.create(code);
-            }
-        }
-        return opResults;
+        return builder.build();
     }
 
-    private CuratorTransactionResult makeCuratorResult(OpResult opResult, CuratorMultiTransactionRecord.TypeAndPath metadata)
+    static CuratorTransactionResult makeCuratorResult(CuratorFrameworkImpl client, OpResult opResult, TypeAndPath metadata)
     {
-        String                                      resultPath = null;
+        String resultPath = null;
         Stat resultStat = null;
         switch ( opResult.getType() )
         {
@@ -188,19 +169,45 @@ class CuratorTransactionImpl implements CuratorTransaction, CuratorTransactionBr
 
             case ZooDefs.OpCode.create:
             {
-                OpResult.CreateResult       createResult = (OpResult.CreateResult)opResult;
+                OpResult.CreateResult createResult = (OpResult.CreateResult)opResult;
                 resultPath = client.unfixForNamespace(createResult.getPath());
                 break;
             }
 
             case ZooDefs.OpCode.setData:
             {
-                OpResult.SetDataResult      setDataResult = (OpResult.SetDataResult)opResult;
+                OpResult.SetDataResult setDataResult = (OpResult.SetDataResult)opResult;
                 resultStat = setDataResult.getStat();
                 break;
             }
         }
 
-        return new CuratorTransactionResult(metadata.type, metadata.forPath, resultPath, resultStat);
+        return new CuratorTransactionResult(metadata.getType(), metadata.getForPath(), resultPath, resultStat);
+    }
+
+    private List<OpResult> doOperation(AtomicBoolean firstTime) throws Exception
+    {
+        boolean localFirstTime = firstTime.getAndSet(false);
+        if ( !localFirstTime )
+        {
+            // TODO
+        }
+
+        List<OpResult> opResults = client.getZooKeeper().multi(transaction);
+        if ( opResults.size() > 0 )
+        {
+            OpResult firstResult = opResults.get(0);
+            if ( firstResult.getType() == ZooDefs.OpCode.error )
+            {
+                OpResult.ErrorResult error = (OpResult.ErrorResult)firstResult;
+                KeeperException.Code code = KeeperException.Code.get(error.getErr());
+                if ( code == null )
+                {
+                    code = KeeperException.Code.UNIMPLEMENTED;
+                }
+                throw KeeperException.create(code);
+            }
+        }
+        return opResults;
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/DeleteBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/DeleteBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/DeleteBuilderImpl.java
index 9db0013..51641b8 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/DeleteBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/DeleteBuilderImpl.java
@@ -28,7 +28,6 @@ import org.apache.curator.framework.api.CuratorEvent;
 import org.apache.curator.framework.api.CuratorEventType;
 import org.apache.curator.framework.api.DeleteBuilder;
 import org.apache.curator.framework.api.Pathable;
-import org.apache.curator.framework.api.transaction.CuratorTransactionBridge;
 import org.apache.curator.framework.api.transaction.OperationType;
 import org.apache.curator.framework.api.transaction.TransactionDeleteBuilder;
 import org.apache.curator.utils.ZKPaths;
@@ -55,20 +54,20 @@ class DeleteBuilderImpl implements DeleteBuilder, BackgroundOperation<String>
         guaranteed = false;
     }
 
-    TransactionDeleteBuilder asTransactionDeleteBuilder(final CuratorTransactionImpl curatorTransaction, final CuratorMultiTransactionRecord transaction)
+    <T> TransactionDeleteBuilder<T> asTransactionDeleteBuilder(final T context, final CuratorMultiTransactionRecord transaction)
     {
-        return new TransactionDeleteBuilder()
+        return new TransactionDeleteBuilder<T>()
         {
             @Override
-            public CuratorTransactionBridge forPath(String path) throws Exception
+            public T forPath(String path) throws Exception
             {
                 String fixedPath = client.fixForNamespace(path);
                 transaction.add(Op.delete(fixedPath, version), OperationType.DELETE, path);
-                return curatorTransaction;
+                return context;
             }
 
             @Override
-            public Pathable<CuratorTransactionBridge> withVersion(int version)
+            public Pathable<T> withVersion(int version)
             {
                 DeleteBuilderImpl.this.withVersion(version);
                 return this;
@@ -159,7 +158,7 @@ class DeleteBuilderImpl implements DeleteBuilder, BackgroundOperation<String>
                         }
                         else
                         {
-                            CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.DELETE, rc, path, null, ctx, null, null, null, null, null);
+                            CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.DELETE, rc, path, null, ctx, null, null, null, null, null, null);
                             client.processBackgroundOperation(operationAndData, event);
                         }
                     }

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/ExistsBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/ExistsBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/ExistsBuilderImpl.java
index a1e2ee5..4681245 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/ExistsBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/ExistsBuilderImpl.java
@@ -119,7 +119,7 @@ class ExistsBuilderImpl implements ExistsBuilder, BackgroundOperation<String>
             public void processResult(int rc, String path, Object ctx, Stat stat)
             {
                 trace.commit();
-                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.EXISTS, rc, path, null, ctx, stat, null, null, null, null);
+                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.EXISTS, rc, path, null, ctx, stat, null, null, null, null, null);
                 client.processBackgroundOperation(operationAndData, event);
             }
         };

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/ExtractingCuratorOp.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/ExtractingCuratorOp.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/ExtractingCuratorOp.java
new file mode 100644
index 0000000..40bd8c8
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/ExtractingCuratorOp.java
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.curator.framework.imps;
+
+import com.google.common.base.Preconditions;
+import org.apache.curator.framework.api.transaction.CuratorOp;
+import org.apache.curator.framework.api.transaction.TypeAndPath;
+import org.apache.zookeeper.Op;
+
+class ExtractingCuratorOp implements CuratorOp
+{
+    private final CuratorMultiTransactionRecord record = new CuratorMultiTransactionRecord();
+
+    CuratorMultiTransactionRecord getRecord()
+    {
+        return record;
+    }
+
+    CuratorOp asCuratorOp()
+    {
+        return this;
+    }
+
+    @Override
+    public TypeAndPath getTypeAndPath()
+    {
+        validate();
+        return record.getMetadata(0);
+    }
+
+    @Override
+    public Op get()
+    {
+        validate();
+        return record.iterator().next();
+    }
+
+    private void validate()
+    {
+        Preconditions.checkArgument(record.size() > 0, "No operation has been added");
+        Preconditions.checkArgument(record.size() == 1, "Multiple operations added");
+    }
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/GetACLBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetACLBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetACLBuilderImpl.java
index 250c2c8..f65c933 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetACLBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetACLBuilderImpl.java
@@ -104,7 +104,7 @@ class GetACLBuilderImpl implements GetACLBuilder, BackgroundOperation<String>
             public void processResult(int rc, String path, Object ctx, List<ACL> acl, Stat stat)
             {
                 trace.commit();
-                CuratorEventImpl event = new CuratorEventImpl(client, CuratorEventType.GET_ACL, rc, path, null, ctx, stat, null, null, null, acl);
+                CuratorEventImpl event = new CuratorEventImpl(client, CuratorEventType.GET_ACL, rc, path, null, ctx, stat, null, null, null, acl, null);
                 client.processBackgroundOperation(operationAndData, event);
             }
         };

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/GetChildrenBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetChildrenBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetChildrenBuilderImpl.java
index 16f6d4b..03010ce 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetChildrenBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetChildrenBuilderImpl.java
@@ -162,7 +162,7 @@ class GetChildrenBuilderImpl implements GetChildrenBuilder, BackgroundOperation<
                 {
                     strings = Lists.newArrayList();
                 }
-                CuratorEventImpl event = new CuratorEventImpl(client, CuratorEventType.CHILDREN, rc, path, null, o, stat, null, strings, null, null);
+                CuratorEventImpl event = new CuratorEventImpl(client, CuratorEventType.CHILDREN, rc, path, null, o, stat, null, strings, null, null, null);
                 client.processBackgroundOperation(operationAndData, event);
             }
         };

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
index c9bbbf6..a837809 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetConfigBuilderImpl.java
@@ -143,7 +143,7 @@ public class GetConfigBuilderImpl implements GetConfigBuilder, BackgroundOperati
             public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat)
             {
                 trace.commit();
-                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.GET_CONFIG, rc, path, null, ctx, stat, data, null, null, null);
+                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.GET_CONFIG, rc, path, null, ctx, stat, data, null, null, null, null);
                 client.processBackgroundOperation(operationAndData, event);
             }
         };

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/GetDataBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetDataBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetDataBuilderImpl.java
index e994b03..23da075 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/GetDataBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/GetDataBuilderImpl.java
@@ -250,7 +250,7 @@ class GetDataBuilderImpl implements GetDataBuilder, BackgroundOperation<String>
                         rc = KeeperException.Code.DATAINCONSISTENCY.intValue();
                     }
                 }
-                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.GET_DATA, rc, path, null, ctx, stat, data, null, null, null);
+                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.GET_DATA, rc, path, null, ctx, stat, data, null, null, null, null);
                 client.processBackgroundOperation(operationAndData, event);
             }
         };

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
index f4dba90..0efa481 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/ReconfigBuilderImpl.java
@@ -476,7 +476,7 @@ public class ReconfigBuilderImpl implements
                 {
                     DataTree.copyStat(stat, responseStat);
                 }
-                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.RECONFIG, rc, path, null, ctx, stat, bytes, null, null, null);
+                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.RECONFIG, rc, path, null, ctx, stat, bytes, null, null, null, null);
                 client.processBackgroundOperation(data, event);
             }
         };

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/SetACLBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/SetACLBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/SetACLBuilderImpl.java
index f7b2480..17e88f8 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/SetACLBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/SetACLBuilderImpl.java
@@ -138,7 +138,7 @@ class SetACLBuilderImpl implements SetACLBuilder, BackgroundPathable<Stat>, Back
                 public void processResult(int rc, String path, Object ctx, Stat stat)
                 {
                     trace.commit();
-                    CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.SET_ACL, rc, path, null, ctx, stat, null, null, null, null);
+                    CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.SET_ACL, rc, path, null, ctx, stat, null, null, null, null, null);
                     client.processBackgroundOperation(operationAndData, event);
                 }
             },

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/SetDataBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/SetDataBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/SetDataBuilderImpl.java
index 8e93cbf..3ea704c 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/SetDataBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/SetDataBuilderImpl.java
@@ -20,7 +20,6 @@ package org.apache.curator.framework.imps;
 
 import org.apache.curator.RetryLoop;
 import org.apache.curator.TimeTrace;
-import org.apache.curator.framework.api.ACLPathAndBytesable;
 import org.apache.curator.framework.api.BackgroundCallback;
 import org.apache.curator.framework.api.BackgroundPathAndBytesable;
 import org.apache.curator.framework.api.CuratorEvent;
@@ -28,13 +27,11 @@ import org.apache.curator.framework.api.CuratorEventType;
 import org.apache.curator.framework.api.PathAndBytesable;
 import org.apache.curator.framework.api.SetDataBackgroundVersionable;
 import org.apache.curator.framework.api.SetDataBuilder;
-import org.apache.curator.framework.api.transaction.CuratorTransactionBridge;
 import org.apache.curator.framework.api.transaction.OperationType;
 import org.apache.curator.framework.api.transaction.TransactionSetDataBuilder;
 import org.apache.zookeeper.AsyncCallback;
 import org.apache.zookeeper.Op;
 import org.apache.zookeeper.data.Stat;
-
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executor;
 
@@ -53,12 +50,12 @@ class SetDataBuilderImpl implements SetDataBuilder, BackgroundOperation<PathAndB
         compress = false;
     }
 
-    TransactionSetDataBuilder   asTransactionSetDataBuilder(final CuratorTransactionImpl curatorTransaction, final CuratorMultiTransactionRecord transaction)
+    <T> TransactionSetDataBuilder<T> asTransactionSetDataBuilder(final T context, final CuratorMultiTransactionRecord transaction)
     {
-        return new TransactionSetDataBuilder()
+        return new TransactionSetDataBuilder<T>()
         {
             @Override
-            public CuratorTransactionBridge forPath(String path, byte[] data) throws Exception
+            public T forPath(String path, byte[] data) throws Exception
             {
                 if ( compress )
                 {
@@ -67,26 +64,26 @@ class SetDataBuilderImpl implements SetDataBuilder, BackgroundOperation<PathAndB
                 
                 String      fixedPath = client.fixForNamespace(path);
                 transaction.add(Op.setData(fixedPath, data, version), OperationType.SET_DATA, path);
-                return curatorTransaction;
+                return context;
             }
 
             @Override
-            public CuratorTransactionBridge forPath(String path) throws Exception
+            public T forPath(String path) throws Exception
             {
                 return forPath(path, client.getDefaultData());
             }
 
             @Override
-            public PathAndBytesable<CuratorTransactionBridge> withVersion(int version)
+            public PathAndBytesable<T> withVersion(int version)
             {
                 SetDataBuilderImpl.this.withVersion(version);
                 return this;
             }
 
             @Override
-            public PathAndBytesable<CuratorTransactionBridge> compressed() {
+            public PathAndBytesable<T> compressed()
+            {
                 compress = true;
-                
                 return this;
             }
         };
@@ -219,7 +216,7 @@ class SetDataBuilderImpl implements SetDataBuilder, BackgroundOperation<PathAndB
                 public void processResult(int rc, String path, Object ctx, Stat stat)
                 {
                     trace.commit();
-                    CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.SET_DATA, rc, path, null, ctx, stat, null, null, null, null);
+                    CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.SET_DATA, rc, path, null, ctx, stat, null, null, null, null, null);
                     client.processBackgroundOperation(operationAndData, event);
                 }
             },
@@ -246,7 +243,7 @@ class SetDataBuilderImpl implements SetDataBuilder, BackgroundOperation<PathAndB
         Stat        resultStat = null;
         if ( backgrounding.inBackground()  )
         {
-            client.processBackgroundOperation(new OperationAndData<PathAndBytes>(this, new PathAndBytes(path, data), backgrounding.getCallback(), null, backgrounding.getContext()), null);
+            client.processBackgroundOperation(new OperationAndData<>(this, new PathAndBytes(path, data), backgrounding.getCallback(), null, backgrounding.getContext()), null);
         }
         else
         {

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/SyncBuilderImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/SyncBuilderImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/SyncBuilderImpl.java
index 2d3e9c0..cab31ae 100644
--- a/curator-framework/src/main/java/org/apache/curator/framework/imps/SyncBuilderImpl.java
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/SyncBuilderImpl.java
@@ -93,7 +93,7 @@ public class SyncBuilderImpl implements SyncBuilder, BackgroundOperation<String>
             public void processResult(int rc, String path, Object ctx)
             {
                 trace.commit();
-                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.SYNC, rc, path, path, ctx, null, null, null, null, null);
+                CuratorEvent event = new CuratorEventImpl(client, CuratorEventType.SYNC, rc, path, path, ctx, null, null, null, null, null, null);
                 client.processBackgroundOperation(operationAndData, event);
             }
         };

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/main/java/org/apache/curator/framework/imps/TransactionOpImpl.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/main/java/org/apache/curator/framework/imps/TransactionOpImpl.java b/curator-framework/src/main/java/org/apache/curator/framework/imps/TransactionOpImpl.java
new file mode 100644
index 0000000..e0ada17
--- /dev/null
+++ b/curator-framework/src/main/java/org/apache/curator/framework/imps/TransactionOpImpl.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.curator.framework.imps;
+
+import org.apache.curator.framework.api.transaction.CuratorOp;
+import org.apache.curator.framework.api.transaction.TransactionCheckBuilder;
+import org.apache.curator.framework.api.transaction.TransactionCreateBuilder;
+import org.apache.curator.framework.api.transaction.TransactionDeleteBuilder;
+import org.apache.curator.framework.api.transaction.TransactionOp;
+import org.apache.curator.framework.api.transaction.TransactionSetDataBuilder;
+
+public class TransactionOpImpl implements TransactionOp
+{
+    private final CuratorFrameworkImpl client;
+
+    public TransactionOpImpl(CuratorFrameworkImpl client)
+    {
+        this.client = client;
+    }
+
+    @Override
+    public TransactionCreateBuilder<CuratorOp> create()
+    {
+        ExtractingCuratorOp op = new ExtractingCuratorOp();
+        return new CreateBuilderImpl(client).asTransactionCreateBuilder(op.asCuratorOp(), op.getRecord());
+    }
+
+    @Override
+    public TransactionDeleteBuilder<CuratorOp> delete()
+    {
+        ExtractingCuratorOp op = new ExtractingCuratorOp();
+        return new DeleteBuilderImpl(client).asTransactionDeleteBuilder(op.asCuratorOp(), op.getRecord());
+    }
+
+    @Override
+    public TransactionSetDataBuilder<CuratorOp> setData()
+    {
+        ExtractingCuratorOp op = new ExtractingCuratorOp();
+        return new SetDataBuilderImpl(client).asTransactionSetDataBuilder(op.asCuratorOp(), op.getRecord());
+    }
+
+    @Override
+    public TransactionCheckBuilder<CuratorOp> check()
+    {
+        ExtractingCuratorOp op = new ExtractingCuratorOp();
+        return CuratorTransactionImpl.makeTransactionCheckBuilder(client, op.asCuratorOp(), op.getRecord());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/curator/blob/7df5ab38/curator-framework/src/test/java/org/apache/curator/framework/imps/TestTransactions.java
----------------------------------------------------------------------
diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestTransactions.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestTransactions.java
deleted file mode 100644
index ae2cf1d..0000000
--- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestTransactions.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.curator.framework.imps;
-
-import com.google.common.collect.Iterables;
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
-import org.apache.curator.framework.api.transaction.OperationType;
-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.Collection;
-
-public class TestTransactions extends BaseClassForTests
-{
-    @Test
-    public void     testCheckVersion() throws Exception
-    {
-        CuratorFramework        client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1));
-        client.start();
-        try
-        {
-            client.create().forPath("/foo");
-            Stat        stat = client.setData().forPath("/foo", "new".getBytes());  // up the version
-
-            try
-            {
-                client.inTransaction()
-                    .check().withVersion(stat.getVersion() + 1).forPath("/foo") // force a bad version
-                .and()
-                    .create().forPath("/bar")
-                .and()
-                    .commit();
-
-                Assert.fail();
-            }
-            catch ( KeeperException.BadVersionException correct )
-            {
-                // correct
-            }
-            
-            Assert.assertNull(client.checkExists().forPath("/bar"));
-        }
-        finally
-        {
-            client.close();
-        }
-    }
-
-    @Test
-    public void     testWithNamespace() throws Exception
-    {
-        CuratorFramework        client = CuratorFrameworkFactory.builder().connectString(server.getConnectString()).retryPolicy(new RetryOneTime(1)).namespace("galt").build();
-        client.start();
-        try
-        {
-            Collection<CuratorTransactionResult>    results =
-                client.inTransaction()
-                    .create().forPath("/foo", "one".getBytes())
-                .and()
-                    .create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/test-", "one".getBytes())
-                .and()
-                    .setData().forPath("/foo", "two".getBytes())
-                .and()
-                    .create().forPath("/foo/bar")
-                .and()
-                    .delete().forPath("/foo/bar")
-                .and()
-                    .commit();
-
-            Assert.assertTrue(client.checkExists().forPath("/foo") != null);
-            Assert.assertTrue(client.usingNamespace(null).checkExists().forPath("/galt/foo") != null);
-            Assert.assertEquals(client.getData().forPath("/foo"), "two".getBytes());
-            Assert.assertTrue(client.checkExists().forPath("/foo/bar") == null);
-
-            CuratorTransactionResult    ephemeralResult = Iterables.find(results, CuratorTransactionResult.ofTypeAndPath(OperationType.CREATE, "/test-"));
-            Assert.assertNotNull(ephemeralResult);
-            Assert.assertNotEquals(ephemeralResult.getResultPath(), "/test-");
-            Assert.assertTrue(ephemeralResult.getResultPath().startsWith("/test-"));
-        }
-        finally
-        {
-            client.close();
-        }
-    }
-
-    @Test
-    public void     testBasic() throws Exception
-    {
-        CuratorFramework        client = CuratorFrameworkFactory.newClient(server.getConnectString(), new RetryOneTime(1));
-        client.start();
-        try
-        {
-            Collection<CuratorTransactionResult>    results =
-                client.inTransaction()
-                    .create().forPath("/foo")
-                .and()
-                    .create().forPath("/foo/bar", "snafu".getBytes())
-                .and()
-                    .commit();
-
-            Assert.assertTrue(client.checkExists().forPath("/foo/bar") != null);
-            Assert.assertEquals(client.getData().forPath("/foo/bar"), "snafu".getBytes());
-
-            CuratorTransactionResult    fooResult = Iterables.find(results, CuratorTransactionResult.ofTypeAndPath(OperationType.CREATE, "/foo"));
-            CuratorTransactionResult    fooBarResult = Iterables.find(results, CuratorTransactionResult.ofTypeAndPath(OperationType.CREATE, "/foo/bar"));
-            Assert.assertNotNull(fooResult);
-            Assert.assertNotNull(fooBarResult);
-            Assert.assertNotSame(fooResult, fooBarResult);
-            Assert.assertEquals(fooResult.getResultPath(), "/foo");
-            Assert.assertEquals(fooBarResult.getResultPath(), "/foo/bar");
-        }
-        finally
-        {
-            client.close();
-        }
-    }
-}