[jbosscache-commits] JBoss Cache SVN: r6111 - in core/trunk/src: main/java/org/jboss/cache/commands and 17 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Fri Jun 27 18:36:57 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-06-27 18:36:56 -0400 (Fri, 27 Jun 2008)
New Revision: 6111

Added:
   core/trunk/src/main/java/org/jboss/cache/commands/WriteCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/ReversibleCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessClearDataCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessCreateNodeCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessMoveCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutDataMapCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutForExternalReadCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutKeyValueCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessRemoveKeyCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessRemoveNodeCommand.java
   core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java
   core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactoryImpl.java
   core/trunk/src/main/java/org/jboss/cache/factories/CommandsMetaFactory.java
   core/trunk/src/main/java/org/jboss/cache/factories/PessimisticCommandsFactoryImpl.java
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/ClearDataCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/CreateNodeCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/MoveCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/PutDataMapCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/PutKeyValueCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/RemoveKeyCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/RemoveNodeCommandTest.java
Removed:
   core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java
   core/trunk/src/test/java/org/jboss/cache/commands/write/MoveCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/buddyreplication/Fqn2BuddyFqnVisitor.java
   core/trunk/src/main/java/org/jboss/cache/commands/VersionedDataCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/read/GetKeyValueCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/read/GravitateDataCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/remote/ClusteredGetCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/remote/DataGravitationCleanupCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/remote/ReplicateCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/tx/OptimisticPrepareCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/tx/PrepareCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/AbstractVersionedDataCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/ClearDataCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/CreateNodeCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/InvalidateCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/MoveCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
   core/trunk/src/main/java/org/jboss/cache/commands/write/VersionedInvalidateCommand.java
   core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
   core/trunk/src/main/java/org/jboss/cache/factories/EmptyConstructorFactory.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CallInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/ReplicationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/marshall/AbstractMarshaller.java
   core/trunk/src/main/java/org/jboss/cache/transaction/PessimisticTransactionContext.java
   core/trunk/src/main/java/org/jboss/cache/transaction/TransactionContext.java
   core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyManagerTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/RollbackOnNoOpTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/StructuralNodesOnRollbackTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/write/AbstractVersionedDataCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/commands/write/EvictCommandTest.java
   core/trunk/src/test/java/org/jboss/cache/marshall/MethodIdPreservationTest.java
   core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingTest.java
   core/trunk/src/test/java/org/jboss/cache/optimistic/AbstractOptimisticTestCase.java
   core/trunk/src/test/java/org/jboss/cache/optimistic/CacheTest.java
   core/trunk/src/test/java/org/jboss/cache/optimistic/TxInterceptorTest.java
Log:
Refactored to move pess locking specific rollbacks into separate command subclasses

Modified: core/trunk/src/main/java/org/jboss/cache/buddyreplication/Fqn2BuddyFqnVisitor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/buddyreplication/Fqn2BuddyFqnVisitor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/buddyreplication/Fqn2BuddyFqnVisitor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -2,7 +2,7 @@
 
 import org.jboss.cache.Fqn;
 import org.jboss.cache.commands.AbstractVisitor;
-import org.jboss.cache.commands.ReversibleCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.read.ExistsCommand;
 import org.jboss.cache.commands.read.GetChildrenNamesCommand;
 import org.jboss.cache.commands.read.GetDataMapCommand;
@@ -169,8 +169,8 @@
    @Override
    public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable
    {
-      List<ReversibleCommand> toTransform = command.getModifications();
-      List<ReversibleCommand> transformedCommands = transformBatch(toTransform);
+      List<WriteCommand> toTransform = command.getModifications();
+      List<WriteCommand> transformedCommands = transformBatch(toTransform);
       return factory.buildPrepareCommand(command.getGlobalTransaction(), transformedCommands, command.getLocalAddress(), command.isOnePhaseCommit());
    }
 
@@ -183,7 +183,7 @@
    @Override
    public Object visitOptimisticPrepareCommand(InvocationContext ctx, OptimisticPrepareCommand command) throws Throwable
    {
-      List<ReversibleCommand> transformed = transformBatch(command.getModifications());
+      List<WriteCommand> transformed = transformBatch(command.getModifications());
       return factory.buildOptimisticPrepareCommand(command.getGlobalTransaction(), transformed, command.getLocalAddress(), command.isOnePhaseCommit());
    }
 
@@ -193,12 +193,12 @@
       return factory.buildCreateNodeCommand(getBackupFqn(command.getFqn()));
    }
 
-   public List<ReversibleCommand> transformBatch(List<ReversibleCommand> toTransform) throws Throwable
+   public List<WriteCommand> transformBatch(List<WriteCommand> toTransform) throws Throwable
    {
-      List<ReversibleCommand> transformedCommands = new ArrayList<ReversibleCommand>(toTransform.size());
-      for (ReversibleCommand com : toTransform)
+      List<WriteCommand> transformedCommands = new ArrayList<WriteCommand>(toTransform.size());
+      for (WriteCommand com : toTransform)
       {
-         transformedCommands.add((ReversibleCommand) com.acceptVisitor(null, this));
+         transformedCommands.add((WriteCommand) com.acceptVisitor(null, this));
       }
       return transformedCommands;
    }

Modified: core/trunk/src/main/java/org/jboss/cache/commands/VersionedDataCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/VersionedDataCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/VersionedDataCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -10,7 +10,7 @@
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 2.2.0
  */
-public interface VersionedDataCommand extends ReversibleCommand
+public interface VersionedDataCommand extends WriteCommand
 {
    /**
     * @return the DataVersion pertaining to this command.

Copied: core/trunk/src/main/java/org/jboss/cache/commands/WriteCommand.java (from rev 6106, core/trunk/src/main/java/org/jboss/cache/commands/ReversibleCommand.java)
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/WriteCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/WriteCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,25 @@
+package org.jboss.cache.commands;
+
+import org.jboss.cache.transaction.GlobalTransaction;
+
+/**
+ * A write command that has a reference to a {@link org.jboss.cache.transaction.GlobalTransaction}.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 2.2.0
+ */
+public interface WriteCommand extends DataCommand
+{
+   /**
+    * @return a GlobalTransaction associated with this command.
+    */
+   GlobalTransaction getGlobalTransaction();
+
+   /**
+    * Sets a GlobalTransaction on this command.
+    *
+    * @param gtx global transaction to set
+    */
+   void setGlobalTransaction(GlobalTransaction gtx);
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/ReversibleCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/ReversibleCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/ReversibleCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,20 @@
+package org.jboss.cache.commands.pessimistic;
+
+import org.jboss.cache.commands.WriteCommand;
+
+/**
+ * A write command that can be reversed by calling a rollback.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public interface ReversibleCommand extends WriteCommand
+{
+   /**
+    * Reverses a command that has already been invoked.
+    * <p/>
+    * <b>Important</b>: this method will be invoked at the end of interceptors chain. It should never be called directly from
+    * a custom interceptor.
+    */
+   void rollback();
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessClearDataCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessClearDataCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessClearDataCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,59 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
+import org.jboss.cache.commands.write.ClearDataCommand;
+import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+import java.util.HashMap;
+
+/**
+ * A version of {@link org.jboss.cache.commands.write.ClearDataCommand} which can be rolled back, for use with
+ * pessimistic locking where changes are made directly on the data structures and may need to be reversed.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class PessClearDataCommand extends ClearDataCommand implements ReversibleCommand
+{
+   private HashMap originalData;
+
+   public PessClearDataCommand(GlobalTransaction gtx, Fqn fqn)
+   {
+      super(gtx, fqn);
+   }
+
+   public PessClearDataCommand()
+   {
+   }
+
+   @Override
+   public Object perform(InvocationContext ctx)
+   {
+      if (globalTransaction != null)
+      {
+         NodeSPI n = ctx.lookUpNode(fqn);
+         originalData = n == null ? null : new HashMap(n.getDataDirect());
+      }
+      return super.perform(ctx);
+   }
+
+   public void rollback()
+   {
+      if (trace) log.trace("rollback(" + globalTransaction + ", \"" + fqn + "\", " + originalData + ")");
+      if (originalData != null && !originalData.isEmpty())
+      {
+         NodeSPI nodeSpi = dataContainer.peek(fqn, false, true);
+         if (nodeSpi == null)
+         {
+            if (trace)
+               log.trace("Not rolling back node clearance for node: " + fqn + " as it does not exist in the cache. " +
+                     "This might be the result of an NoOp clear operation");
+            return;
+         }
+         nodeSpi.putAllDirect(originalData);
+      }
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessCreateNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessCreateNodeCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessCreateNodeCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,39 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
+import org.jboss.cache.commands.write.CreateNodeCommand;
+
+import java.util.List;
+
+/**
+ * A version of {@link org.jboss.cache.commands.write.CreateNodeCommand} which can be rolled back, for use with
+ * pessimistic locking where changes are made directly on the data structures and may need to be reversed.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class PessCreateNodeCommand extends CreateNodeCommand implements ReversibleCommand
+{
+   public PessCreateNodeCommand(Fqn fqn)
+   {
+      super(fqn);
+   }
+
+   public PessCreateNodeCommand()
+   {
+   }
+
+   public void rollback()
+   {
+      if (newlyCreated != null)
+      {
+         for (Fqn f : newlyCreated) dataContainer.removeFromDataStructure(f, true);
+      }
+   }
+
+   List<Fqn> getNewlyCreated()
+   {
+      return newlyCreated;
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessMoveCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessMoveCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessMoveCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,29 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
+import org.jboss.cache.commands.write.MoveCommand;
+
+/**
+ * A version of {@link org.jboss.cache.commands.write.MoveCommand} which can be rolled back, for use with
+ * pessimistic locking where changes are made directly on the data structures and may need to be reversed.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class PessMoveCommand extends MoveCommand implements ReversibleCommand
+{
+   public PessMoveCommand()
+   {
+   }
+
+   public PessMoveCommand(Fqn from, Fqn to)
+   {
+      super(from, to);
+   }
+
+   public void rollback()
+   {
+      move(Fqn.fromRelativeElements(to, fqn.getLastElement()), fqn.getParent(), true, null);
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutDataMapCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutDataMapCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutDataMapCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,56 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A version of {@link org.jboss.cache.commands.write.PutDataMapCommand} which can be rolled back, for use with
+ * pessimistic locking where changes are made directly on the data structures and may need to be reversed.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class PessPutDataMapCommand extends PutDataMapCommand implements ReversibleCommand
+{
+   Map oldData;
+
+   public PessPutDataMapCommand(GlobalTransaction globalTransaction, Fqn fqn, Map data)
+   {
+      super(globalTransaction, fqn, data);
+   }
+
+   public PessPutDataMapCommand()
+   {
+   }
+
+   @Override
+   public Object perform(InvocationContext ctx)
+   {
+      // first get a hold of existing data.
+      NodeSPI node = ctx.lookUpNode(fqn);
+      Map existingData = node == null ? null : node.getDataDirect();
+      if (existingData != null && !existingData.isEmpty())
+      {
+         oldData = new HashMap(existingData); // defensive copy
+      }
+      return super.perform(ctx);
+   }
+
+   public void rollback()
+   {
+      if (trace) log.trace("rollback(" + globalTransaction + ", " + fqn + ", " + data + ")");
+      NodeSPI n = dataContainer.peek(fqn, false, true);
+      if (n != null)
+      {
+         n.clearDataDirect();
+         if (oldData != null) n.putAllDirect(oldData);
+      }
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutForExternalReadCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutForExternalReadCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutForExternalReadCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,51 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
+import org.jboss.cache.commands.write.PutForExternalReadCommand;
+import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+/**
+ * A version of {@link org.jboss.cache.commands.write.PutForExternalReadCommand} which can be rolled back, for use with
+ * pessimistic locking where changes are made directly on the data structures and may need to be reversed.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class PessPutForExternalReadCommand extends PutForExternalReadCommand implements ReversibleCommand
+{
+   protected Object oldValue;
+
+   public PessPutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
+   {
+      super(gtx, fqn, key, value);
+   }
+
+   public PessPutForExternalReadCommand()
+   {
+   }
+
+   @Override
+   public Object perform(InvocationContext ctx)
+   {
+      oldValue = super.perform(ctx);
+      return oldValue;
+   }
+
+   public void rollback()
+   {
+      NodeSPI n = dataContainer.peek(fqn, false, false);
+      if (n == null) throw new CacheException("node " + fqn + " not found for rollback!");
+      if (oldValue == null)
+      {
+         n.removeDirect(key);
+      }
+      else
+      {
+         n.putDirect(key, oldValue);
+      }
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutKeyValueCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutKeyValueCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessPutKeyValueCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,51 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+/**
+ * A version of {@link org.jboss.cache.commands.write.PutKeyValueCommand} which can be rolled back, for use with
+ * pessimistic locking where changes are made directly on the data structures and may need to be reversed.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class PessPutKeyValueCommand extends PutKeyValueCommand implements ReversibleCommand
+{
+   protected Object oldValue;
+
+   public PessPutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
+   {
+      super(gtx, fqn, key, value);
+   }
+
+   public PessPutKeyValueCommand()
+   {
+   }
+
+   @Override
+   public Object perform(InvocationContext ctx)
+   {
+      oldValue = super.perform(ctx);
+      return oldValue;
+   }
+
+   public void rollback()
+   {
+      NodeSPI n = dataContainer.peek(fqn, false, false);
+      if (n == null) throw new CacheException("node " + fqn + " not found for rollback!");
+      if (oldValue == null)
+      {
+         n.removeDirect(key);
+      }
+      else
+      {
+         n.putDirect(key, oldValue);
+      }
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessRemoveKeyCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessRemoveKeyCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessRemoveKeyCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,46 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+/**
+ * A version of {@link org.jboss.cache.commands.write.RemoveKeyCommand} which can be rolled back, for use with
+ * pessimistic locking where changes are made directly on the data structures and may need to be reversed.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class PessRemoveKeyCommand extends RemoveKeyCommand implements ReversibleCommand
+{
+   /* internally used for rollback */
+   private Object oldValue;
+
+   public PessRemoveKeyCommand(GlobalTransaction gtx, Fqn fqn, Object key)
+   {
+      super(gtx, fqn, key);
+   }
+
+   public PessRemoveKeyCommand()
+   {
+   }
+
+   @Override
+   public Object perform(InvocationContext ctx)
+   {
+      oldValue = super.perform(ctx);
+      return oldValue;
+   }
+
+   public void rollback()
+   {
+      if (oldValue != null)
+      {
+         NodeSPI targetNode = dataContainer.peek(fqn, false, true);
+         if (targetNode != null) targetNode.putDirect(key, oldValue);
+      }
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessRemoveNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessRemoveNodeCommand.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/commands/pessimistic/write/PessRemoveNodeCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,86 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
+import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A version of {@link org.jboss.cache.commands.write.RemoveNodeCommand} which can be rolled back, for use with
+ * pessimistic locking where changes are made directly on the data structures and may need to be reversed.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class PessRemoveNodeCommand extends RemoveNodeCommand implements ReversibleCommand
+{
+   protected Map originalData;
+
+   public PessRemoveNodeCommand(GlobalTransaction globalTransaction, Fqn fqn)
+   {
+      super(globalTransaction, fqn);
+   }
+
+   public PessRemoveNodeCommand()
+   {
+   }
+
+   @Override
+   public Object perform(InvocationContext ctx)
+   {
+      boolean found = (Boolean) super.perform(ctx);
+
+      // now record rollback info.
+      if (globalTransaction != null && found)
+      {
+         NodeSPI parentNode = targetNode.getParent();
+         prepareForRollback(parentNode);
+      }
+      return found;
+   }
+
+
+   private void prepareForRollback(NodeSPI parentNode)
+   {
+      parentFqn = parentNode.getFqn();
+      Map targetData = targetNode.getDataDirect();
+      if (!targetData.isEmpty())
+      {
+         originalData = new HashMap(targetNode.getDataDirect());
+      }
+   }
+
+   public void rollback()
+   {
+      if (targetNode != null)
+      {
+         Object childName = targetNode.getFqn().getLastElement();
+         if (trace)
+         {
+            log.trace("rollback(parent: " + parentFqn + ", child: " + childName + ", node=" + targetNode + ")");
+         }
+
+         if (parentFqn == null || childName == null)
+         {
+            log.error("parent fqn or childName or childNode was null");
+            return;
+         }
+         NodeSPI parentNode = dataContainer.peek(parentFqn);
+         if (parentNode == null)
+         {
+            log.warn("node " + parentFqn + " not found");
+            return;
+         }
+         parentNode.addChild(childName, targetNode);
+         targetNode.markAsDeleted(false, true);
+         targetNode.clearDataDirect();
+         if (originalData != null) targetNode.putAllDirect(originalData);
+         targetNode.setValid(true, true);
+      }
+   }
+}

Modified: core/trunk/src/main/java/org/jboss/cache/commands/read/GetKeyValueCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/read/GetKeyValueCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GetKeyValueCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -22,7 +22,7 @@
 {
    public static final int METHOD_ID = 26;
    private static final Log log = LogFactory.getLog(GetKeyValueCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
    private Notifier notifier;
 
    private Object key;

Modified: core/trunk/src/main/java/org/jboss/cache/commands/read/GravitateDataCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/read/GravitateDataCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GravitateDataCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -41,7 +41,7 @@
    private Address localAddress;
 
    private static final Log log = LogFactory.getLog(GravitateDataCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
    private BuddyFqnTransformer buddyFqnTransformer;
 
    public GravitateDataCommand(Fqn fqn, boolean searchSubtrees, Address localAddress)

Modified: core/trunk/src/main/java/org/jboss/cache/commands/remote/ClusteredGetCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/remote/ClusteredGetCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/remote/ClusteredGetCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -34,7 +34,7 @@
    private InterceptorChain interceptorChain;
 
    private static final Log log = LogFactory.getLog(ClusteredGetCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
 
    public ClusteredGetCommand(boolean searchBackupSubtrees, DataCommand dataCommand)
    {

Modified: core/trunk/src/main/java/org/jboss/cache/commands/remote/DataGravitationCleanupCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/remote/DataGravitationCleanupCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/remote/DataGravitationCleanupCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -31,7 +31,7 @@
 {
    public static final int METHOD_ID = 34;
    private static final Log log = LogFactory.getLog(DataGravitationCleanupCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
 
    /* dependencies */
    private BuddyManager buddyManager;

Modified: core/trunk/src/main/java/org/jboss/cache/commands/remote/ReplicateCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/remote/ReplicateCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/remote/ReplicateCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -31,7 +31,7 @@
    private InterceptorChain invoker;
 
    private static final Log log = LogFactory.getLog(ReplicateCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
 
    /**
     * optimisation - rather than constructing a new list each for scenarios where a single modification needs

Modified: core/trunk/src/main/java/org/jboss/cache/commands/tx/OptimisticPrepareCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/tx/OptimisticPrepareCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/tx/OptimisticPrepareCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,7 +1,7 @@
 package org.jboss.cache.commands.tx;
 
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.Visitor;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.invocation.InvocationContext;
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jgroups.Address;
@@ -19,7 +19,7 @@
 {
    public static final int METHOD_ID = 18;
 
-   public OptimisticPrepareCommand(GlobalTransaction gtx, List<ReversibleCommand> modifications, Address address, boolean onePhaseCommit)
+   public OptimisticPrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, Address address, boolean onePhaseCommit)
    {
       super(gtx, modifications, address, onePhaseCommit);
    }
@@ -58,7 +58,7 @@
       OptimisticPrepareCommand copy = new OptimisticPrepareCommand();
       copy.globalTransaction = globalTransaction;
       copy.localAddress = localAddress;
-      copy.modifications = modifications == null ? null : new ArrayList<ReversibleCommand>(modifications);
+      copy.modifications = modifications == null ? null : new ArrayList<WriteCommand>(modifications);
       copy.onePhaseCommit = onePhaseCommit;
       return copy;
    }
@@ -68,7 +68,7 @@
    public void setParameters(int commandId, Object[] args)
    {
       globalTransaction = (GlobalTransaction) args[0];
-      modifications = (List<ReversibleCommand>) args[1];
+      modifications = (List<WriteCommand>) args[1];
       //args[2] is probably null.
       localAddress = (Address) args[3];
       onePhaseCommit = (Boolean) args[4];

Modified: core/trunk/src/main/java/org/jboss/cache/commands/tx/PrepareCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/tx/PrepareCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/tx/PrepareCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,8 +1,8 @@
 package org.jboss.cache.commands.tx;
 
 import org.jboss.cache.commands.ReplicableCommand;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.Visitor;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.invocation.InvocationContext;
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jgroups.Address;
@@ -21,11 +21,11 @@
 {
    public static final int METHOD_ID = 10;
 
-   protected List<ReversibleCommand> modifications;
+   protected List<WriteCommand> modifications;
    protected Address localAddress;
    protected boolean onePhaseCommit;
 
-   public PrepareCommand(GlobalTransaction gtx, List<ReversibleCommand> modifications, Address localAddress, boolean onePhaseCommit)
+   public PrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, Address localAddress, boolean onePhaseCommit)
    {
       this.globalTransaction = gtx;
       this.modifications = modifications;
@@ -33,7 +33,7 @@
       this.onePhaseCommit = onePhaseCommit;
    }
 
-   public void removeModifications(Collection<ReversibleCommand> modificationsToRemove)
+   public void removeModifications(Collection<WriteCommand> modificationsToRemove)
    {
       if (modifications != null) modifications.removeAll(modificationsToRemove);
    }
@@ -47,7 +47,7 @@
       return visitor.visitPrepareCommand(ctx, this);
    }
 
-   public List<ReversibleCommand> getModifications()
+   public List<WriteCommand> getModifications()
    {
       return modifications;
    }
@@ -88,7 +88,7 @@
    public void setParameters(int commandId, Object[] args)
    {
       globalTransaction = (GlobalTransaction) args[0];
-      modifications = (List<ReversibleCommand>) args[1];
+      modifications = (List<WriteCommand>) args[1];
       localAddress = (Address) args[2];
       onePhaseCommit = (Boolean) args[3];
    }
@@ -124,7 +124,7 @@
       PrepareCommand copy = new PrepareCommand();
       copy.globalTransaction = globalTransaction;
       copy.localAddress = localAddress;
-      copy.modifications = modifications == null ? null : new ArrayList<ReversibleCommand>(modifications);
+      copy.modifications = modifications == null ? null : new ArrayList<WriteCommand>(modifications);
       copy.onePhaseCommit = onePhaseCommit;
       return copy;
    }

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/AbstractVersionedDataCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/AbstractVersionedDataCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/AbstractVersionedDataCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,6 +1,5 @@
 package org.jboss.cache.commands.write;
 
-import org.jboss.cache.CacheException;
 import org.jboss.cache.DataContainer;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeSPI;
@@ -24,24 +23,13 @@
 
    protected DataVersion dataVersion;
    protected GlobalTransaction globalTransaction;
-   private boolean suppressRollbacks;
 
-   public void initialize(Notifier notifier, DataContainer dataContainer, boolean suppressRollbacks)
+   public void initialize(Notifier notifier, DataContainer dataContainer)
    {
       this.notifier = notifier;
       this.dataContainer = dataContainer;
-      this.suppressRollbacks = suppressRollbacks;
    }
 
-   /**
-    * Test if the current node locking scheme allows for rollbacks.
-    */
-   protected void assertRollbackAllowed()
-   {
-      if (suppressRollbacks)
-         throw new CacheException("Rollback should never be called directly on a command when using MVCC, since this should be dealt with in the MVCCLockingInterceptor.");
-   }
-
    public DataVersion getDataVersion()
    {
       return dataVersion;

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/ClearDataCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/ClearDataCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/ClearDataCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -10,7 +10,6 @@
 import org.jboss.cache.optimistic.DataVersion;
 import org.jboss.cache.transaction.GlobalTransaction;
 
-import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -24,12 +23,9 @@
    public static final int METHOD_ID = 7;
    public static final int VERSIONED_METHOD_ID = 42;
 
-   private static final Log log = LogFactory.getLog(ClearDataCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   protected static final Log log = LogFactory.getLog(ClearDataCommand.class);
+   protected static final boolean trace = log.isTraceEnabled();
 
-   /* parameters*/
-   private HashMap originalData;
-
    public ClearDataCommand(GlobalTransaction gtx, Fqn fqn)
    {
       this.globalTransaction = gtx;
@@ -58,36 +54,12 @@
       }
 
       Map data = targetNode.getDataDirect();
-      prepareDataForRollback(data);
       notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, data, ctx);
       targetNode.clearDataDirect();
       notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, data, ctx);
       return null;
    }
 
-   private void prepareDataForRollback(Map data)
-   {
-      if (globalTransaction != null && !data.isEmpty())
-      {
-         originalData = new HashMap(data);
-      }
-   }
-
-   public void rollback()
-   {
-      assertRollbackAllowed();
-      if (trace) log.trace("rollback(" + globalTransaction + ", \"" + fqn + "\", " + originalData + ")");
-      NodeSPI nodeSpi = dataContainer.peek(fqn, false, true);
-      if (nodeSpi == null)
-      {
-         if (trace)
-            log.trace("Not rolling back node clearance for node: " + fqn + " as it does not exist in the cache. " +
-                  "This might be the result of an NoOp clear operation");
-         return;
-      }
-      nodeSpi.putAllDirect(originalData);
-   }
-
    public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
    {
       return visitor.visitClearDataCommand(ctx, this);
@@ -146,7 +118,6 @@
             "fqn=" + fqn +
             ", dataVersion=" + dataVersion +
             ", globalTransaction=" + globalTransaction +
-            ", originalData=" + originalData +
             '}';
    }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/CreateNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/CreateNodeCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/CreateNodeCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,10 +1,9 @@
 package org.jboss.cache.commands.write;
 
-import org.jboss.cache.CacheException;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeSPI;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.Visitor;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.read.AbstractDataCommand;
 import org.jboss.cache.invocation.InvocationContext;
 import org.jboss.cache.transaction.GlobalTransaction;
@@ -18,16 +17,14 @@
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 2.2.0
  */
-public class CreateNodeCommand extends AbstractDataCommand implements ReversibleCommand
+public class CreateNodeCommand extends AbstractDataCommand implements WriteCommand
 {
    public static final int METHOD_ID = 48;
-   private final List<Fqn> newlyCreated = new LinkedList<Fqn>();
-   private boolean suppressRollbacks;
+   protected final List<Fqn> newlyCreated = new LinkedList<Fqn>();
 
-   public CreateNodeCommand(Fqn fqn, boolean suppressRollbacks)
+   public CreateNodeCommand(Fqn fqn)
    {
       this.fqn = fqn;
-      this.suppressRollbacks = suppressRollbacks;
       newlyCreated.add(fqn);
    }
 
@@ -35,15 +32,6 @@
    {
    }
 
-   /**
-    * Test if the current node locking scheme allows for rollbacks.
-    */
-   protected void assertRollbackAllowed()
-   {
-      if (suppressRollbacks)
-         throw new CacheException("Rollback should never be called directly on a command when using MVCC, since this should be dealt with in the MVCCLockingInterceptor.");
-   }
-
    public int getCommandId()
    {
       return METHOD_ID;
@@ -86,15 +74,6 @@
       return visitor.visitCreateNodeCommand(ctx, this);
    }
 
-   public void rollback()
-   {
-      assertRollbackAllowed();
-      if (newlyCreated != null)
-      {
-         for (Fqn f : newlyCreated) dataContainer.removeFromDataStructure(f, true);
-      }
-   }
-
    @Override
    public String toString()
    {
@@ -103,9 +82,4 @@
             ", newlyCreated=" + newlyCreated +
             '}';
    }
-
-   List<Fqn> getNewlyCreated()
-   {
-      return newlyCreated;
-   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/InvalidateCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/InvalidateCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/InvalidateCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -22,7 +22,7 @@
 {
    public static final int METHOD_ID = 47;
    private static final Log log = LogFactory.getLog(InvalidateCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
 
    /* dependencies*/
    protected CacheSPI spi;

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/MoveCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/MoveCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/MoveCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -2,13 +2,12 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.CacheException;
 import org.jboss.cache.DataContainer;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeNotExistsException;
 import org.jboss.cache.NodeSPI;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.Visitor;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.read.AbstractDataCommand;
 import org.jboss.cache.invocation.InvocationContext;
 import org.jboss.cache.notifications.Notifier;
@@ -21,29 +20,27 @@
  * @since 2.2
  */
 // TODO: 2.2.0: Make sure this is properly intercepted, i.e., locked and loaded!!
-public class MoveCommand extends AbstractDataCommand implements ReversibleCommand
+public class MoveCommand extends AbstractDataCommand implements WriteCommand
 {
    public static final int METHOD_ID = 36;
    private static final Log log = LogFactory.getLog(MoveCommand.class);
-   private static boolean trace = log.isTraceEnabled();
-   private boolean suppressRollbacks;
+   private static final boolean trace = log.isTraceEnabled();
 
    /* dependencies */
    private Notifier notifier;
 
    /* params */
-   private Fqn to;
-   private GlobalTransaction globalTransaction;
+   protected Fqn to;
+   protected GlobalTransaction globalTransaction;
 
    public MoveCommand()
    {
    }
 
-   public void initialize(Notifier notifier, DataContainer dataContainer, boolean suppressRollbacks)
+   public void initialize(Notifier notifier, DataContainer dataContainer)
    {
       this.notifier = notifier;
       this.dataContainer = dataContainer;
-      this.suppressRollbacks = suppressRollbacks;
    }
 
    public MoveCommand(Fqn from, Fqn to)
@@ -52,15 +49,6 @@
       this.to = to;
    }
 
-   /**
-    * Test if the current node locking scheme allows for rollbacks.
-    */
-   protected void assertRollbackAllowed()
-   {
-      if (suppressRollbacks)
-         throw new CacheException("Rollback should never be called directly on a command when using MVCC, since this should be dealt with in the MVCCLockingInterceptor.");
-   }
-
    public GlobalTransaction getGlobalTransaction()
    {
       return globalTransaction;
@@ -83,13 +71,6 @@
       return null;
    }
 
-   public void rollback()
-   {
-      assertRollbackAllowed();
-      move(Fqn.fromRelativeElements(to, fqn.getLastElement()), fqn.getParent(), true, null);
-   }
-
-
    private void adjustFqn(NodeSPI node, Fqn newBase)
    {
       Fqn newFqn = Fqn.fromRelativeElements(newBase, node.getFqn().getLastElement());
@@ -101,7 +82,7 @@
       return visitor.visitMoveCommand(ctx, this);
    }
 
-   private void move(Fqn toMoveFqn, Fqn newParentFqn, boolean skipNotifications, InvocationContext ctx)
+   protected void move(Fqn toMoveFqn, Fqn newParentFqn, boolean skipNotifications, InvocationContext ctx)
    {
       // the actual move algorithm.
       // ctx *could* be null if this is a rollback!!!  Sucks big time.

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/PutDataMapCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -12,7 +12,6 @@
 import org.jboss.cache.transaction.GlobalTransaction;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -28,12 +27,11 @@
    public static final int VERSIONED_METHOD_ID = 37;
    public static final int ERASE_VERSIONED_METHOD_ID = 38;
 
-   private static final Log log = LogFactory.getLog(PutDataMapCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   protected static final Log log = LogFactory.getLog(PutDataMapCommand.class);
+   protected static final boolean trace = log.isTraceEnabled();
 
    /* parameters*/
-   private Map data;
-   private Map oldData;
+   protected Map data;
 
    public PutDataMapCommand(GlobalTransaction globalTransaction, Fqn fqn, Map data)
    {
@@ -59,13 +57,10 @@
       NodeSPI nodeSPI = ctx.lookUpNode(fqn);
       if (nodeSPI == null) throw new NodeNotExistsException("Node " + fqn + " does not exist!");
       Map existingData = nodeSPI.getDataDirect();
-      if (!existingData.isEmpty())
-      {
-         oldData = new HashMap(existingData); // defensive copy
-      }
+
       if (notifier.shouldNotifyOnNodeModified())
       {
-         notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_MAP, oldData == null ? Collections.emptyMap() : oldData, ctx);
+         notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_MAP, existingData == null ? Collections.emptyMap() : existingData, ctx);
       }
 
       nodeSPI.putAllDirect(data);
@@ -76,18 +71,6 @@
       return null;
    }
 
-   public void rollback()
-   {
-      assertRollbackAllowed();
-      if (trace) log.trace("rollback(" + globalTransaction + ", " + fqn + ", " + data + ")");
-      NodeSPI n = dataContainer.peek(fqn, false, true);
-      if (n != null)
-      {
-         n.clearDataDirect();
-         if (oldData != null) n.putAllDirect(oldData);
-      }
-   }
-
    public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
    {
       return visitor.visitPutDataMapCommand(ctx, this);
@@ -172,9 +155,4 @@
             ", globalTransaction=" + globalTransaction +
             '}';
    }
-
-   Map getOldData()
-   {
-      return oldData;
-   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/PutKeyValueCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -2,7 +2,6 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.CacheException;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeNotExistsException;
 import org.jboss.cache.NodeSPI;
@@ -27,12 +26,11 @@
    public static final int VERSIONED_METHOD_ID = 39;
 
    private static final Log log = LogFactory.getLog(PutKeyValueCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
 
    /* parametres */
    protected Object key;
    protected Object value;
-   protected Object oldValue;
 
    public PutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
    {
@@ -64,7 +62,7 @@
       {
          notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, n.getDataDirect(), ctx);
       }
-      oldValue = n.putDirect(key, value);
+      Object oldValue = n.putDirect(key, value);
 
       if (notifier.shouldNotifyOnNodeModified())
       {
@@ -74,21 +72,6 @@
       return oldValue;
    }
 
-   public void rollback()
-   {
-      assertRollbackAllowed();
-      NodeSPI n = dataContainer.peek(fqn, false, false);
-      if (n == null) throw new CacheException("node " + fqn + " not found for rollback!");
-      if (oldValue == null)
-      {
-         n.removeDirect(key);
-      }
-      else
-      {
-         n.putDirect(key, oldValue);
-      }
-   }
-
    public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
    {
       return visitor.visitPutKeyValueCommand(ctx, this);
@@ -187,7 +170,6 @@
             ", globalTransaction=" + globalTransaction +
             ", key=" + key +
             ", value=" + value +
-            ", oldValue=" + oldValue +
             '}';
    }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveKeyCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -25,14 +25,11 @@
    public static final int VERSIONED_METHOD_ID = 41;
 
    private static final Log log = LogFactory.getLog(RemoveKeyCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
 
    /* parameters */
-   private Object key;
+   protected Object key;
 
-   /* internally used for rollback */
-   private Object oldValue;
-
    public RemoveKeyCommand(GlobalTransaction gtx, Fqn fqn, Object key)
    {
       this.globalTransaction = gtx;
@@ -54,7 +51,6 @@
    {
       if (trace) log.trace("perform(" + globalTransaction + ", \"" + fqn + "\", key=" + key + ")");
 
-//      NodeSPI n = dataContainer.peek(fqn, false, false);
       NodeSPI n = ctx.lookUpNode(fqn);
       if (n == null)
       {
@@ -65,7 +61,7 @@
       {
          notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, n.getDataDirect(), ctx);
       }
-      this.oldValue = n.removeDirect(key);
+      Object oldValue = n.removeDirect(key);
       if (notifier.shouldNotifyOnNodeModified())
       {
          Map removedData = Collections.singletonMap(key, oldValue);
@@ -74,16 +70,6 @@
       return oldValue;
    }
 
-   public void rollback()
-   {
-      assertRollbackAllowed();
-      NodeSPI targetNode = dataContainer.peek(fqn, false, true);
-      if (oldValue != null)
-      {
-         targetNode.putDirect(key, oldValue);
-      }
-   }
-
    public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
    {
       return visitor.visitRemoveKeyCommand(ctx, this);
@@ -161,7 +147,6 @@
             ", dataVersion=" + dataVersion +
             ", globalTransaction=" + globalTransaction +
             ", key=" + key +
-            ", oldValue=" + oldValue +
             '}';
    }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -9,9 +9,6 @@
 import org.jboss.cache.optimistic.DataVersion;
 import org.jboss.cache.transaction.GlobalTransaction;
 
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * Implements functionality defined by {@link org.jboss.cache.CacheSPI#removeNode(org.jboss.cache.Fqn)}
  *
@@ -22,14 +19,13 @@
 {
    public static final int METHOD_ID = 5;
    public static final int VERSIONED_METHOD_ID = 40;
-   private static final Log log = LogFactory.getLog(RemoveNodeCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   protected static final Log log = LogFactory.getLog(RemoveNodeCommand.class);
+   protected static final boolean trace = log.isTraceEnabled();
 
    /*parameters*/
    private boolean skipSendingNodeEvents = false;
    protected Fqn parentFqn;
    protected NodeSPI targetNode;
-   protected Map originalData;
 
    public RemoveNodeCommand(GlobalTransaction globalTransaction, Fqn fqn)
    {
@@ -57,28 +53,13 @@
       }
       notifyBeforeRemove(targetNode, ctx);
 
-      NodeSPI parentNode = targetNode.getParent();
       boolean found = targetNode.isValid() && !targetNode.isDeleted();
       targetNode.markAsDeleted(true, true);
 
-      if (globalTransaction != null && found)
-      {
-         prepareForRollback(parentNode);
-      }
       notifyAfterRemove(ctx);
       return found;
    }
 
-   private void prepareForRollback(NodeSPI parentNode)
-   {
-      parentFqn = parentNode.getFqn();
-      Map targetData = targetNode.getDataDirect();
-      if (!targetData.isEmpty())
-      {
-         originalData = new HashMap(targetNode.getDataDirect());
-      }
-   }
-
    private void notifyBeforeRemove(NodeSPI n, InvocationContext ctx)
    {
       if (!skipSendingNodeEvents)
@@ -95,36 +76,6 @@
       }
    }
 
-   public void rollback()
-   {
-      assertRollbackAllowed();
-      if (targetNode != null)
-      {
-         Object childName = targetNode.getFqn().getLastElement();
-         if (trace)
-         {
-            log.trace("rollback(parent: " + parentFqn + ", child: " + childName + ", node=" + targetNode + ")");
-         }
-
-         if (parentFqn == null || childName == null)
-         {
-            log.error("parent fqn or childName or childNode was null");
-            return;
-         }
-         NodeSPI parentNode = dataContainer.peek(parentFqn);
-         if (parentNode == null)
-         {
-            log.warn("node " + parentFqn + " not found");
-            return;
-         }
-         parentNode.addChild(childName, targetNode);
-         targetNode.markAsDeleted(false, true);
-         targetNode.clearDataDirect();
-         if (originalData != null) targetNode.putAllDirect(originalData);
-         targetNode.setValid(true, true);
-      }
-   }
-
    public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
    {
       return visitor.visitRemoveNodeCommand(ctx, this);

Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/VersionedInvalidateCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/VersionedInvalidateCommand.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/VersionedInvalidateCommand.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -30,7 +30,7 @@
 public class VersionedInvalidateCommand extends InvalidateCommand implements VersionedDataCommand
 {
    private static final Log log = LogFactory.getLog(VersionedInvalidateCommand.class);
-   private static boolean trace = log.isTraceEnabled();
+   private static final boolean trace = log.isTraceEnabled();
 
    /*
      dependencies
@@ -178,9 +178,4 @@
       fqn = (Fqn) args[0];
       dataVersion = (DataVersion) args[1];
    }
-
-   public void rollback()
-   {
-      //no op
-   }
 }

Deleted: core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,528 +0,0 @@
-package org.jboss.cache.factories;
-
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DataContainer;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.RPCManager;
-import org.jboss.cache.buddyreplication.BuddyFqnTransformer;
-import org.jboss.cache.buddyreplication.BuddyGroup;
-import org.jboss.cache.buddyreplication.BuddyManager;
-import org.jboss.cache.commands.DataCommand;
-import org.jboss.cache.commands.ReplicableCommand;
-import org.jboss.cache.commands.ReversibleCommand;
-import org.jboss.cache.commands.read.ExistsCommand;
-import org.jboss.cache.commands.read.GetChildrenNamesCommand;
-import org.jboss.cache.commands.read.GetDataMapCommand;
-import org.jboss.cache.commands.read.GetKeyValueCommand;
-import org.jboss.cache.commands.read.GetKeysCommand;
-import org.jboss.cache.commands.read.GetNodeCommand;
-import org.jboss.cache.commands.read.GravitateDataCommand;
-import org.jboss.cache.commands.remote.AnnounceBuddyPoolNameCommand;
-import org.jboss.cache.commands.remote.AssignToBuddyGroupCommand;
-import org.jboss.cache.commands.remote.ClusteredGetCommand;
-import org.jboss.cache.commands.remote.DataGravitationCleanupCommand;
-import org.jboss.cache.commands.remote.RemoveFromBuddyGroupCommand;
-import org.jboss.cache.commands.remote.ReplicateCommand;
-import org.jboss.cache.commands.tx.CommitCommand;
-import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
-import org.jboss.cache.commands.tx.PrepareCommand;
-import org.jboss.cache.commands.tx.RollbackCommand;
-import org.jboss.cache.commands.write.*;
-import org.jboss.cache.config.Configuration;
-import org.jboss.cache.config.Configuration.NodeLockingScheme;
-import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.factories.annotations.NonVolatile;
-import org.jboss.cache.factories.annotations.Start;
-import org.jboss.cache.interceptors.InterceptorChain;
-import org.jboss.cache.notifications.Notifier;
-import org.jboss.cache.transaction.GlobalTransaction;
-import org.jboss.cache.transaction.TransactionTable;
-import org.jgroups.Address;
-
-import javax.transaction.TransactionManager;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Factory for all types of cache commands.
- * Here are some of the purposes of this class:
- * <pre>
- *   - not creating <code>CacheCommands</code> directly (i.e. through new usage) as this would reduce unit testability
- *   - reduce the coupling between commands and other components. e.g. considering a commands that needs to knwo whether
- *     locking type is optimistic, we will pass in a 'optimistic' boolean flag rather than entire Configuration object
- * </pre>
- *
- * @author Mircea.Markus at jboss.com
- * @since 2.2
- */
- at NonVolatile
-public class CommandsFactory
-{
-   private RPCManager rpcManager;
-   private DataContainer dataContainer;
-   private Notifier notifier;
-   private InterceptorChain invoker;
-   private BuddyManager buddyManager;
-   private TransactionTable transactionTable;
-   private CacheSPI cacheSpi;
-   private Configuration configuration;
-   private TransactionManager txManager;
-   private BuddyFqnTransformer buddyFqnTransformer;
-   private boolean suppressRollbacks;
-
-   public CommandsFactory()
-   {
-   }
-
-   @Inject
-   public void initialize(RPCManager rpc, DataContainer dataContainer, Notifier notifier, BuddyManager buddyManager,
-                          InterceptorChain invoker, TransactionTable transactionTable, CacheSPI cacheSpi,
-                          Configuration configuration, TransactionManager txManager, BuddyFqnTransformer buddyFqnTransformer)
-   {
-      this.rpcManager = rpc;
-      this.dataContainer = dataContainer;
-      this.notifier = notifier;
-      this.buddyManager = buddyManager;
-      this.invoker = invoker;
-      this.transactionTable = transactionTable;
-      this.cacheSpi = cacheSpi;
-      this.configuration = configuration;
-      this.txManager = txManager;
-      this.buddyFqnTransformer = buddyFqnTransformer;
-   }
-
-   @Start
-   public void start()
-   {
-      suppressRollbacks = configuration.getNodeLockingScheme() == NodeLockingScheme.MVCC;
-   }
-
-   public PutDataMapCommand buildPutDataMapCommand(GlobalTransaction gtx, Fqn fqn, Map data)
-   {
-      PutDataMapCommand cmd = new PutDataMapCommand(gtx, fqn, data);
-      cmd.initialize(notifier, dataContainer, suppressRollbacks);
-      return cmd;
-   }
-
-   public PutKeyValueCommand buildPutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
-   {
-      PutKeyValueCommand cmd = new PutKeyValueCommand(gtx, fqn, key, value);
-      cmd.initialize(notifier, dataContainer, suppressRollbacks);
-      return cmd;
-   }
-
-   public PutForExternalReadCommand buildPutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
-   {
-      PutForExternalReadCommand cmd = new PutForExternalReadCommand(gtx, fqn, key, value);
-      cmd.initialize(notifier, dataContainer, suppressRollbacks);
-      return cmd;
-   }
-
-   public ReplicateCommand buildReplicateCommand(ReplicableCommand command)
-   {
-      ReplicateCommand cmd = new ReplicateCommand(command);
-      cmd.initialize(invoker);
-      return cmd;
-   }
-
-   public ReplicateCommand buildReplicateCommand(List<ReplicableCommand> modifications)
-   {
-      ReplicateCommand cmd = new ReplicateCommand(modifications);
-      cmd.initialize(invoker);
-      return cmd;
-   }
-
-   public PrepareCommand buildPrepareCommand(GlobalTransaction gtx, ReversibleCommand command, boolean onePhaseCommit)
-   {
-      return buildPrepareCommand(gtx, Collections.singletonList(command), rpcManager.getLocalAddress(), onePhaseCommit);
-   }
-
-   public PrepareCommand buildPrepareCommand(GlobalTransaction gtx, List<ReversibleCommand> modifications, Address address, boolean onePhaseCommit)
-   {
-      return new PrepareCommand(gtx, modifications, address, onePhaseCommit);
-   }
-
-   public CommitCommand buildCommitCommand(GlobalTransaction gtx)
-   {
-      return new CommitCommand(gtx);
-   }
-
-   public DataGravitationCleanupCommand buildDataGravitationCleanupCommand(Fqn primaryFqn, Fqn backupFqn)
-   {
-      DataGravitationCleanupCommand command = new DataGravitationCleanupCommand(primaryFqn, backupFqn);
-      command.initialize(buddyManager, invoker, transactionTable, this, dataContainer, buddyFqnTransformer);
-      return command;
-   }
-
-   public GravitateDataCommand buildGravitateDataCommand(Fqn fqn, Boolean searchSubtrees)
-   {
-      GravitateDataCommand command = new GravitateDataCommand(fqn, searchSubtrees, rpcManager.getLocalAddress());
-      command.initialize(dataContainer, cacheSpi, buddyFqnTransformer);
-      return command;
-   }
-
-   public RemoveNodeCommand buildRemoveNodeCommand(GlobalTransaction gtx, Fqn fqn)
-   {
-      RemoveNodeCommand cmd = new RemoveNodeCommand(gtx, fqn);
-      cmd.initialize(notifier, dataContainer, suppressRollbacks);
-      return cmd;
-   }
-
-   public ClearDataCommand buildClearDataCommand(GlobalTransaction gtx, Fqn fqn)
-   {
-      ClearDataCommand cmd = new ClearDataCommand(gtx, fqn);
-      cmd.initialize(notifier, dataContainer, suppressRollbacks);
-      return cmd;
-   }
-
-   public EvictCommand buildEvictFqnCommand(Fqn fqn)
-   {
-      EvictCommand command = new EvictCommand(fqn);
-      command.initialize(notifier, dataContainer);
-      return command;
-   }
-
-   public InvalidateCommand buildInvalidateCommand(Fqn fqn)
-   {
-      if (configuration.getNodeLockingScheme().isVersionedScheme())
-      {
-         VersionedInvalidateCommand command = new VersionedInvalidateCommand(fqn);
-         command.initialize(txManager);
-         command.initialize(cacheSpi, dataContainer, notifier);
-         return command;
-      }
-      else
-      {
-         InvalidateCommand command = new InvalidateCommand(fqn);
-         command.initialize(cacheSpi, dataContainer, notifier);
-         return command;
-      }
-   }
-
-   public RemoveKeyCommand buildRemoveKeyCommand(GlobalTransaction tx, Fqn<?> fqn, Object key)
-   {
-      RemoveKeyCommand cmd = new RemoveKeyCommand(tx, fqn, key);
-      cmd.initialize(notifier, dataContainer, suppressRollbacks);
-      return cmd;
-   }
-
-   public GetDataMapCommand buildGetDataMapCommand(Fqn fqn)
-   {
-      GetDataMapCommand command = new GetDataMapCommand(fqn);
-      command.initialize(dataContainer);
-      return command;
-   }
-
-   public ExistsCommand buildExistsNodeCommand(Fqn fqn)
-   {
-      ExistsCommand command = new ExistsCommand(fqn);
-      command.initialize(dataContainer);
-      return command;
-   }
-
-   public GetKeyValueCommand buildGetKeyValueCommand(Fqn<?> fqn, Object key, boolean sendNodeEvent)
-   {
-      GetKeyValueCommand command = new GetKeyValueCommand(fqn, key, sendNodeEvent);
-      command.initialize(dataContainer, notifier);
-      return command;
-   }
-
-   public GetNodeCommand buildGetNodeCommand(Fqn fqn)
-   {
-      GetNodeCommand command = new GetNodeCommand(fqn);
-      command.initialize(dataContainer);
-      return command;
-   }
-
-   public GetKeysCommand buildGetKeysCommand(Fqn fqn)
-   {
-      GetKeysCommand command = new GetKeysCommand(fqn);
-      command.initialize(dataContainer);
-      return command;
-   }
-
-   public GetChildrenNamesCommand buildGetChildrenNamesCommand(Fqn fqn)
-   {
-      GetChildrenNamesCommand command = new GetChildrenNamesCommand(fqn);
-      command.initialize(dataContainer);
-      return command;
-   }
-
-   public MoveCommand buildMoveCommand(Fqn from, Fqn to)
-   {
-      MoveCommand cmd = new MoveCommand(from, to);
-      cmd.initialize(notifier, dataContainer, suppressRollbacks);
-      return cmd;
-   }
-
-   public RollbackCommand buildRollbackCommand(GlobalTransaction gtx)
-   {
-      return new RollbackCommand(gtx);
-   }
-
-   public OptimisticPrepareCommand buildOptimisticPrepareCommand(GlobalTransaction gtx, List<ReversibleCommand> modifications, Address address, boolean onePhaseCommit)
-   {
-      return new OptimisticPrepareCommand(gtx, modifications, address, onePhaseCommit);
-   }
-
-   public AnnounceBuddyPoolNameCommand buildAnnounceBuddyPoolNameCommand(Address address, String buddyPoolName)
-   {
-      AnnounceBuddyPoolNameCommand command = new AnnounceBuddyPoolNameCommand(address, buddyPoolName);
-      command.initialize(buddyManager);
-      return command;
-   }
-
-   public RemoveFromBuddyGroupCommand buildRemoveFromBuddyGroupCommand(String groupName)
-   {
-      RemoveFromBuddyGroupCommand command = new RemoveFromBuddyGroupCommand(groupName);
-      command.initialize(buddyManager);
-      return command;
-   }
-
-   public AssignToBuddyGroupCommand buildAssignToBuddyGroupCommand(BuddyGroup group, Map<Fqn, byte[]> state)
-   {
-      AssignToBuddyGroupCommand command = new AssignToBuddyGroupCommand(group, state);
-      command.initialize(buddyManager);
-      return command;
-   }
-
-   public ClusteredGetCommand buildClusteredGetCommand(Boolean searchBackupSubtrees, DataCommand dataCommand)
-   {
-      ClusteredGetCommand command = new ClusteredGetCommand(searchBackupSubtrees, dataCommand);
-      command.initialize(dataContainer, invoker);
-      return command;
-   }
-
-   public CreateNodeCommand buildCreateNodeCommand(Fqn fqn)
-   {
-      CreateNodeCommand command = new CreateNodeCommand(fqn, suppressRollbacks);
-      command.initialize(dataContainer);
-      return command;
-   }
-
-   /**
-    * Builds a cache command based on the ID passed in and an object array of parameters
-    *
-    * @param id         id of the command to build
-    * @param parameters parameters attached to the command
-    * @return a newly constructed cache command
-    */
-   public ReplicableCommand fromStream(int id, Object[] parameters)
-   {
-      ReplicableCommand command;
-      switch (id)
-      {
-         case ExistsCommand.METHOD_ID:
-         {
-            ExistsCommand result = new ExistsCommand();
-            result.initialize(dataContainer);
-            command = result;
-            break;
-         }
-         case GetChildrenNamesCommand.METHOD_ID:
-         {
-            GetChildrenNamesCommand returnValue = new GetChildrenNamesCommand();
-            returnValue.initialize(dataContainer);
-            command = returnValue;
-            break;
-         }
-         case GetDataMapCommand.METHOD_ID:
-         {
-            GetDataMapCommand returnValue = new GetDataMapCommand();
-            returnValue.initialize(dataContainer);
-            command = returnValue;
-            break;
-         }
-         case GetKeysCommand.METHOD_ID:
-         {
-            GetKeysCommand returnValue = new GetKeysCommand();
-            returnValue.initialize(dataContainer);
-            command = returnValue;
-            break;
-         }
-         case GetKeyValueCommand.METHOD_ID:
-         {
-            GetKeyValueCommand returnValue = new GetKeyValueCommand();
-            returnValue.initialize(dataContainer, notifier);
-            command = returnValue;
-            break;
-         }
-         case GetNodeCommand.METHOD_ID:
-         {
-            GetNodeCommand returnValue = new GetNodeCommand();
-            returnValue.initialize(dataContainer);
-            command = returnValue;
-            break;
-         }
-         case MoveCommand.METHOD_ID:
-         {
-            MoveCommand returnValue = new MoveCommand();
-            returnValue.initialize(notifier, dataContainer, suppressRollbacks);
-            command = returnValue;
-            break;
-         }
-         case PutDataMapCommand.METHOD_ID:
-         case PutDataMapCommand.ERASE_METHOD_ID:
-         case PutDataMapCommand.ERASE_VERSIONED_METHOD_ID:
-         case PutDataMapCommand.VERSIONED_METHOD_ID:
-         {
-            PutDataMapCommand returnValue = new PutDataMapCommand();
-            returnValue.initialize(notifier, dataContainer, suppressRollbacks);
-            command = returnValue;
-            break;
-         }
-         case PutKeyValueCommand.METHOD_ID:
-         case PutKeyValueCommand.VERSIONED_METHOD_ID:
-         {
-            PutKeyValueCommand returnValue = new PutKeyValueCommand();
-            returnValue.initialize(notifier, dataContainer, suppressRollbacks);
-            command = returnValue;
-            break;
-         }
-         case PutForExternalReadCommand.METHOD_ID:
-         case PutForExternalReadCommand.VERSIONED_METHOD_ID:
-         {
-            PutForExternalReadCommand returnValue = new PutForExternalReadCommand();
-            returnValue.initialize(notifier, dataContainer, suppressRollbacks);
-            command = returnValue;
-            break;
-         }
-         case ClearDataCommand.METHOD_ID:
-         case ClearDataCommand.VERSIONED_METHOD_ID:
-         {
-            ClearDataCommand returnValue = new ClearDataCommand();
-            returnValue.initialize(notifier, dataContainer, suppressRollbacks);
-            command = returnValue;
-            break;
-         }
-         case RemoveKeyCommand.METHOD_ID:
-         case RemoveKeyCommand.VERSIONED_METHOD_ID:
-         {
-            RemoveKeyCommand returnValue = new RemoveKeyCommand();
-            returnValue.initialize(notifier, dataContainer, suppressRollbacks);
-            command = returnValue;
-            break;
-         }
-
-         case RemoveNodeCommand.METHOD_ID:
-         case RemoveNodeCommand.VERSIONED_METHOD_ID:
-         {
-            RemoveNodeCommand returnValue = new RemoveNodeCommand();
-            returnValue.initialize(notifier, dataContainer, suppressRollbacks);
-            command = returnValue;
-            break;
-         }
-         case CreateNodeCommand.METHOD_ID:
-         {
-            CreateNodeCommand returnValue = new CreateNodeCommand(null, suppressRollbacks);
-            returnValue.initialize(dataContainer);
-            command = returnValue;
-            break;
-         }
-         // --- transactional method calls
-
-         case PrepareCommand.METHOD_ID:
-         {
-            command = new PrepareCommand();
-            break;
-         }
-
-         case OptimisticPrepareCommand.METHOD_ID:
-         {
-            command = new OptimisticPrepareCommand();
-            break;
-         }
-
-         case CommitCommand.METHOD_ID:
-         {
-            command = new CommitCommand();
-            break;
-         }
-
-         case RollbackCommand.METHOD_ID:
-         {
-            command = new RollbackCommand();
-            break;
-         }
-
-         // --- replicate methods
-         case ReplicateCommand.MULTIPLE_METHOD_ID:
-         case ReplicateCommand.SINGLE_METHOD_ID:
-         {
-            ReplicateCommand returnValue = new ReplicateCommand();
-            returnValue.initialize(invoker);
-            command = returnValue;
-            break;
-         }
-
-         case InvalidateCommand.METHOD_ID:
-         {
-            if (configuration.getNodeLockingScheme().isVersionedScheme())
-            {
-               VersionedInvalidateCommand returnValue = new VersionedInvalidateCommand();
-               returnValue.initialize(txManager);
-               returnValue.initialize(cacheSpi, dataContainer, notifier);
-               command = returnValue;
-            }
-            else
-            {
-               InvalidateCommand returnValue = new InvalidateCommand();
-               returnValue.initialize(cacheSpi, dataContainer, notifier);
-               command = returnValue;
-            }
-            break;
-         }
-
-         case ClusteredGetCommand.METHOD_ID:
-         {
-            ClusteredGetCommand returnValue = new ClusteredGetCommand();
-            returnValue.initialize(dataContainer, invoker);
-            command = returnValue;
-            break;
-         }
-         // ---- Buddy replication - group organisation commands
-         case AnnounceBuddyPoolNameCommand.METHOD_ID:
-         {
-            AnnounceBuddyPoolNameCommand returnValue = new AnnounceBuddyPoolNameCommand();
-            returnValue.initialize(buddyManager);
-            command = returnValue;
-            break;
-         }
-         case AssignToBuddyGroupCommand.METHOD_ID:
-         {
-            AssignToBuddyGroupCommand returnValue = new AssignToBuddyGroupCommand();
-            returnValue.initialize(buddyManager);
-            command = returnValue;
-            break;
-         }
-         case RemoveFromBuddyGroupCommand.METHOD_ID:
-         {
-            RemoveFromBuddyGroupCommand returnValue = new RemoveFromBuddyGroupCommand();
-            returnValue.initialize(buddyManager);
-            command = returnValue;
-            break;
-         }
-         case DataGravitationCleanupCommand.METHOD_ID:
-         {
-            DataGravitationCleanupCommand returnValue = new DataGravitationCleanupCommand();
-            returnValue.initialize(buddyManager, invoker, transactionTable, this, dataContainer, buddyFqnTransformer);
-            command = returnValue;
-            break;
-         }
-         case GravitateDataCommand.METHOD_ID:
-         {
-            GravitateDataCommand returnValue = new GravitateDataCommand(rpcManager.getLocalAddress());
-            returnValue.initialize(dataContainer, cacheSpi, buddyFqnTransformer);
-            command = returnValue;
-            break;
-         }
-         default:
-            throw new CacheException("Unknown command id " + id + "!");
-      }
-
-      command.setParameters(id, parameters);
-      return command;
-   }
-}

Added: core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,115 @@
+package org.jboss.cache.factories;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.buddyreplication.BuddyGroup;
+import org.jboss.cache.commands.DataCommand;
+import org.jboss.cache.commands.ReplicableCommand;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.commands.read.ExistsCommand;
+import org.jboss.cache.commands.read.GetChildrenNamesCommand;
+import org.jboss.cache.commands.read.GetDataMapCommand;
+import org.jboss.cache.commands.read.GetKeyValueCommand;
+import org.jboss.cache.commands.read.GetKeysCommand;
+import org.jboss.cache.commands.read.GetNodeCommand;
+import org.jboss.cache.commands.read.GravitateDataCommand;
+import org.jboss.cache.commands.remote.AnnounceBuddyPoolNameCommand;
+import org.jboss.cache.commands.remote.AssignToBuddyGroupCommand;
+import org.jboss.cache.commands.remote.ClusteredGetCommand;
+import org.jboss.cache.commands.remote.DataGravitationCleanupCommand;
+import org.jboss.cache.commands.remote.RemoveFromBuddyGroupCommand;
+import org.jboss.cache.commands.remote.ReplicateCommand;
+import org.jboss.cache.commands.tx.CommitCommand;
+import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
+import org.jboss.cache.commands.tx.PrepareCommand;
+import org.jboss.cache.commands.tx.RollbackCommand;
+import org.jboss.cache.commands.write.*;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jgroups.Address;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Factory for all types of cache commands.
+ * Here are some of the purposes of this class:
+ * <pre>
+ *   - not creating <code>CacheCommands</code> directly (i.e. through new usage) as this would reduce unit testability
+ *   - reduce the coupling between commands and other components. e.g. considering a commands that needs to knwo whether
+ *     locking type is optimistic, we will pass in a 'optimistic' boolean flag rather than entire Configuration object
+ * </pre>
+ * <p/>
+ * <b>Note:</b> As of 3.0, this is now an interface.
+ * <p/>
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+public interface CommandsFactory
+{
+   PutDataMapCommand buildPutDataMapCommand(GlobalTransaction gtx, Fqn fqn, Map data);
+
+   PutKeyValueCommand buildPutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value);
+
+   PutForExternalReadCommand buildPutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value);
+
+   ReplicateCommand buildReplicateCommand(ReplicableCommand command);
+
+   ReplicateCommand buildReplicateCommand(List<ReplicableCommand> modifications);
+
+   PrepareCommand buildPrepareCommand(GlobalTransaction gtx, WriteCommand command, boolean onePhaseCommit);
+
+   PrepareCommand buildPrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, Address address, boolean onePhaseCommit);
+
+   CommitCommand buildCommitCommand(GlobalTransaction gtx);
+
+   DataGravitationCleanupCommand buildDataGravitationCleanupCommand(Fqn primaryFqn, Fqn backupFqn);
+
+   GravitateDataCommand buildGravitateDataCommand(Fqn fqn, Boolean searchSubtrees);
+
+   RemoveNodeCommand buildRemoveNodeCommand(GlobalTransaction gtx, Fqn fqn);
+
+   ClearDataCommand buildClearDataCommand(GlobalTransaction gtx, Fqn fqn);
+
+   EvictCommand buildEvictFqnCommand(Fqn fqn);
+
+   InvalidateCommand buildInvalidateCommand(Fqn fqn);
+
+   RemoveKeyCommand buildRemoveKeyCommand(GlobalTransaction tx, Fqn<?> fqn, Object key);
+
+   GetDataMapCommand buildGetDataMapCommand(Fqn fqn);
+
+   ExistsCommand buildExistsNodeCommand(Fqn fqn);
+
+   GetKeyValueCommand buildGetKeyValueCommand(Fqn<?> fqn, Object key, boolean sendNodeEvent);
+
+   GetNodeCommand buildGetNodeCommand(Fqn fqn);
+
+   GetKeysCommand buildGetKeysCommand(Fqn fqn);
+
+   GetChildrenNamesCommand buildGetChildrenNamesCommand(Fqn fqn);
+
+   MoveCommand buildMoveCommand(Fqn from, Fqn to);
+
+   RollbackCommand buildRollbackCommand(GlobalTransaction gtx);
+
+   OptimisticPrepareCommand buildOptimisticPrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, Address address, boolean onePhaseCommit);
+
+   AnnounceBuddyPoolNameCommand buildAnnounceBuddyPoolNameCommand(Address address, String buddyPoolName);
+
+   RemoveFromBuddyGroupCommand buildRemoveFromBuddyGroupCommand(String groupName);
+
+   AssignToBuddyGroupCommand buildAssignToBuddyGroupCommand(BuddyGroup group, Map<Fqn, byte[]> state);
+
+   ClusteredGetCommand buildClusteredGetCommand(Boolean searchBackupSubtrees, DataCommand dataCommand);
+
+   CreateNodeCommand buildCreateNodeCommand(Fqn fqn);
+
+   /**
+    * Builds a cache command based on the ID passed in and an object array of parameters
+    *
+    * @param id         id of the command to build
+    * @param parameters parameters attached to the command
+    * @return a newly constructed cache command
+    */
+   ReplicableCommand fromStream(int id, Object[] parameters);
+}

Copied: core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactoryImpl.java (from rev 6106, core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactory.java)
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactoryImpl.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/factories/CommandsFactoryImpl.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,503 @@
+package org.jboss.cache.factories;
+
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DataContainer;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.RPCManager;
+import org.jboss.cache.buddyreplication.BuddyFqnTransformer;
+import org.jboss.cache.buddyreplication.BuddyGroup;
+import org.jboss.cache.buddyreplication.BuddyManager;
+import org.jboss.cache.commands.DataCommand;
+import org.jboss.cache.commands.ReplicableCommand;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.commands.read.ExistsCommand;
+import org.jboss.cache.commands.read.GetChildrenNamesCommand;
+import org.jboss.cache.commands.read.GetDataMapCommand;
+import org.jboss.cache.commands.read.GetKeyValueCommand;
+import org.jboss.cache.commands.read.GetKeysCommand;
+import org.jboss.cache.commands.read.GetNodeCommand;
+import org.jboss.cache.commands.read.GravitateDataCommand;
+import org.jboss.cache.commands.remote.AnnounceBuddyPoolNameCommand;
+import org.jboss.cache.commands.remote.AssignToBuddyGroupCommand;
+import org.jboss.cache.commands.remote.ClusteredGetCommand;
+import org.jboss.cache.commands.remote.DataGravitationCleanupCommand;
+import org.jboss.cache.commands.remote.RemoveFromBuddyGroupCommand;
+import org.jboss.cache.commands.remote.ReplicateCommand;
+import org.jboss.cache.commands.tx.CommitCommand;
+import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
+import org.jboss.cache.commands.tx.PrepareCommand;
+import org.jboss.cache.commands.tx.RollbackCommand;
+import org.jboss.cache.commands.write.*;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.NonVolatile;
+import org.jboss.cache.interceptors.InterceptorChain;
+import org.jboss.cache.notifications.Notifier;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jboss.cache.transaction.TransactionTable;
+import org.jgroups.Address;
+
+import javax.transaction.TransactionManager;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This is the implementation to use for most commands and most locking schemes.
+ */
+ at NonVolatile
+public class CommandsFactoryImpl implements CommandsFactory
+{
+   protected RPCManager rpcManager;
+   protected DataContainer dataContainer;
+   protected Notifier notifier;
+   protected InterceptorChain invoker;
+   protected BuddyManager buddyManager;
+   protected TransactionTable transactionTable;
+   protected CacheSPI cacheSpi;
+   protected Configuration configuration;
+   protected TransactionManager txManager;
+   protected BuddyFqnTransformer buddyFqnTransformer;
+
+   public CommandsFactoryImpl()
+   {
+   }
+
+   @Inject
+   public void initialize(RPCManager rpc, DataContainer dataContainer, Notifier notifier, BuddyManager buddyManager,
+                          InterceptorChain invoker, TransactionTable transactionTable, CacheSPI cacheSpi,
+                          Configuration configuration, TransactionManager txManager, BuddyFqnTransformer buddyFqnTransformer)
+   {
+      this.rpcManager = rpc;
+      this.dataContainer = dataContainer;
+      this.notifier = notifier;
+      this.buddyManager = buddyManager;
+      this.invoker = invoker;
+      this.transactionTable = transactionTable;
+      this.cacheSpi = cacheSpi;
+      this.configuration = configuration;
+      this.txManager = txManager;
+      this.buddyFqnTransformer = buddyFqnTransformer;
+   }
+
+   public PutDataMapCommand buildPutDataMapCommand(GlobalTransaction gtx, Fqn fqn, Map data)
+   {
+      PutDataMapCommand cmd = new PutDataMapCommand(gtx, fqn, data);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   public PutKeyValueCommand buildPutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
+   {
+      PutKeyValueCommand cmd = new PutKeyValueCommand(gtx, fqn, key, value);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   public PutForExternalReadCommand buildPutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
+   {
+      PutForExternalReadCommand cmd = new PutForExternalReadCommand(gtx, fqn, key, value);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   public ReplicateCommand buildReplicateCommand(ReplicableCommand command)
+   {
+      ReplicateCommand cmd = new ReplicateCommand(command);
+      cmd.initialize(invoker);
+      return cmd;
+   }
+
+   public ReplicateCommand buildReplicateCommand(List<ReplicableCommand> modifications)
+   {
+      ReplicateCommand cmd = new ReplicateCommand(modifications);
+      cmd.initialize(invoker);
+      return cmd;
+   }
+
+   public PrepareCommand buildPrepareCommand(GlobalTransaction gtx, WriteCommand command, boolean onePhaseCommit)
+   {
+      return buildPrepareCommand(gtx, Collections.singletonList(command), rpcManager.getLocalAddress(), onePhaseCommit);
+   }
+
+   public PrepareCommand buildPrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, Address address, boolean onePhaseCommit)
+   {
+      return new PrepareCommand(gtx, modifications, address, onePhaseCommit);
+   }
+
+   public CommitCommand buildCommitCommand(GlobalTransaction gtx)
+   {
+      return new CommitCommand(gtx);
+   }
+
+   public DataGravitationCleanupCommand buildDataGravitationCleanupCommand(Fqn primaryFqn, Fqn backupFqn)
+   {
+      DataGravitationCleanupCommand command = new DataGravitationCleanupCommand(primaryFqn, backupFqn);
+      command.initialize(buddyManager, invoker, transactionTable, this, dataContainer, buddyFqnTransformer);
+      return command;
+   }
+
+   public GravitateDataCommand buildGravitateDataCommand(Fqn fqn, Boolean searchSubtrees)
+   {
+      GravitateDataCommand command = new GravitateDataCommand(fqn, searchSubtrees, rpcManager.getLocalAddress());
+      command.initialize(dataContainer, cacheSpi, buddyFqnTransformer);
+      return command;
+   }
+
+   public EvictCommand buildEvictFqnCommand(Fqn fqn)
+   {
+      EvictCommand command = new EvictCommand(fqn);
+      command.initialize(notifier, dataContainer);
+      return command;
+   }
+
+   public InvalidateCommand buildInvalidateCommand(Fqn fqn)
+   {
+      if (configuration.getNodeLockingScheme().isVersionedScheme())
+      {
+         VersionedInvalidateCommand command = new VersionedInvalidateCommand(fqn);
+         command.initialize(txManager);
+         command.initialize(cacheSpi, dataContainer, notifier);
+         return command;
+      }
+      else
+      {
+         InvalidateCommand command = new InvalidateCommand(fqn);
+         command.initialize(cacheSpi, dataContainer, notifier);
+         return command;
+      }
+   }
+
+   public GetDataMapCommand buildGetDataMapCommand(Fqn fqn)
+   {
+      GetDataMapCommand command = new GetDataMapCommand(fqn);
+      command.initialize(dataContainer);
+      return command;
+   }
+
+   public ExistsCommand buildExistsNodeCommand(Fqn fqn)
+   {
+      ExistsCommand command = new ExistsCommand(fqn);
+      command.initialize(dataContainer);
+      return command;
+   }
+
+   public GetKeyValueCommand buildGetKeyValueCommand(Fqn<?> fqn, Object key, boolean sendNodeEvent)
+   {
+      GetKeyValueCommand command = new GetKeyValueCommand(fqn, key, sendNodeEvent);
+      command.initialize(dataContainer, notifier);
+      return command;
+   }
+
+   public GetNodeCommand buildGetNodeCommand(Fqn fqn)
+   {
+      GetNodeCommand command = new GetNodeCommand(fqn);
+      command.initialize(dataContainer);
+      return command;
+   }
+
+   public GetKeysCommand buildGetKeysCommand(Fqn fqn)
+   {
+      GetKeysCommand command = new GetKeysCommand(fqn);
+      command.initialize(dataContainer);
+      return command;
+   }
+
+   public GetChildrenNamesCommand buildGetChildrenNamesCommand(Fqn fqn)
+   {
+      GetChildrenNamesCommand command = new GetChildrenNamesCommand(fqn);
+      command.initialize(dataContainer);
+      return command;
+   }
+
+   public RollbackCommand buildRollbackCommand(GlobalTransaction gtx)
+   {
+      return new RollbackCommand(gtx);
+   }
+
+   public OptimisticPrepareCommand buildOptimisticPrepareCommand(GlobalTransaction gtx, List<WriteCommand> modifications, Address address, boolean onePhaseCommit)
+   {
+      return new OptimisticPrepareCommand(gtx, modifications, address, onePhaseCommit);
+   }
+
+   public AnnounceBuddyPoolNameCommand buildAnnounceBuddyPoolNameCommand(Address address, String buddyPoolName)
+   {
+      AnnounceBuddyPoolNameCommand command = new AnnounceBuddyPoolNameCommand(address, buddyPoolName);
+      command.initialize(buddyManager);
+      return command;
+   }
+
+   public RemoveFromBuddyGroupCommand buildRemoveFromBuddyGroupCommand(String groupName)
+   {
+      RemoveFromBuddyGroupCommand command = new RemoveFromBuddyGroupCommand(groupName);
+      command.initialize(buddyManager);
+      return command;
+   }
+
+   public AssignToBuddyGroupCommand buildAssignToBuddyGroupCommand(BuddyGroup group, Map<Fqn, byte[]> state)
+   {
+      AssignToBuddyGroupCommand command = new AssignToBuddyGroupCommand(group, state);
+      command.initialize(buddyManager);
+      return command;
+   }
+
+   public ClusteredGetCommand buildClusteredGetCommand(Boolean searchBackupSubtrees, DataCommand dataCommand)
+   {
+      ClusteredGetCommand command = new ClusteredGetCommand(searchBackupSubtrees, dataCommand);
+      command.initialize(dataContainer, invoker);
+      return command;
+   }
+
+   public RemoveNodeCommand buildRemoveNodeCommand(GlobalTransaction gtx, Fqn fqn)
+   {
+      RemoveNodeCommand cmd = new RemoveNodeCommand(gtx, fqn);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   public ClearDataCommand buildClearDataCommand(GlobalTransaction gtx, Fqn fqn)
+   {
+      ClearDataCommand cmd = new ClearDataCommand(gtx, fqn);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   public RemoveKeyCommand buildRemoveKeyCommand(GlobalTransaction tx, Fqn<?> fqn, Object key)
+   {
+      RemoveKeyCommand cmd = new RemoveKeyCommand(tx, fqn, key);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   public MoveCommand buildMoveCommand(Fqn from, Fqn to)
+   {
+      MoveCommand cmd = new MoveCommand(from, to);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   public CreateNodeCommand buildCreateNodeCommand(Fqn fqn)
+   {
+      CreateNodeCommand command = new CreateNodeCommand(fqn);
+      command.initialize(dataContainer);
+      return command;
+   }
+
+   public ReplicableCommand fromStream(int id, Object[] parameters)
+   {
+      ReplicableCommand command;
+      switch (id)
+      {
+         case ExistsCommand.METHOD_ID:
+         {
+            ExistsCommand result = new ExistsCommand();
+            result.initialize(dataContainer);
+            command = result;
+            break;
+         }
+         case GetChildrenNamesCommand.METHOD_ID:
+         {
+            GetChildrenNamesCommand returnValue = new GetChildrenNamesCommand();
+            returnValue.initialize(dataContainer);
+            command = returnValue;
+            break;
+         }
+         case GetDataMapCommand.METHOD_ID:
+         {
+            GetDataMapCommand returnValue = new GetDataMapCommand();
+            returnValue.initialize(dataContainer);
+            command = returnValue;
+            break;
+         }
+         case GetKeysCommand.METHOD_ID:
+         {
+            GetKeysCommand returnValue = new GetKeysCommand();
+            returnValue.initialize(dataContainer);
+            command = returnValue;
+            break;
+         }
+         case GetKeyValueCommand.METHOD_ID:
+         {
+            GetKeyValueCommand returnValue = new GetKeyValueCommand();
+            returnValue.initialize(dataContainer, notifier);
+            command = returnValue;
+            break;
+         }
+         case GetNodeCommand.METHOD_ID:
+         {
+            GetNodeCommand returnValue = new GetNodeCommand();
+            returnValue.initialize(dataContainer);
+            command = returnValue;
+            break;
+         }
+         case MoveCommand.METHOD_ID:
+         {
+            MoveCommand returnValue = new MoveCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case PutDataMapCommand.METHOD_ID:
+         case PutDataMapCommand.ERASE_METHOD_ID:
+         case PutDataMapCommand.ERASE_VERSIONED_METHOD_ID:
+         case PutDataMapCommand.VERSIONED_METHOD_ID:
+         {
+            PutDataMapCommand returnValue = new PutDataMapCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case PutKeyValueCommand.METHOD_ID:
+         case PutKeyValueCommand.VERSIONED_METHOD_ID:
+         {
+            PutKeyValueCommand returnValue = new PutKeyValueCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case PutForExternalReadCommand.METHOD_ID:
+         case PutForExternalReadCommand.VERSIONED_METHOD_ID:
+         {
+            PutForExternalReadCommand returnValue = new PutForExternalReadCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case ClearDataCommand.METHOD_ID:
+         case ClearDataCommand.VERSIONED_METHOD_ID:
+         {
+            ClearDataCommand returnValue = new ClearDataCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case RemoveKeyCommand.METHOD_ID:
+         case RemoveKeyCommand.VERSIONED_METHOD_ID:
+         {
+            RemoveKeyCommand returnValue = new RemoveKeyCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+
+         case RemoveNodeCommand.METHOD_ID:
+         case RemoveNodeCommand.VERSIONED_METHOD_ID:
+         {
+            RemoveNodeCommand returnValue = new RemoveNodeCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case CreateNodeCommand.METHOD_ID:
+         {
+            CreateNodeCommand returnValue = new CreateNodeCommand(null);
+            returnValue.initialize(dataContainer);
+            command = returnValue;
+            break;
+         }
+         // --- transactional method calls
+
+         case PrepareCommand.METHOD_ID:
+         {
+            command = new PrepareCommand();
+            break;
+         }
+
+         case OptimisticPrepareCommand.METHOD_ID:
+         {
+            command = new OptimisticPrepareCommand();
+            break;
+         }
+
+         case CommitCommand.METHOD_ID:
+         {
+            command = new CommitCommand();
+            break;
+         }
+
+         case RollbackCommand.METHOD_ID:
+         {
+            command = new RollbackCommand();
+            break;
+         }
+
+         // --- replicate methods
+         case ReplicateCommand.MULTIPLE_METHOD_ID:
+         case ReplicateCommand.SINGLE_METHOD_ID:
+         {
+            ReplicateCommand returnValue = new ReplicateCommand();
+            returnValue.initialize(invoker);
+            command = returnValue;
+            break;
+         }
+
+         case InvalidateCommand.METHOD_ID:
+         {
+            if (configuration.getNodeLockingScheme().isVersionedScheme())
+            {
+               VersionedInvalidateCommand returnValue = new VersionedInvalidateCommand();
+               returnValue.initialize(txManager);
+               returnValue.initialize(cacheSpi, dataContainer, notifier);
+               command = returnValue;
+            }
+            else
+            {
+               InvalidateCommand returnValue = new InvalidateCommand();
+               returnValue.initialize(cacheSpi, dataContainer, notifier);
+               command = returnValue;
+            }
+            break;
+         }
+
+         case ClusteredGetCommand.METHOD_ID:
+         {
+            ClusteredGetCommand returnValue = new ClusteredGetCommand();
+            returnValue.initialize(dataContainer, invoker);
+            command = returnValue;
+            break;
+         }
+         // ---- Buddy replication - group organisation commands
+         case AnnounceBuddyPoolNameCommand.METHOD_ID:
+         {
+            AnnounceBuddyPoolNameCommand returnValue = new AnnounceBuddyPoolNameCommand();
+            returnValue.initialize(buddyManager);
+            command = returnValue;
+            break;
+         }
+         case AssignToBuddyGroupCommand.METHOD_ID:
+         {
+            AssignToBuddyGroupCommand returnValue = new AssignToBuddyGroupCommand();
+            returnValue.initialize(buddyManager);
+            command = returnValue;
+            break;
+         }
+         case RemoveFromBuddyGroupCommand.METHOD_ID:
+         {
+            RemoveFromBuddyGroupCommand returnValue = new RemoveFromBuddyGroupCommand();
+            returnValue.initialize(buddyManager);
+            command = returnValue;
+            break;
+         }
+         case DataGravitationCleanupCommand.METHOD_ID:
+         {
+            DataGravitationCleanupCommand returnValue = new DataGravitationCleanupCommand();
+            returnValue.initialize(buddyManager, invoker, transactionTable, this, dataContainer, buddyFqnTransformer);
+            command = returnValue;
+            break;
+         }
+         case GravitateDataCommand.METHOD_ID:
+         {
+            GravitateDataCommand returnValue = new GravitateDataCommand(rpcManager.getLocalAddress());
+            returnValue.initialize(dataContainer, cacheSpi, buddyFqnTransformer);
+            command = returnValue;
+            break;
+         }
+         default:
+            throw new CacheException("Unknown command id " + id + "!");
+      }
+
+      command.setParameters(id, parameters);
+      return command;
+   }
+}

Added: core/trunk/src/main/java/org/jboss/cache/factories/CommandsMetaFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/CommandsMetaFactory.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/factories/CommandsMetaFactory.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,23 @@
+package org.jboss.cache.factories;
+
+import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.factories.annotations.DefaultFactoryFor;
+
+/**
+ * COnstructs commands factory
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+ at DefaultFactoryFor(classes = CommandsFactory.class)
+public class CommandsMetaFactory extends ComponentFactory
+{
+   @SuppressWarnings("unchecked")
+   protected <T> T construct(Class<T> componentType)
+   {
+      if (configuration.getNodeLockingScheme() == NodeLockingScheme.PESSIMISTIC)
+         return (T) new PessimisticCommandsFactoryImpl();
+      else
+         return (T) new CommandsFactoryImpl();
+   }
+}

Modified: core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -175,6 +175,7 @@
       s.add(ReplicationQueueFactory.class);
       s.add(LockManagerFactory.class);
       s.add(ContextMetaFactory.class);
+      s.add(CommandsMetaFactory.class);
       return s;
    }
 

Modified: core/trunk/src/main/java/org/jboss/cache/factories/EmptyConstructorFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/EmptyConstructorFactory.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/factories/EmptyConstructorFactory.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -24,7 +24,7 @@
  */
 @DefaultFactoryFor(classes = {StateTransferManager.class, RegionManager.class, Notifier.class,
       ChannelMessageListener.class, CacheLoaderManager.class, Marshaller.class, InvocationContextContainer.class,
-      CacheInvocationDelegate.class, TransactionTable.class, DataContainer.class, CommandsFactory.class,
+      CacheInvocationDelegate.class, TransactionTable.class, DataContainer.class,
       LockStrategyFactory.class, BuddyFqnTransformer.class})
 public class EmptyConstructorFactory extends ComponentFactory
 {

Added: core/trunk/src/main/java/org/jboss/cache/factories/PessimisticCommandsFactoryImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/PessimisticCommandsFactoryImpl.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/factories/PessimisticCommandsFactoryImpl.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,184 @@
+package org.jboss.cache.factories;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.commands.ReplicableCommand;
+import org.jboss.cache.commands.pessimistic.write.PessClearDataCommand;
+import org.jboss.cache.commands.pessimistic.write.PessCreateNodeCommand;
+import org.jboss.cache.commands.pessimistic.write.PessMoveCommand;
+import org.jboss.cache.commands.pessimistic.write.PessPutDataMapCommand;
+import org.jboss.cache.commands.pessimistic.write.PessPutForExternalReadCommand;
+import org.jboss.cache.commands.pessimistic.write.PessPutKeyValueCommand;
+import org.jboss.cache.commands.pessimistic.write.PessRemoveKeyCommand;
+import org.jboss.cache.commands.pessimistic.write.PessRemoveNodeCommand;
+import org.jboss.cache.commands.write.ClearDataCommand;
+import org.jboss.cache.commands.write.CreateNodeCommand;
+import org.jboss.cache.commands.write.MoveCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutForExternalReadCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
+import org.jboss.cache.factories.annotations.NonVolatile;
+import org.jboss.cache.transaction.GlobalTransaction;
+
+import java.util.Map;
+
+/**
+ * This specific implementation of {@link org.jboss.cache.factories.CommandsFactory} specifically creates
+ * pessimistic commands where appropriate, with the ability to roll back.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @see org.jboss.cache.commands.pessimistic.ReversibleCommand
+ * @since 3.0
+ */
+ at NonVolatile
+public class PessimisticCommandsFactoryImpl extends CommandsFactoryImpl
+{
+   @Override
+   public PutDataMapCommand buildPutDataMapCommand(GlobalTransaction gtx, Fqn fqn, Map data)
+   {
+      PutDataMapCommand cmd = new PessPutDataMapCommand(gtx, fqn, data);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   @Override
+   public PutKeyValueCommand buildPutKeyValueCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
+   {
+      PutKeyValueCommand cmd = new PessPutKeyValueCommand(gtx, fqn, key, value);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   @Override
+   public PutForExternalReadCommand buildPutForExternalReadCommand(GlobalTransaction gtx, Fqn fqn, Object key, Object value)
+   {
+      PutForExternalReadCommand cmd = new PessPutForExternalReadCommand(gtx, fqn, key, value);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   @Override
+   public RemoveNodeCommand buildRemoveNodeCommand(GlobalTransaction gtx, Fqn fqn)
+   {
+      RemoveNodeCommand cmd = new PessRemoveNodeCommand(gtx, fqn);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   @Override
+   public ClearDataCommand buildClearDataCommand(GlobalTransaction gtx, Fqn fqn)
+   {
+      ClearDataCommand cmd = new PessClearDataCommand(gtx, fqn);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   @Override
+   public RemoveKeyCommand buildRemoveKeyCommand(GlobalTransaction tx, Fqn<?> fqn, Object key)
+   {
+      RemoveKeyCommand cmd = new PessRemoveKeyCommand(tx, fqn, key);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   @Override
+   public MoveCommand buildMoveCommand(Fqn from, Fqn to)
+   {
+      MoveCommand cmd = new PessMoveCommand(from, to);
+      cmd.initialize(notifier, dataContainer);
+      return cmd;
+   }
+
+   @Override
+   public CreateNodeCommand buildCreateNodeCommand(Fqn fqn)
+   {
+      CreateNodeCommand command = new PessCreateNodeCommand(fqn);
+      command.initialize(dataContainer);
+      return command;
+   }
+
+   @Override
+   public ReplicableCommand fromStream(int id, Object[] parameters)
+   {
+      ReplicableCommand command;
+      boolean skipSetParams = false;
+      switch (id)
+      {
+         case MoveCommand.METHOD_ID:
+         {
+            MoveCommand returnValue = new PessMoveCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case PutDataMapCommand.METHOD_ID:
+         case PutDataMapCommand.ERASE_METHOD_ID:
+         case PutDataMapCommand.ERASE_VERSIONED_METHOD_ID:
+         case PutDataMapCommand.VERSIONED_METHOD_ID:
+         {
+            PutDataMapCommand returnValue = new PessPutDataMapCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case PutKeyValueCommand.METHOD_ID:
+         case PutKeyValueCommand.VERSIONED_METHOD_ID:
+         {
+            PutKeyValueCommand returnValue = new PessPutKeyValueCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case PutForExternalReadCommand.METHOD_ID:
+         case PutForExternalReadCommand.VERSIONED_METHOD_ID:
+         {
+            PutForExternalReadCommand returnValue = new PessPutForExternalReadCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case ClearDataCommand.METHOD_ID:
+         case ClearDataCommand.VERSIONED_METHOD_ID:
+         {
+            ClearDataCommand returnValue = new PessClearDataCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case RemoveKeyCommand.METHOD_ID:
+         case RemoveKeyCommand.VERSIONED_METHOD_ID:
+         {
+            RemoveKeyCommand returnValue = new PessRemoveKeyCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+
+         case RemoveNodeCommand.METHOD_ID:
+         case RemoveNodeCommand.VERSIONED_METHOD_ID:
+         {
+            RemoveNodeCommand returnValue = new PessRemoveNodeCommand();
+            returnValue.initialize(notifier, dataContainer);
+            command = returnValue;
+            break;
+         }
+         case CreateNodeCommand.METHOD_ID:
+         {
+            CreateNodeCommand returnValue = new PessCreateNodeCommand(null);
+            returnValue.initialize(dataContainer);
+            command = returnValue;
+            break;
+         }
+         default:
+            // pass up to superclass
+            command = super.fromStream(id, parameters);
+            skipSetParams = true;
+      }
+      if (!skipSetParams)
+      {
+         command.setParameters(id, parameters);
+      }
+      return command;
+   }
+}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -4,7 +4,7 @@
 import org.jboss.cache.DataContainer;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeSPI;
-import org.jboss.cache.commands.ReversibleCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.read.GetChildrenNamesCommand;
 import org.jboss.cache.commands.read.GetDataMapCommand;
 import org.jboss.cache.commands.read.GetKeyValueCommand;
@@ -474,7 +474,7 @@
       TransactionContext transactionContext = ctx.getTransactionContext();
       if (transactionContext == null) return false;
 
-      for (ReversibleCommand txCacheCommand : transactionContext.getModifications())
+      for (WriteCommand txCacheCommand : transactionContext.getModifications())
       {
          if (txCacheCommand instanceof RemoveNodeCommand && fqn.isChildOrEquals(txCacheCommand.getFqn())) return true;
       }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -6,8 +6,8 @@
 import org.jboss.cache.Modification;
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.commands.AbstractVisitor;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
 import org.jboss.cache.commands.tx.PrepareCommand;
@@ -339,7 +339,7 @@
       {
          throw new Exception("transactionContext for transaction " + gtx + " not found in transaction table");
       }
-      List<ReversibleCommand> modifications = transactionContext.getModifications();
+      List<WriteCommand> modifications = transactionContext.getModifications();
       if (modifications.size() == 0)
       {
          if (trace) log.trace("Transaction has not logged any modifications!");
@@ -347,7 +347,7 @@
       }
       if (trace) log.trace("Cache loader modification list: " + modifications);
       StoreModificationsBuilder modsBuilder = new StoreModificationsBuilder(getStatisticsEnabled());
-      for (ReversibleCommand cacheCommand : modifications)
+      for (WriteCommand cacheCommand : modifications)
       {
          cacheCommand.acceptVisitor(null, modsBuilder);
       }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CallInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CallInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CallInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,8 +1,8 @@
 package org.jboss.cache.interceptors;
 
 import org.jboss.cache.commands.ReplicableCommand;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
 import org.jboss.cache.commands.tx.PrepareCommand;
@@ -146,7 +146,7 @@
     * in case a method has been invoked that the OptimisticNodeInterceptor knows nothing about, it will
     * filter down here.
     */
-   private Object handleAlterCacheMethod(InvocationContext ctx, ReversibleCommand command)
+   private Object handleAlterCacheMethod(InvocationContext ctx, WriteCommand command)
          throws Throwable
    {
       Object result = invokeCommand(ctx, command);

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/InvalidationInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -8,8 +8,8 @@
 
 import org.jboss.cache.Fqn;
 import org.jboss.cache.commands.AbstractVisitor;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
 import org.jboss.cache.commands.tx.PrepareCommand;
@@ -63,7 +63,7 @@
 public class InvalidationInterceptor extends BaseRpcInterceptor implements InvalidationInterceptorMBean
 {
    private long invalidations = 0;
-   protected Map<GlobalTransaction, List<ReversibleCommand>> txMods;
+   protected Map<GlobalTransaction, List<WriteCommand>> txMods;
    protected boolean optimistic;
    private CommandsFactory commandsFactory;
 
@@ -77,7 +77,7 @@
    private void initTxMap()
    {
       optimistic = configuration.getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
-      if (optimistic) txMods = new ConcurrentHashMap<GlobalTransaction, List<ReversibleCommand>>();
+      if (optimistic) txMods = new ConcurrentHashMap<GlobalTransaction, List<WriteCommand>>();
    }
 
    @Override
@@ -140,10 +140,10 @@
 
          if (transactionContext.hasModifications())
          {
-            List<ReversibleCommand> mods;
+            List<WriteCommand> mods;
             if (transactionContext.hasLocalModifications())
             {
-               mods = new ArrayList<ReversibleCommand>(command.getModifications());
+               mods = new ArrayList<WriteCommand>(command.getModifications());
                mods.removeAll(transactionContext.getLocalModifications());
             }
             else
@@ -175,7 +175,7 @@
 
          if (transactionContext.hasModifications())
          {
-            List<ReversibleCommand> mods = new ArrayList<ReversibleCommand>(transactionContext.getModifications());
+            List<WriteCommand> mods = new ArrayList<WriteCommand>(transactionContext.getModifications());
             if (transactionContext.hasLocalModifications()) mods.removeAll(transactionContext.getLocalModifications());
             txMods.put(gtx, mods);
          }
@@ -191,7 +191,7 @@
       if (tx != null && optimistic)
       {
          GlobalTransaction gtx = ctx.getGlobalTransaction();
-         List<ReversibleCommand> modifications = txMods.remove(gtx);
+         List<WriteCommand> modifications = txMods.remove(gtx);
          broadcastInvalidate(modifications, tx, ctx);
          if (trace) log.trace("Committing.  Broadcasting invalidations.");
       }
@@ -240,13 +240,13 @@
          }
          else
          {
-            if (isLocalModeForced(ctx)) ctx.getTransactionContext().addLocalModification((ReversibleCommand) command);
+            if (isLocalModeForced(ctx)) ctx.getTransactionContext().addLocalModification((WriteCommand) command);
          }
       }
       return retval;
    }
 
-   private void broadcastInvalidate(List<ReversibleCommand> modifications, Transaction tx, InvocationContext ctx) throws Throwable
+   private void broadcastInvalidate(List<WriteCommand> modifications, Transaction tx, InvocationContext ctx) throws Throwable
    {
       if (ctx.getTransaction() != null && !isLocalModeForced(ctx))
       {

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -13,7 +13,7 @@
 import org.jboss.cache.NodeFactory;
 import org.jboss.cache.NodeNotExistsException;
 import org.jboss.cache.NodeSPI;
-import org.jboss.cache.commands.ReversibleCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.read.GetChildrenNamesCommand;
 import org.jboss.cache.commands.read.GetDataMapCommand;
 import org.jboss.cache.commands.read.GetKeyValueCommand;
@@ -343,7 +343,7 @@
    /**
     * Adds a method call to the modification list of a given transaction's transaction entry
     */
-   private void addToModificationList(ReversibleCommand command, InvocationContext ctx)
+   private void addToModificationList(WriteCommand command, InvocationContext ctx)
    {
       Option opt = ctx.getOptionOverrides();
       ctx.getTransactionContext().addModification(command);

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -10,9 +10,9 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.commands.AbstractVisitor;
 import org.jboss.cache.commands.ReplicableCommand;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.VersionedDataCommand;
 import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.read.GravitateDataCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
@@ -153,8 +153,8 @@
 
    public Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable
    {
-      if (isLocalModeForced(ctx) && command instanceof ReversibleCommand)
-         ctx.getTransactionContext().addLocalModification((ReversibleCommand) command);
+      if (isLocalModeForced(ctx) && command instanceof WriteCommand)
+         ctx.getTransactionContext().addLocalModification((WriteCommand) command);
       return invokeNextInterceptor(ctx, command);
    }
 
@@ -256,12 +256,12 @@
    public class DataVersionPopulator extends AbstractVisitor
    {
       final TransactionWorkspace workspace;
-      final List<ReversibleCommand> versionedCommands;
+      final List<WriteCommand> versionedCommands;
 
       public DataVersionPopulator(TransactionWorkspace workspace, int numCommands)
       {
          this.workspace = workspace;
-         versionedCommands = new ArrayList<ReversibleCommand>(numCommands);
+         versionedCommands = new ArrayList<WriteCommand>(numCommands);
       }
 
       private void setDataVersion(VersionedDataCommand clone, Fqn fqn)

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -10,8 +10,9 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.commands.DataCommand;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.commands.pessimistic.ReversibleCommand;
 import org.jboss.cache.commands.read.GetChildrenNamesCommand;
 import org.jboss.cache.commands.read.GetKeyValueCommand;
 import org.jboss.cache.commands.read.GetKeysCommand;
@@ -177,7 +178,7 @@
 
    private void undoOperations(TransactionContext transactionContext)
    {
-      List<ReversibleCommand> modificationList = transactionContext.getModifications();
+      List<WriteCommand> modificationList = transactionContext.getModifications();
 
       if (modificationList.isEmpty())
       {
@@ -187,12 +188,13 @@
 
       if (trace) log.trace("undoOperations " + modificationList);
 
-      ArrayList<ReversibleCommand> copy;
-      copy = new ArrayList<ReversibleCommand>(modificationList);
+      ArrayList<WriteCommand> copy;
+      copy = new ArrayList<WriteCommand>(modificationList);
       RuntimeException exc = null;
-      for (ListIterator i = copy.listIterator(copy.size()); i.hasPrevious();)
+      for (ListIterator<WriteCommand> i = copy.listIterator(copy.size()); i.hasPrevious();)
       {
-         Object undoOp = i.previous();
+         WriteCommand undoOp = i.previous();
+         // since we are using pessimistic locking, all pessimistic WriteCommands implement ReversibleCommand.
          ReversibleCommand txCommand = (ReversibleCommand) undoOp;
          if (log.isDebugEnabled()) log.debug("Calling rollback() on command " + undoOp);
          try

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/ReplicationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/ReplicationInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/ReplicationInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,7 +1,7 @@
 package org.jboss.cache.interceptors;
 
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.PrepareCommand;
 import org.jboss.cache.commands.tx.RollbackCommand;
@@ -140,7 +140,7 @@
       }
       else
       {
-         if (local) ctx.getTransactionContext().addLocalModification((ReversibleCommand) command);
+         if (local) ctx.getTransactionContext().addLocalModification((WriteCommand) command);
       }
       return returnValue;
    }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -11,8 +11,8 @@
 import org.jboss.cache.ReplicationException;
 import org.jboss.cache.commands.AbstractVisitor;
 import org.jboss.cache.commands.ReplicableCommand;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
 import org.jboss.cache.commands.tx.PrepareCommand;
@@ -495,7 +495,7 @@
       try
       {
          // replay modifications
-         for (ReversibleCommand modification : command.getModifications())
+         for (WriteCommand modification : command.getModifications())
          {
             invokeNextInterceptor(ctx, modification);
             assertTxIsStillValid(ltx);
@@ -604,7 +604,7 @@
    /**
     * creates a rollback()
     */
-   protected void runRollbackPhase(InvocationContext ctx, GlobalTransaction gtx, Transaction tx, List<ReversibleCommand> modifications)
+   protected void runRollbackPhase(InvocationContext ctx, GlobalTransaction gtx, Transaction tx, List<WriteCommand> modifications)
    {
       try
       {
@@ -637,12 +637,12 @@
     * @param mods list of modifications
     * @return compacted list of modifications
     */
-   private List<ReversibleCommand> compact(List<ReversibleCommand> mods)
+   private List<WriteCommand> compact(List<WriteCommand> mods)
    {
       // TODO: 3.0.0: Make this more sophisticated, so it aggregates multiple puts on the same node, puts followed by a remove, etc.
       // for now this just removes the redundant CreateNodeCommands from the list.
-      List<ReversibleCommand> newList = new LinkedList<ReversibleCommand>();
-      for (ReversibleCommand cmd : mods)
+      List<WriteCommand> newList = new LinkedList<WriteCommand>();
+      for (WriteCommand cmd : mods)
       {
          if (!(cmd instanceof CreateNodeCommand)) newList.add(cmd);
       }
@@ -665,7 +665,7 @@
     * method call and passes the prepare() call up the chain.
     */
    @SuppressWarnings("deprecation")
-   public Object runPreparePhase(InvocationContext ctx, GlobalTransaction gtx, List<ReversibleCommand> modifications) throws Throwable
+   public Object runPreparePhase(InvocationContext ctx, GlobalTransaction gtx, List<WriteCommand> modifications) throws Throwable
    {
       // running a 2-phase commit.
       VisitableCommand prepareCommand = buildPrepareCommand(gtx, modifications, false);
@@ -890,7 +890,7 @@
    {
       Transaction tx = null;
       GlobalTransaction gtx = null;
-      List<ReversibleCommand> modifications = null;
+      List<WriteCommand> modifications = null;
       TransactionContext transactionContext = null;
       protected InvocationContext ctx; // the context for this call.
 

Modified: core/trunk/src/main/java/org/jboss/cache/marshall/AbstractMarshaller.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/AbstractMarshaller.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/AbstractMarshaller.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -14,10 +14,24 @@
 import org.jboss.cache.buddyreplication.BuddyFqnTransformer;
 import org.jboss.cache.commands.DataCommand;
 import org.jboss.cache.commands.ReplicableCommand;
-import org.jboss.cache.commands.ReversibleCommand;
-import org.jboss.cache.commands.read.*;
-import org.jboss.cache.commands.remote.*;
-import org.jboss.cache.commands.tx.*;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.commands.read.ExistsCommand;
+import org.jboss.cache.commands.read.GetChildrenNamesCommand;
+import org.jboss.cache.commands.read.GetDataMapCommand;
+import org.jboss.cache.commands.read.GetKeyValueCommand;
+import org.jboss.cache.commands.read.GetKeysCommand;
+import org.jboss.cache.commands.read.GravitateDataCommand;
+import org.jboss.cache.commands.remote.AnnounceBuddyPoolNameCommand;
+import org.jboss.cache.commands.remote.AssignToBuddyGroupCommand;
+import org.jboss.cache.commands.remote.ClusteredGetCommand;
+import org.jboss.cache.commands.remote.DataGravitationCleanupCommand;
+import org.jboss.cache.commands.remote.RemoveFromBuddyGroupCommand;
+import org.jboss.cache.commands.remote.ReplicateCommand;
+import org.jboss.cache.commands.tx.AbstractTransactionCommand;
+import org.jboss.cache.commands.tx.CommitCommand;
+import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
+import org.jboss.cache.commands.tx.PrepareCommand;
+import org.jboss.cache.commands.tx.RollbackCommand;
 import org.jboss.cache.commands.write.EvictCommand;
 import org.jboss.cache.commands.write.InvalidateCommand;
 import org.jboss.cache.config.Configuration;
@@ -115,7 +129,7 @@
 
             // Prepare method has a list of modifications. We will just take the first one and extract.
             PrepareCommand pc = (PrepareCommand) cmd;
-            List<ReversibleCommand> modifications = pc.getModifications();
+            List<WriteCommand> modifications = pc.getModifications();
             fqn = extractFqn(modifications.get(0));
 
             // If this is two phase commit, map the FQN to the GTX so

Modified: core/trunk/src/main/java/org/jboss/cache/transaction/PessimisticTransactionContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/PessimisticTransactionContext.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/PessimisticTransactionContext.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -10,7 +10,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.Fqn;
-import org.jboss.cache.commands.ReversibleCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.config.Option;
 import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
 
@@ -29,7 +29,7 @@
  * A TransactionContext maintains:
  * <ul>
  * <li>Handle to the local Transaction</li>
- * <li>List of {@link org.jboss.cache.commands.ReversibleCommand}s that make up this transaction</li>
+ * <li>List of {@link org.jboss.cache.commands.WriteCommand}s that make up this transaction</li>
  * <li>List of locks acquired</li>
  * <li>Any transaction-scope options</li>
  * </ul>
@@ -55,13 +55,13 @@
    private boolean forceSyncReplication = false;
 
    /**
-    * List&lt;ReversibleCommand&gt; of modifications ({@link ReversibleCommand}). They will be replicated on TX commit
+    * List&lt;ReversibleCommand&gt; of modifications ({@link org.jboss.cache.commands.WriteCommand}). They will be replicated on TX commit
     */
-   private List<ReversibleCommand> modificationList;
+   private List<WriteCommand> modificationList;
    /**
     * A list of modifications that have been encountered with a LOCAL mode option.  These will be removed from the modification list during replication.
     */
-   private List<ReversibleCommand> localModifications;
+   private List<WriteCommand> localModifications;
 
    /**
     * LinkedHashSet of locks acquired by the transaction. We use a LinkedHashSet because we need efficient Set semantics
@@ -89,27 +89,27 @@
       orderedSynchronizationHandler = new OrderedSynchronizationHandler(tx);
    }
 
-   public void addModification(ReversibleCommand command)
+   public void addModification(WriteCommand command)
    {
       if (command == null) return;
-      if (modificationList == null) modificationList = new LinkedList<ReversibleCommand>();
+      if (modificationList == null) modificationList = new LinkedList<WriteCommand>();
       modificationList.add(command);
    }
 
-   public List<ReversibleCommand> getModifications()
+   public List<WriteCommand> getModifications()
    {
       if (modificationList == null) return Collections.emptyList();
       return modificationList;
    }
 
-   public void addLocalModification(ReversibleCommand command)
+   public void addLocalModification(WriteCommand command)
    {
       if (command == null) throw new NullPointerException("Command is null!");
-      if (localModifications == null) localModifications = new LinkedList<ReversibleCommand>();
+      if (localModifications == null) localModifications = new LinkedList<WriteCommand>();
       localModifications.add(command);
    }
 
-   public List<ReversibleCommand> getLocalModifications()
+   public List<WriteCommand> getLocalModifications()
    {
       if (localModifications == null) return Collections.emptyList();
       return localModifications;

Modified: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionContext.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionContext.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,7 +1,7 @@
 package org.jboss.cache.transaction;
 
 import org.jboss.cache.Fqn;
-import org.jboss.cache.commands.ReversibleCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.config.Option;
 import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
 
@@ -24,14 +24,14 @@
     *
     * @param command modification
     */
-   void addModification(ReversibleCommand command);
+   void addModification(WriteCommand command);
 
    /**
     * Returns all modifications.  If there are no modifications in this transaction this method will return an empty list.
     *
     * @return list of modifications.
     */
-   List<ReversibleCommand> getModifications();
+   List<WriteCommand> getModifications();
 
    /**
     * Adds a modification to the local modification list.
@@ -39,14 +39,14 @@
     * @param command command to add to list.  Should not be null.
     * @throws NullPointerException if the command to be added is null.
     */
-   void addLocalModification(ReversibleCommand command);
+   void addLocalModification(WriteCommand command);
 
    /**
     * Returns all modifications that have been invoked with the LOCAL cache mode option.  These will also be in the standard modification list.
     *
     * @return list of LOCAL modifications, or an empty list.
     */
-   List<ReversibleCommand> getLocalModifications();
+   List<WriteCommand> getLocalModifications();
 
    /**
     * Adds the node that has been removed in the scope of the current transaction.

Modified: core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyManagerTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyManagerTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyManagerTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -12,9 +12,9 @@
 import org.jboss.cache.commands.write.PutKeyValueCommand;
 import org.jboss.cache.config.BuddyReplicationConfig;
 import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.parsing.XmlConfigHelper;
 import org.jboss.cache.config.parsing.element.BuddyElementParser;
-import org.jboss.cache.config.parsing.XmlConfigHelper;
-import org.jboss.cache.factories.CommandsFactory;
+import org.jboss.cache.factories.CommandsFactoryImpl;
 import static org.testng.AssertJUnit.*;
 import org.testng.annotations.Test;
 import org.w3c.dom.Element;
@@ -41,12 +41,12 @@
    {
       String xmlConfig =
             "   <buddyReplication enabled=\"true\" buddyPoolName=\"groupOne\">\n" +
-            "      <buddyLocator>\n" +
-            "         <properties>\n" +
-            "            numBuddies = 3\n" +
-            "         </properties>\n" +
-            "      </buddyLocator>\n" +
-            "   </buddyReplication>";
+                  "      <buddyLocator>\n" +
+                  "         <properties>\n" +
+                  "            numBuddies = 3\n" +
+                  "         </properties>\n" +
+                  "      </buddyLocator>\n" +
+                  "   </buddyReplication>";
       BuddyReplicationConfig config = getBuddyReplicationConfig(xmlConfig);
       BuddyManager mgr = new BuddyManager(config);
 
@@ -75,12 +75,12 @@
    {
       String xmlConfig =
             "   <buddyReplication enabled=\"true\" buddyPoolName=\"groupOne\">\n" +
-            "      <buddyLocator class=\"org.i.dont.exist.PhantomBuddyLocator\">\n" +
-            "         <properties>\n" +
-            "            numBuddies = 3\n" +
-            "         </properties>\n" +
-            "      </buddyLocator>\n" +
-            "   </buddyReplication>";
+                  "      <buddyLocator class=\"org.i.dont.exist.PhantomBuddyLocator\">\n" +
+                  "         <properties>\n" +
+                  "            numBuddies = 3\n" +
+                  "         </properties>\n" +
+                  "      </buddyLocator>\n" +
+                  "   </buddyReplication>";
       BuddyReplicationConfig config = getBuddyReplicationConfig(xmlConfig);
       BuddyManager mgr = new BuddyManager(config);
 
@@ -136,7 +136,7 @@
          BuddyReplicationConfig config = getBuddyReplicationConfig(xmlConfig);
          bm = new BuddyManager(config);
          bm.injectDependencies(null, null, null, null, null, null, null, null, new BuddyFqnTransformer());
-         CommandsFactory commandsFactory = new CommandsFactory();
+         CommandsFactoryImpl commandsFactory = new CommandsFactoryImpl();
          commandsFactory.initialize(null, null, null, null, null, null, null, new Configuration(), null, new BuddyFqnTransformer());
          bm.initFqnTransformer(DUMMY_LOCAL_ADDRESS, commandsFactory);
       }

Modified: core/trunk/src/test/java/org/jboss/cache/commands/RollbackOnNoOpTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/RollbackOnNoOpTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/commands/RollbackOnNoOpTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,16 +1,15 @@
 package org.jboss.cache.commands;
 
-import org.testng.annotations.Test;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.AfterMethod;
 import org.jboss.cache.CacheSPI;
 import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
 import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.util.TestingUtil;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
 
 import javax.transaction.TransactionManager;
-import java.util.HashMap;
 
 /**
  * @author Mircea.Markus at jboss.com
@@ -34,8 +33,7 @@
    @AfterMethod(alwaysRun = true)
    public void tearDown()
    {
-      cache.stop();
-      cache.destroy();
+      TestingUtil.killCaches(cache);
    }
 
    public void testRollbackOnRemoveNodeDoesNotFail() throws Exception
@@ -64,7 +62,7 @@
    public void testRemoveKeyCommand() throws Exception
    {
       txMgr.begin();
-      cache.remove("/blah/blah","key");
+      cache.remove("/blah/blah", "key");
       txMgr.rollback();
    }
 

Modified: core/trunk/src/test/java/org/jboss/cache/commands/StructuralNodesOnRollbackTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/StructuralNodesOnRollbackTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/commands/StructuralNodesOnRollbackTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,13 +1,13 @@
 package org.jboss.cache.commands;
 
-import org.testng.annotations.Test;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.AfterMethod;
 import org.jboss.cache.CacheSPI;
 import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
 import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.util.TestingUtil;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
 
 import javax.transaction.TransactionManager;
 import java.util.HashMap;
@@ -36,30 +36,29 @@
    @AfterMethod(alwaysRun = true)
    public void tearDown()
    {
-      cache.stop();
-      cache.destroy();
+      TestingUtil.killCaches(cache);
    }
 
    public void testPutDataMap() throws Exception
    {
       HashMap map = new HashMap();
-      map.put("k","v");
+      map.put("k", "v");
 
-      assert  !cache.exists("/a/b");
+      assert !cache.exists("/a/b");
       txMgr.begin();
       cache.put("/a/b/c", map);
-      assert  cache.exists("/a/b");
+      assert cache.exists("/a/b");
       txMgr.rollback();
-      assert  !cache.exists("/a/b");
+      assert !cache.exists("/a/b");
    }
-   
+
    public void testPutKeyValueCommand() throws Exception
    {
-      assert  !cache.exists("/a/b");
+      assert !cache.exists("/a/b");
       txMgr.begin();
       cache.put("/a/b/c", "key", "value");
-      assert  cache.exists("/a/b");
+      assert cache.exists("/a/b");
       txMgr.rollback();
-      assert  !cache.exists("/a/b");
+      assert !cache.exists("/a/b");
    }
 }

Copied: core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/ClearDataCommandTest.java (from rev 6106, core/trunk/src/test/java/org/jboss/cache/commands/write/ClearDataCommandTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/ClearDataCommandTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/ClearDataCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,102 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import static org.easymock.EasyMock.expect;
+import org.jboss.cache.commands.write.AbstractVersionedDataCommand;
+import org.jboss.cache.commands.write.AbstractVersionedDataCommandTest;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+
+/**
+ * tester class for {@link org.jboss.cache.commands.write.ClearDataCommand}.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = "unit")
+public class ClearDataCommandTest extends AbstractVersionedDataCommandTest
+{
+
+   PessClearDataCommand command;
+
+   public AbstractVersionedDataCommand moreSetUp()
+   {
+      command = new PessClearDataCommand(globalTransaction, fqn);
+      command.setDataVersion(dataVersion);
+      return command;
+   }
+
+   public void testNonexistentNode()
+   {
+      // will happen twice - once in the Pess subclass.
+      expect(container.peek(fqn)).andReturn(null);
+      expect(container.peek(fqn)).andReturn(null);
+      control.replay();
+      assert null == command.perform(ctx);
+      control.verify();
+   }
+
+   public void testExistentDataVersioned()
+   {
+      nodes.adfgNode.put("key", "value");
+      nodes.adfgNode.setVersion(dataVersion);
+      // will happen twice - once in the Pess subclass.
+      expect(container.peek(fqn)).andReturn(nodes.adfgNode);
+      expect(container.peek(fqn)).andReturn(nodes.adfgNode);
+      notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, nodes.adfgNode.getDataDirect(), ctx);
+      notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, Collections.EMPTY_MAP, ctx);
+      control.replay();
+      assert null == command.perform(ctx);
+      assert nodes.adfgNode.getData().isEmpty();
+      control.verify();
+
+      //now do a rollback
+      control.reset();
+      expect(container.peek(fqn, false, true)).andReturn(nodes.aNode);
+      control.replay();
+      command.rollback();
+      assert nodes.aNode.dataSize() == 1;
+      assert nodes.aNode.getData().get("key").equals("value");
+   }
+
+   public void testExistentDataUnversioned()
+   {
+      command.setDataVersion(null);
+      nodes.adfgNode.put("key", "value");
+      // will happen twice - once in the Pess subclass.
+      expect(container.peek(fqn)).andReturn(nodes.adfgNode);
+      expect(container.peek(fqn)).andReturn(nodes.adfgNode);
+      notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, nodes.adfgNode.getDataDirect(), ctx);
+      notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, Collections.EMPTY_MAP, ctx);
+      control.replay();
+      assert null == command.perform(ctx);
+      assert nodes.adfgNode.getData().isEmpty();
+      control.verify();
+
+      //now do a rollback
+      control.reset();
+      expect(container.peek(fqn, false, true)).andReturn(nodes.aNode);
+      control.replay();
+      command.rollback();
+      assert nodes.aNode.dataSize() == 1;
+      assert nodes.aNode.getData().get("key").equals("value");
+   }
+
+   /**
+    * If clearing data on an inexistent node, the rollback should not fail
+    */
+   public void testNoOpRollback()
+   {
+      expect(container.peek(fqn, false, true)).andReturn(null);
+      control.replay();
+      try
+      {
+         command.rollback();
+      }
+      catch (Exception e)
+      {
+         assert false : "should not fail but expect this scenarion";
+      }
+   }
+}

Copied: core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/CreateNodeCommandTest.java (from rev 6106, core/trunk/src/test/java/org/jboss/cache/commands/write/CreateNodeCommandTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/CreateNodeCommandTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/CreateNodeCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,73 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import static org.easymock.EasyMock.*;
+import org.jboss.cache.commands.read.AbstractDataCommandTest;
+import org.jboss.cache.mock.MockNodesFixture;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+
+/**
+ * Tester class for {@link org.jboss.cache.commands.write.CreateNodeCommand}
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = "unit")
+public class CreateNodeCommandTest extends AbstractDataCommandTest
+{
+   PessCreateNodeCommand command;
+   private Object[] result;
+   private ArrayList createdNodes;
+
+   protected void moreSetup()
+   {
+      command = new PessCreateNodeCommand(testFqn);
+      command.initialize(container);
+      createdNodes = new ArrayList();
+      result = new Object[2];
+      result[0] = this.createdNodes;
+   }
+
+   public void testPerformNoNodesCreated()
+   {
+      expect(container.createNodes(testFqn)).andReturn(result);
+      replay(container);
+      assert null == command.perform(ctx);
+      assert command.getNewlyCreated().isEmpty();
+   }
+
+   public void testPerformWithCreatedNodes()
+   {
+      MockNodesFixture nodes = new MockNodesFixture();
+      createdNodes.add(nodes.aNode);
+      createdNodes.add(nodes.abNode);
+      createdNodes.add(nodes.abcNode);
+      result[1] = nodes.abcNode;
+
+      expect(container.createNodes(testFqn)).andReturn(result);
+      replay(container);
+      assert nodes.abcNode == command.perform(ctx);
+      assert command.getNewlyCreated().size() == 3;
+      assert command.getNewlyCreated().contains(nodes.a);
+      assert command.getNewlyCreated().contains(nodes.ab);
+      assert command.getNewlyCreated().contains(nodes.abc);
+   }
+
+   public void testRollback()
+   {
+      MockNodesFixture nodes = new MockNodesFixture();
+      createdNodes.add(nodes.aNode);
+      createdNodes.add(nodes.abNode);
+      createdNodes.add(nodes.abcNode);
+      expect(container.createNodes(testFqn)).andReturn(result);
+      expect(container.removeFromDataStructure(nodes.a, true)).andReturn(Boolean.TRUE);
+      expect(container.removeFromDataStructure(nodes.ab, true)).andReturn(Boolean.TRUE);
+      expect(container.removeFromDataStructure(nodes.abc, true)).andReturn(Boolean.TRUE);
+      replay(container);
+      command.perform(ctx);
+      command.rollback();
+      verify(container);
+   }
+
+}

Copied: core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/MoveCommandTest.java (from rev 6106, core/trunk/src/test/java/org/jboss/cache/commands/write/MoveCommandTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/MoveCommandTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/MoveCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,75 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import static org.easymock.EasyMock.createStrictControl;
+import static org.easymock.EasyMock.expect;
+import org.easymock.IMocksControl;
+import org.jboss.cache.DataContainer;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeNotExistsException;
+import org.jboss.cache.commands.read.AbstractDataCommandTest;
+import org.jboss.cache.commands.write.MoveCommand;
+import org.jboss.cache.mock.MockNodesFixture;
+import org.jboss.cache.notifications.Notifier;
+import org.testng.annotations.Test;
+
+/**
+ * Tester class for {@link org.jboss.cache.commands.write.MoveCommand}.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = "unit")
+public class MoveCommandTest extends AbstractDataCommandTest
+{
+   MoveCommand command;
+   Notifier notifier;
+   IMocksControl control;
+   MockNodesFixture nodes;
+
+   Fqn source = Fqn.fromString("/source");
+   Fqn destination = Fqn.fromString("/destination");
+
+   protected void moreSetup()
+   {
+      control = createStrictControl();
+      notifier = control.createMock(Notifier.class);
+      container = control.createMock(DataContainer.class);
+      command = new MoveCommand(source, destination);
+      command.initialize(notifier, container);
+      nodes = new MockNodesFixture();
+   }
+
+   public void testFailsOnMissingSource()
+   {
+      control.checkOrder(false);
+      expect(container.peek(source)).andReturn(null);
+      expect(container.peek(destination)).andReturn(nodes.adfgNode);
+      control.replay();
+      try
+      {
+         command.perform(ctx);
+         assert false : "should have thrown an exception as the source is null";
+      }
+      catch (NodeNotExistsException e)
+      {
+         //expected
+      }
+   }
+
+   public void testFailsOnMissingDestination()
+   {
+      control.checkOrder(false);
+      expect(container.peek(source)).andReturn(nodes.adfgNode);
+      expect(container.peek(destination)).andReturn(null);
+      control.replay();
+      try
+      {
+         command.perform(ctx);
+         assert false : "should have thrown an exception as the source is null";
+      }
+      catch (NodeNotExistsException e)
+      {
+         //expected
+      }
+   }
+}

Copied: core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/PutDataMapCommandTest.java (from rev 6106, core/trunk/src/test/java/org/jboss/cache/commands/write/PutDataMapCommandTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/PutDataMapCommandTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/PutDataMapCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,83 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import static org.easymock.EasyMock.createStrictControl;
+import static org.easymock.EasyMock.expect;
+import org.easymock.IMocksControl;
+import org.jboss.cache.DataContainer;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.commands.TestContextBase;
+import org.jboss.cache.invocation.InvocationContext;
+import org.jboss.cache.mock.NodeSpiMock;
+import org.jboss.cache.notifications.Notifier;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tester class for {@link org.jboss.cache.commands.write.PutDataMapCommand}
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = "unit")
+public class PutDataMapCommandTest extends TestContextBase
+{
+   Fqn testFqn = Fqn.fromString("/testfqn");
+   PessPutDataMapCommand command;
+   GlobalTransaction gtx;
+   Notifier notifier;
+   DataContainer container;
+   Map dataMap;
+   IMocksControl control;
+   NodeSpiMock node;
+   InvocationContext ctx;
+
+
+   @BeforeMethod
+   protected void setUp()
+   {
+      gtx = new GlobalTransaction();
+      dataMap = new HashMap();
+      command = new PessPutDataMapCommand(gtx, testFqn, dataMap);
+      control = createStrictControl();
+      notifier = control.createMock(Notifier.class);
+      container = control.createMock(DataContainer.class);
+      command.initialize(notifier, container);
+      node = new NodeSpiMock(testFqn);
+      node.put("k", "v");
+      ctx = createLegacyInvocationContext(container);
+   }
+
+   public void testAddDataNoErase()
+   {
+      // will happen twice - once in the Pess subclass.
+      expect(container.peek(testFqn)).andReturn(node);
+      expect(container.peek(testFqn)).andReturn(node);
+      dataMap.put("k2", "v2");
+      Map expected = new HashMap(dataMap);
+      expected.putAll(node.getDataDirect());
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(testFqn, true, NodeModifiedEvent.ModificationType.PUT_MAP, node.getData(), ctx);
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(testFqn, false, NodeModifiedEvent.ModificationType.PUT_MAP, expected, ctx);
+
+      control.replay();
+      assert null == command.perform(ctx) : "null result is always expected";
+      assert command.oldData.size() == 1;
+      assert command.oldData.get("k").equals("v");
+      control.verify();
+   }
+
+
+   public void testRollbackNonexistentNode()
+   {
+      expect(container.peek(testFqn, false, true)).andReturn(null);
+      control.replay();
+      command.rollback();
+      control.verify();
+   }
+}

Copied: core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/PutKeyValueCommandTest.java (from rev 6106, core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/PutKeyValueCommandTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/PutKeyValueCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,96 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import static org.easymock.EasyMock.expect;
+import org.jboss.cache.NodeNotExistsException;
+import org.jboss.cache.commands.write.AbstractVersionedDataCommand;
+import org.jboss.cache.commands.write.AbstractVersionedDataCommandTest;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * tester class for {@link org.jboss.cache.commands.write.PutKeyValueCommand}.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = "unit")
+public class PutKeyValueCommandTest extends AbstractVersionedDataCommandTest
+{
+   PessPutForExternalReadCommand command;
+
+   public AbstractVersionedDataCommand moreSetUp()
+   {
+      command = new PessPutForExternalReadCommand(globalTransaction, fqn, "k", "v");
+      return command;
+   }
+
+   public void testInexistentNode()
+   {
+      expect(container.peek(fqn)).andReturn(null); // simulate node not existing.
+      control.replay();
+      try
+      {
+         command.perform(ctx);
+         assert false : "exception should have been thrown as data does not exists.";
+      }
+      catch (NodeNotExistsException e)
+      {
+         //expected
+      }
+      control.verify();
+   }
+
+   public void testAddNewData()
+   {
+      nodes.adfNode.put("existingKey", "existingValue");
+      expect(container.peek(fqn)).andReturn(nodes.adfNode);
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, nodes.adfNode.getDataDirect(), ctx);
+      Map expected = new HashMap();
+      expected.put("k", "v");
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_DATA, expected, ctx);
+      control.replay();
+      assert null == command.perform(ctx) : "no pre existing value";
+      assert nodes.adfNode.getData().size() == 2;
+      assert "v".equals(nodes.adfNode.getData().get("k"));
+      assert "existingValue".equals(nodes.adfNode.getData().get("existingKey"));
+      control.verify();
+
+      control.reset();
+      expect(container.peek(fqn, false, false)).andReturn(nodes.adfNode);
+      control.replay();
+      command.rollback();
+      assert nodes.adfNode.getData().size() == 1;
+      assert "existingValue".equals(nodes.adfNode.getData().get("existingKey"));
+      control.verify();
+   }
+
+   public void testOverWriteData()
+   {
+      nodes.adfNode.put("k", "oldValue");
+      expect(container.peek(fqn)).andReturn(nodes.adfNode);
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, nodes.adfNode.getDataDirect(), ctx);
+      Map expected = new HashMap();
+      expected.put("k", "v");
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_DATA, expected, ctx);
+      control.replay();
+      assert "oldValue".equals(command.perform(ctx)) : "no pre existing value";
+      assert nodes.adfNode.getData().size() == 1;
+      assert "v".equals(nodes.adfNode.getData().get("k"));
+      control.verify();
+
+      control.reset();
+      expect(container.peek(fqn, false, false)).andReturn(nodes.adfNode);
+      control.replay();
+      command.rollback();
+      assert nodes.adfNode.getData().size() == 1;
+      assert "oldValue".equals(nodes.adfNode.getData().get("k"));
+      control.verify();
+   }
+}

Copied: core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/RemoveKeyCommandTest.java (from rev 6106, core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveKeyCommandTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/RemoveKeyCommandTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/RemoveKeyCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,101 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import static org.easymock.EasyMock.expect;
+import org.jboss.cache.commands.write.AbstractVersionedDataCommand;
+import org.jboss.cache.commands.write.AbstractVersionedDataCommandTest;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * tester class for {@link org.jboss.cache.commands.write.RemoveKeyCommand}.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = "unit")
+public class RemoveKeyCommandTest extends AbstractVersionedDataCommandTest
+{
+   PessRemoveKeyCommand command;
+   private String key;
+
+   public AbstractVersionedDataCommand moreSetUp()
+   {
+      key = "key";
+      command = new PessRemoveKeyCommand(globalTransaction, fqn, key);
+      return command;
+   }
+
+   public void testNonexistentNode()
+   {
+      expect(container.peek(fqn)).andReturn(null);
+      control.replay();
+      assert null == command.perform(ctx);
+      control.verify();
+   }
+
+   public void testRemoveNonexistentPair()
+   {
+      Map expected = new HashMap();
+      expected.put("newKey", "newValue");
+      nodes.adfgNode.putAll(expected);
+      expect(container.peek(fqn)).andReturn(nodes.adfgNode);
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, expected, ctx);
+      expected = new HashMap();
+      expected.put(key, null);
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, expected, ctx);
+      control.replay();
+      assert null == command.perform(ctx);
+      assert nodes.adfgNode.getData().size() == 1;
+      assert "newValue".equals(nodes.adfgNode.getData().get("newKey"));
+      control.verify();
+
+      control.reset();
+      // won't do the peek if the oldValue was null.  Nothing to set anyway, why peek.
+//      expect(container.peek(fqn, false, true)).andReturn(nodes.adfgNode);
+      control.replay();
+      command.rollback();
+      assert nodes.adfgNode.getData().size() == 1;
+      assert "newValue".equals(nodes.adfgNode.getData().get("newKey"));
+      control.verify();
+   }
+
+   public void testRemoveExistentPair()
+   {
+      Map expected = new HashMap();
+      expected.put(key, "newValue");
+      nodes.adfgNode.putAll(expected);
+      expect(container.peek(fqn)).andReturn(nodes.adfgNode);
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.REMOVE_DATA, expected, ctx);
+      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
+      notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.REMOVE_DATA, expected, ctx);
+      control.replay();
+      assert "newValue" == command.perform(ctx);
+      assert nodes.adfgNode.getData().get(key) == null;
+      control.verify();
+
+      control.reset();
+      expect(container.peek(fqn, false, true)).andReturn(nodes.adfgNode);
+      control.replay();
+      command.rollback();
+      assert nodes.adfgNode.getData().size() == 1;
+      assert "newValue".equals(nodes.adfgNode.getData().get(key));
+      control.verify();
+   }
+
+   /**
+    * On an no-op scenario the user will try to remove a key on an unexisting node.
+    * When rollback is being called, the node might not exist in the cache and we should know how to handle that.
+    */
+   public void testRollbackOnNoOp()
+   {
+      expect(container.peek(fqn, false, true)).andReturn(null);
+      control.replay();
+      command.rollback();
+   }
+}

Copied: core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/RemoveNodeCommandTest.java (from rev 6106, core/trunk/src/test/java/org/jboss/cache/commands/write/RemoveNodeCommandTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/RemoveNodeCommandTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/commands/pessimistic/write/RemoveNodeCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -0,0 +1,88 @@
+package org.jboss.cache.commands.pessimistic.write;
+
+import static org.easymock.EasyMock.expect;
+import org.jboss.cache.commands.write.AbstractVersionedDataCommand;
+import org.jboss.cache.commands.write.AbstractVersionedDataCommandTest;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.testng.annotations.Test;
+
+/**
+ * tester for  {@link org.jboss.cache.commands.write.RemoveNodeCommand}.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = "unit")
+public class RemoveNodeCommandTest extends AbstractVersionedDataCommandTest
+{
+   PessRemoveNodeCommand command;
+
+   public AbstractVersionedDataCommand moreSetUp()
+   {
+      command = new PessRemoveNodeCommand(globalTransaction, fqn);
+      command.setDataVersion(dataVersion);
+      return command;
+   }
+
+   public void testNonExistentNode()
+   {
+      expect(container.peek(fqn)).andReturn(null);
+      control.replay();
+      assert Boolean.FALSE == command.perform(ctx) : "nonexistent node was not remove; false expected";
+   }
+
+   public void testRemovalNoNotificationsValidNode()
+   {
+      //aditional setup
+      command.setSkipSendingNodeEvents(true); //no notification
+      nodes.adfNode.put("akey", "avalue");
+      nodes.adfNode.setVersion(dataVersion);
+      ctx.setGlobalTransaction(new GlobalTransaction());
+
+      //check perform
+      expect(container.peek(fqn)).andReturn(nodes.adfNode);
+      control.replay();
+      assert Boolean.TRUE == command.perform(ctx);
+      assert nodes.adfgNode.isDeleted();
+      assert nodes.adfhNode.isDeleted();
+      assert command.originalData != null;
+      control.verify();
+
+      //check rollback
+      control.reset();
+      nodes.adNode.removeChild("f");
+      expect(container.peek(nodes.ad)).andReturn(nodes.adNode);
+      control.replay();
+      command.rollback();
+      assert nodes.adNode.hasChild("f");
+   }
+
+   public void testRemovalNoNotificationsInvalidNode()
+   {
+      command.setSkipSendingNodeEvents(true); //no notification
+      nodes.adfNode.setValid(false, false);   //invalid node
+      nodes.adfNode.setVersion(dataVersion);
+
+      expect(container.peek(fqn)).andReturn(nodes.adfNode);
+      control.replay();
+      assert Boolean.FALSE == command.perform(ctx);
+      assert nodes.adfgNode.isDeleted();
+      assert nodes.adfhNode.isDeleted();
+      control.verify();
+   }
+
+   public void testRemovalWithNotificationsInvalidNode()
+   {
+      nodes.adfNode.setValid(false, false);   //invalid node
+      nodes.adfNode.setVersion(dataVersion);
+
+      expect(container.peek(fqn)).andReturn(nodes.adfNode);
+      notifier.notifyNodeRemoved(fqn, true, nodes.adfNode.getDataDirect(), ctx);
+      notifier.notifyNodeRemoved(fqn, false, null, ctx);
+      control.replay();
+      assert Boolean.FALSE == command.perform(ctx);
+      assert nodes.adfgNode.isDeleted();
+      assert nodes.adfhNode.isDeleted();
+      control.verify();
+   }
+}

Modified: core/trunk/src/test/java/org/jboss/cache/commands/write/AbstractVersionedDataCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/AbstractVersionedDataCommandTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/AbstractVersionedDataCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -23,17 +23,16 @@
 @Test(groups = "unit")
 public abstract class AbstractVersionedDataCommandTest extends TestContextBase
 {
-   Notifier notifier;
-   DataContainer container;
-   IMocksControl control;
+   protected Notifier notifier;
+   protected DataContainer container;
+   protected IMocksControl control;
 
-   MockNodesFixture nodes;
-   DataVersion dataVersion;
-   GlobalTransaction globalTransaction;
-   Fqn fqn = Fqn.fromString("/test/fqn");
-   InvocationContext ctx;
+   protected MockNodesFixture nodes;
+   protected DataVersion dataVersion;
+   protected GlobalTransaction globalTransaction;
+   protected Fqn fqn = Fqn.fromString("/test/fqn");
+   protected InvocationContext ctx;
 
-
    @BeforeMethod
    public final void setUp()
    {
@@ -46,7 +45,7 @@
       ctx = createLegacyInvocationContext(container);
 
       AbstractVersionedDataCommand command = moreSetUp();
-      command.initialize(notifier, container, false);
+      command.initialize(notifier, container);
    }
 
    public abstract AbstractVersionedDataCommand moreSetUp();

Modified: core/trunk/src/test/java/org/jboss/cache/commands/write/EvictCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/EvictCommandTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/EvictCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -40,7 +40,7 @@
    public void testResidentNodesEviction()
    {
       nodes.abNode.setResident(true);
-      expect(container.peek(testFqn)).andReturn(nodes.abNode);
+      expect(container.peek(testFqn, false, true)).andReturn(nodes.abNode);
       control.replay();
       assert Boolean.TRUE == command.perform(ctx);
       control.verify();
@@ -48,7 +48,7 @@
 
    public void testSimpleEviction()
    {
-      expect(container.peek(testFqn)).andReturn(nodes.abNode);
+      expect(container.peek(testFqn, false, true)).andReturn(nodes.abNode);
       notifier.notifyNodeEvicted(testFqn, true, ctx);
       expect(container.evict(testFqn)).andReturn(true);
       notifier.notifyNodeEvicted(testFqn, false, ctx);
@@ -63,7 +63,7 @@
       nodesToEvict.add(nodes.a);
       nodesToEvict.add(nodes.ab);
       command.setRecursive(true);
-      expect(container.peek(testFqn)).andReturn(nodes.aNode);
+      expect(container.peek(testFqn, false, true)).andReturn(nodes.aNode);
 
       expect(container.getNodesForEviction(testFqn, true)).andReturn(nodesToEvict);
       control.checkOrder(false);

Deleted: core/trunk/src/test/java/org/jboss/cache/commands/write/MoveCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/MoveCommandTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/MoveCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,74 +0,0 @@
-package org.jboss.cache.commands.write;
-
-import static org.easymock.EasyMock.createStrictControl;
-import static org.easymock.EasyMock.expect;
-import org.easymock.IMocksControl;
-import org.jboss.cache.DataContainer;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.NodeNotExistsException;
-import org.jboss.cache.commands.read.AbstractDataCommandTest;
-import org.jboss.cache.mock.MockNodesFixture;
-import org.jboss.cache.notifications.Notifier;
-import org.testng.annotations.Test;
-
-/**
- * Tester class for {@link org.jboss.cache.commands.write.MoveCommand}.
- *
- * @author Mircea.Markus at jboss.com
- * @since 2.2
- */
- at Test(groups = "unit")
-public class MoveCommandTest extends AbstractDataCommandTest
-{
-   MoveCommand command;
-   Notifier notifier;
-   IMocksControl control;
-   MockNodesFixture nodes;
-
-   Fqn source = Fqn.fromString("/source");
-   Fqn destination = Fqn.fromString("/destination");
-
-   protected void moreSetup()
-   {
-      control = createStrictControl();
-      notifier = control.createMock(Notifier.class);
-      container = control.createMock(DataContainer.class);
-      command = new MoveCommand(source, destination);
-      command.initialize(notifier, container, false);
-      nodes = new MockNodesFixture();
-   }
-
-   public void testFailsOnMissingSource()
-   {
-      control.checkOrder(false);
-      expect(container.peek(source)).andReturn(null);
-      expect(container.peek(destination)).andReturn(nodes.adfgNode);
-      control.replay();
-      try
-      {
-         command.perform(ctx);
-         assert false : "should have thrown an exception as the source is null";
-      }
-      catch (NodeNotExistsException e)
-      {
-         //expected
-      }
-   }
-
-   public void testFailsOnMissingDestination()
-   {
-      control.checkOrder(false);
-      expect(container.peek(source)).andReturn(nodes.adfgNode);
-      expect(container.peek(destination)).andReturn(null);
-      control.replay();
-      try
-      {
-         command.perform(ctx);
-         assert false : "should have thrown an exception as the source is null";
-      }
-      catch (NodeNotExistsException e)
-      {
-         //expected
-      }
-   }
-}

Deleted: core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/commands/write/PutKeyValueCommandTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,94 +0,0 @@
-package org.jboss.cache.commands.write;
-
-import static org.easymock.EasyMock.expect;
-import org.jboss.cache.NodeNotExistsException;
-import org.jboss.cache.notifications.event.NodeModifiedEvent;
-import org.testng.annotations.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * tester class for {@link PutKeyValueCommand}.
- *
- * @author Mircea.Markus at jboss.com
- * @since 2.2
- */
- at Test(groups = "unit")
-public class PutKeyValueCommandTest extends AbstractVersionedDataCommandTest
-{
-   PutKeyValueCommand command;
-
-   public AbstractVersionedDataCommand moreSetUp()
-   {
-      command = new PutForExternalReadCommand(globalTransaction, fqn, "k", "v");
-      return command;
-   }
-
-   public void testInexistentNode()
-   {
-      expect(container.peek(fqn)).andReturn(null); // simulate node not existing.
-      control.replay();
-      try
-      {
-         command.perform(ctx);
-         assert false : "exception should have been thrown as data does not exists.";
-      }
-      catch (NodeNotExistsException e)
-      {
-         //expected
-      }
-      control.verify();
-   }
-
-   public void testAddNewData()
-   {
-      nodes.adfNode.put("existingKey", "existingValue");
-      expect(container.peek(fqn)).andReturn(nodes.adfNode);
-      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
-      notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, nodes.adfNode.getDataDirect(), ctx);
-      Map expected = new HashMap();
-      expected.put("k", "v");
-      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
-      notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_DATA, expected, ctx);
-      control.replay();
-      assert null == command.perform(ctx) : "no pre existing value";
-      assert nodes.adfNode.getData().size() == 2;
-      assert "v".equals(nodes.adfNode.getData().get("k"));
-      assert "existingValue".equals(nodes.adfNode.getData().get("existingKey"));
-      control.verify();
-
-      control.reset();
-      expect(container.peek(fqn, false, false)).andReturn(nodes.adfNode);
-      control.replay();
-      command.rollback();
-      assert nodes.adfNode.getData().size() == 1;
-      assert "existingValue".equals(nodes.adfNode.getData().get("existingKey"));
-      control.verify();
-   }
-
-   public void testOverWriteData()
-   {
-      nodes.adfNode.put("k", "oldValue");
-      expect(container.peek(fqn)).andReturn(nodes.adfNode);
-      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
-      notifier.notifyNodeModified(fqn, true, NodeModifiedEvent.ModificationType.PUT_DATA, nodes.adfNode.getDataDirect(), ctx);
-      Map expected = new HashMap();
-      expected.put("k", "v");
-      expect(notifier.shouldNotifyOnNodeModified()).andReturn(true);
-      notifier.notifyNodeModified(fqn, false, NodeModifiedEvent.ModificationType.PUT_DATA, expected, ctx);
-      control.replay();
-      assert "oldValue".equals(command.perform(ctx)) : "no pre existing value";
-      assert nodes.adfNode.getData().size() == 1;
-      assert "v".equals(nodes.adfNode.getData().get("k"));
-      control.verify();
-
-      control.reset();
-      expect(container.peek(fqn, false, false)).andReturn(nodes.adfNode);
-      control.replay();
-      command.rollback();
-      assert nodes.adfNode.getData().size() == 1;
-      assert "oldValue".equals(nodes.adfNode.getData().get("k"));
-      control.verify();
-   }
-}

Modified: core/trunk/src/test/java/org/jboss/cache/marshall/MethodIdPreservationTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/MethodIdPreservationTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/MethodIdPreservationTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -1,10 +1,11 @@
 package org.jboss.cache.marshall;
 
 import org.jboss.cache.Fqn;
-import org.jboss.cache.commands.ReversibleCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.tx.PrepareCommand;
 import org.jboss.cache.commands.write.PutDataMapCommand;
 import org.jboss.cache.factories.CommandsFactory;
+import org.jboss.cache.factories.CommandsFactoryImpl;
 import static org.testng.AssertJUnit.assertEquals;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -26,8 +27,8 @@
    private Marshaller m;
    private ObjectOutputStream stream;
    private ByteArrayOutputStream byteStream;
-   private ReversibleCommand command1;
-   private List<ReversibleCommand> list = new ArrayList<ReversibleCommand>(2);
+   private WriteCommand command1;
+   private List<WriteCommand> list = new ArrayList<WriteCommand>(2);
    private PrepareCommand prepareComand;
 
    @BeforeMethod(alwaysRun = true)
@@ -44,7 +45,7 @@
       prepareComand = new PrepareCommand(null, list, null, true);
 
       CacheMarshaller210 cm210 = new CacheMarshaller210();
-      CommandsFactory factory = new CommandsFactory();
+      CommandsFactory factory = new CommandsFactoryImpl();
       cm210.injectCommandsFactory(factory);
 
       m = cm210;

Modified: core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/ReturnValueMarshallingTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -11,6 +11,7 @@
 import org.jboss.cache.commands.remote.ClusteredGetCommand;
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.factories.CommandsFactory;
+import org.jboss.cache.factories.CommandsFactoryImpl;
 import org.jboss.cache.util.TestingUtil;
 import static org.testng.AssertJUnit.*;
 import org.testng.annotations.AfterMethod;
@@ -35,7 +36,7 @@
    private Object key = "key", value;
    private String className = "org.jboss.cache.marshall.MyList";
    private Class listClass;
-   private CommandsFactory commandsFactory = new CommandsFactory();
+   private CommandsFactory commandsFactory = new CommandsFactoryImpl();
 
    @BeforeMethod(alwaysRun = true)
    public void setUp() throws Exception

Modified: core/trunk/src/test/java/org/jboss/cache/optimistic/AbstractOptimisticTestCase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/optimistic/AbstractOptimisticTestCase.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/optimistic/AbstractOptimisticTestCase.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -7,8 +7,8 @@
 import org.jboss.cache.CacheSPI;
 import org.jboss.cache.DefaultCacheFactory;
 import org.jboss.cache.Fqn;
-import org.jboss.cache.commands.ReversibleCommand;
 import org.jboss.cache.commands.VersionedDataCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.config.CacheLoaderConfig;
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
@@ -281,10 +281,10 @@
       }
    }
 
-   protected List<ReversibleCommand> injectDataVersion(List<ReversibleCommand> modifications)
+   protected List<WriteCommand> injectDataVersion(List<WriteCommand> modifications)
    {
       List<MethodCall> newList = new LinkedList<MethodCall>();
-      for (ReversibleCommand c : modifications)
+      for (WriteCommand c : modifications)
       {
          if (c instanceof VersionedDataCommand)
          {

Modified: core/trunk/src/test/java/org/jboss/cache/optimistic/CacheTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/optimistic/CacheTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/optimistic/CacheTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -10,7 +10,7 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.VersionedNode;
-import org.jboss.cache.commands.ReversibleCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
 import org.jboss.cache.commands.tx.RollbackCommand;
@@ -213,7 +213,7 @@
       TransactionTable table = c.getTransactionTable();
       OptimisticTransactionContext entry = (OptimisticTransactionContext) table.get(gtx);
       assertNotNull(mgr.getTransaction());
-      ReversibleCommand command = entry.getModifications().get(0);
+      WriteCommand command = entry.getModifications().get(0);
       mgr.commit();
 
       GlobalTransaction remoteGtx = new GlobalTransaction();
@@ -224,7 +224,7 @@
       command.setGlobalTransaction(remoteGtx);
 
       //call our remote method
-      List<ReversibleCommand> cacheCommands = injectDataVersion(entry.getModifications());
+      List<WriteCommand> cacheCommands = injectDataVersion(entry.getModifications());
       OptimisticPrepareCommand prepareCommand = new OptimisticPrepareCommand(remoteGtx, cacheCommands, (Address) remoteGtx.getAddress(), false);
 
       TestingUtil.replicateCommand(c, prepareCommand);

Modified: core/trunk/src/test/java/org/jboss/cache/optimistic/TxInterceptorTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/optimistic/TxInterceptorTest.java	2008-06-27 22:06:51 UTC (rev 6110)
+++ core/trunk/src/test/java/org/jboss/cache/optimistic/TxInterceptorTest.java	2008-06-27 22:36:56 UTC (rev 6111)
@@ -7,7 +7,7 @@
 package org.jboss.cache.optimistic;
 
 import org.jboss.cache.CacheSPI;
-import org.jboss.cache.commands.ReversibleCommand;
+import org.jboss.cache.commands.WriteCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
 import org.jboss.cache.commands.tx.RollbackCommand;
@@ -288,7 +288,7 @@
       TransactionTable table = cache.getTransactionTable();
       OptimisticTransactionContext entry = (OptimisticTransactionContext) table.get(gtx);
       assertNotNull(mgr.getTransaction());
-      ReversibleCommand command = entry.getModifications().get(0);
+      WriteCommand command = entry.getModifications().get(0);
       mgr.commit();
 
       //test local calls
@@ -364,7 +364,7 @@
 
       remoteGtx.setAddress(new DummyAddress());
       //hack the method call to make it have the remote globalTransaction
-      ReversibleCommand command = entry.getModifications().get(0);
+      WriteCommand command = entry.getModifications().get(0);
       command.setGlobalTransaction(remoteGtx);
       //call our remote method
       OptimisticPrepareCommand prepareCommand = new OptimisticPrepareCommand(remoteGtx, injectDataVersion(entry.getModifications()), (Address) remoteGtx.getAddress(), Boolean.FALSE);
@@ -447,7 +447,7 @@
 
       remoteGtx.setAddress(new DummyAddress());
       //hack the method call to make it have the remote globalTransaction
-      ReversibleCommand command = entry.getModifications().get(0);
+      WriteCommand command = entry.getModifications().get(0);
       command.setGlobalTransaction(remoteGtx);
       //call our remote method
       OptimisticPrepareCommand prepareCommand = new OptimisticPrepareCommand(remoteGtx, injectDataVersion(entry.getModifications()), (Address) remoteGtx.getAddress(), Boolean.FALSE);
@@ -535,7 +535,7 @@
 
       remoteGtx.setAddress(new DummyAddress());
       //hack the method call to make it have the remote globalTransaction
-      ReversibleCommand command = entry.getModifications().get(0);
+      WriteCommand command = entry.getModifications().get(0);
       command.setGlobalTransaction(remoteGtx);
       //call our remote method
       OptimisticPrepareCommand prepareCommand = new OptimisticPrepareCommand(remoteGtx, injectDataVersion(entry.getModifications()), (Address) remoteGtx.getAddress(), Boolean.FALSE);
@@ -615,7 +615,7 @@
       TransactionTable table = cache.getTransactionTable();
       OptimisticTransactionContext entry = (OptimisticTransactionContext) table.get(gtx);
       assertNotNull(mgr.getTransaction());
-      ReversibleCommand command = entry.getModifications().get(0);
+      WriteCommand command = entry.getModifications().get(0);
       mgr.commit();
 
       //test local calls
@@ -707,7 +707,7 @@
       TransactionTable table = cache.getTransactionTable();
       OptimisticTransactionContext entry = (OptimisticTransactionContext) table.get(gtx);
       assertNotNull(mgr.getTransaction());
-      ReversibleCommand command = entry.getModifications().get(0);
+      WriteCommand command = entry.getModifications().get(0);
       mgr.commit();
 
       //test local calls




More information about the jbosscache-commits mailing list