[jbosscache-commits] JBoss Cache SVN: r7669 - in core/branches/flat/src: main/java/org/horizon/atomic and 23 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Mon Feb 9 13:30:59 EST 2009


Author: manik.surtani at jboss.com
Date: 2009-02-09 13:30:59 -0500 (Mon, 09 Feb 2009)
New Revision: 7669

Added:
   core/branches/flat/src/main/java/org/horizon/AdvancedCache.java
   core/branches/flat/src/main/java/org/horizon/context/AbstractContext.java
   core/branches/flat/src/main/java/org/horizon/context/OptionContainer.java
   core/branches/flat/src/main/java/org/horizon/invocation/Options.java
Removed:
   core/branches/flat/src/main/java/org/horizon/CacheSPI.java
   core/branches/flat/src/main/java/org/horizon/config/Option.java
Modified:
   core/branches/flat/src/main/java/org/horizon/Cache.java
   core/branches/flat/src/main/java/org/horizon/CacheDelegate.java
   core/branches/flat/src/main/java/org/horizon/atomic/AtomicHashMap.java
   core/branches/flat/src/main/java/org/horizon/atomic/AtomicHashMapProxy.java
   core/branches/flat/src/main/java/org/horizon/commands/CommandsFactoryImpl.java
   core/branches/flat/src/main/java/org/horizon/context/EntryLookup.java
   core/branches/flat/src/main/java/org/horizon/context/InvocationContext.java
   core/branches/flat/src/main/java/org/horizon/context/InvocationContextImpl.java
   core/branches/flat/src/main/java/org/horizon/context/TransactionContext.java
   core/branches/flat/src/main/java/org/horizon/context/TransactionContextImpl.java
   core/branches/flat/src/main/java/org/horizon/factories/BootstrapFactory.java
   core/branches/flat/src/main/java/org/horizon/factories/ComponentRegistry.java
   core/branches/flat/src/main/java/org/horizon/factories/DefaultCacheFactory.java
   core/branches/flat/src/main/java/org/horizon/factories/EntryFactoryImpl.java
   core/branches/flat/src/main/java/org/horizon/factories/annotations/NonVolatile.java
   core/branches/flat/src/main/java/org/horizon/interceptors/CacheStoreInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/InvalidationInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/InvocationContextInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/LockingInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/ReplicationInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/base/BaseRpcInterceptor.java
   core/branches/flat/src/main/java/org/horizon/invocation/InvocationContextContainer.java
   core/branches/flat/src/main/java/org/horizon/jmx/JmxRegistrationManager.java
   core/branches/flat/src/main/java/org/horizon/jmx/PlatformMBeanServerRegistration.java
   core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheLoader.java
   core/branches/flat/src/main/java/org/horizon/loader/AbstractDelegatingCacheLoader.java
   core/branches/flat/src/main/java/org/horizon/loader/CacheLoader.java
   core/branches/flat/src/main/java/org/horizon/loader/CacheLoaderManager.java
   core/branches/flat/src/main/java/org/horizon/loader/ClusteredCacheLoader.java
   core/branches/flat/src/main/java/org/horizon/loader/SingletonStoreCacheLoader.java
   core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java
   core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifierImpl.java
   core/branches/flat/src/main/java/org/horizon/statetransfer/DefaultStateTransferManager.java
   core/branches/flat/src/main/java/org/horizon/tree/Node.java
   core/branches/flat/src/main/java/org/horizon/tree/NodeImpl.java
   core/branches/flat/src/main/java/org/horizon/tree/TreeCache.java
   core/branches/flat/src/main/java/org/horizon/tree/TreeCacheImpl.java
   core/branches/flat/src/main/java/org/horizon/tree/TreeStructureSupport.java
   core/branches/flat/src/main/java/org/horizon/util/TestingUtil.java
   core/branches/flat/src/test/java/org/horizon/BaseClusteredTest.java
   core/branches/flat/src/test/java/org/horizon/api/CacheAPITest.java
   core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java
   core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java
   core/branches/flat/src/test/java/org/horizon/api/tree/NodeLockSupport.java
   core/branches/flat/src/test/java/org/horizon/api/tree/NodeMoveAPITest.java
   core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java
   core/branches/flat/src/test/java/org/horizon/api/tree/TreeCacheAPITest.java
   core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java
   core/branches/flat/src/test/java/org/horizon/notifications/cachelistener/CacheNotifierImplTest.java
   core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java
   core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java
   core/branches/flat/src/test/java/org/horizon/tx/LocalModeTxTest.java
   core/branches/flat/src/test/java/org/horizon/tx/MarkAsRollbackTest.java
Log:
- New Options API
- Removed CacheSPI in favour of AdvancedCache


Added: core/branches/flat/src/main/java/org/horizon/AdvancedCache.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/AdvancedCache.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/AdvancedCache.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -0,0 +1,108 @@
+package org.horizon;
+
+import org.horizon.batch.BatchContainer;
+import org.horizon.eviction.EvictionManager;
+import org.horizon.factories.ComponentRegistry;
+import org.horizon.interceptors.base.CommandInterceptor;
+import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.invocation.Options;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * An advanced interface that exposes additional methods not available on {@link Cache}.
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public interface AdvancedCache<K, V> extends Cache<K, V> {
+   /**
+    * Adds a custom interceptor to the interceptor chain, at specified position, where the first interceptor in the
+    * chain is at position 0 and the last one at NUM_INTERCEPTORS - 1.
+    *
+    * @param i        the interceptor to add
+    * @param position the position to add the interceptor
+    */
+   void addInterceptor(CommandInterceptor i, int position);
+
+   /**
+    * Adds a custom interceptor to the interceptor chain, after an instance of the specified interceptor type. Throws a
+    * cache exception if it cannot find an interceptor of the specified type.
+    *
+    * @param i                interceptor to add
+    * @param afterInterceptor interceptor type after which to place custom interceptor
+    */
+   void addInterceptorAfter(CommandInterceptor i, Class<? extends CommandInterceptor> afterInterceptor);
+
+   /**
+    * Adds a custom interceptor to the interceptor chain, before an instance of the specified interceptor type. Throws a
+    * cache exception if it cannot find an interceptor of the specified type.
+    *
+    * @param i                 interceptor to add
+    * @param beforeInterceptor interceptor type before which to place custom interceptor
+    */
+   void addInterceptorBefore(CommandInterceptor i, Class<? extends CommandInterceptor> beforeInterceptor);
+
+   /**
+    * Removes the interceptor at a specified position, where the first interceptor in the chain is at position 0 and the
+    * last one at getInterceptorChain().size() - 1.
+    *
+    * @param position the position at which to remove an interceptor
+    */
+   void removeInterceptor(int position);
+
+   /**
+    * Removes the interceptor of specified type.
+    *
+    * @param interceptorType type of interceptor to remove
+    */
+   void removeInterceptor(Class<? extends CommandInterceptor> interceptorType);
+
+   /**
+    * Retrieves the current Interceptor chain.
+    *
+    * @return an immutable {@link java.util.List} of {@link org.horizon.interceptors.base.CommandInterceptor}s
+    *         configured for this cache
+    */
+   List<CommandInterceptor> getInterceptorChain();
+
+   /**
+    * @return the eviction manager - if one is configured - for this cache instance
+    */
+   EvictionManager getEvictionManager();
+
+   /**
+    * @return the component registry for this cache instance
+    */
+   ComponentRegistry getComponentRegistry();
+
+   BatchContainer getBatchContainer();
+
+   InvocationContextContainer getInvocationContextContainer();
+
+   void putForExternalRead(K key, V value, Options... options);
+
+   V put(K key, V value, Options... options);
+
+   V put(K key, V value, long lifespan, TimeUnit unit, Options... options);
+
+   V putIfAbsent(K key, V value, Options... options);
+
+   V putIfAbsent(K key, V value, long lifespan, TimeUnit unit, Options... options);
+
+   void putAll(Map<? extends K, ? extends V> map, Options... options);
+
+   void putAll(Map<? extends K, ? extends V> map, long lifespan, TimeUnit unit, Options... options);
+
+   V remove(Object key, Options... options);
+
+   boolean remove(Object key, Object oldValue, Options... options);
+
+   void clear(Options... options);
+
+   boolean containsKey(Object key, Options... options);
+
+   V get(Object key, Options... options);
+}

Modified: core/branches/flat/src/main/java/org/horizon/Cache.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/Cache.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/Cache.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -22,8 +22,6 @@
 package org.horizon;
 
 import org.horizon.config.Configuration;
-import org.horizon.context.InvocationContext;
-import org.horizon.interceptors.base.CommandInterceptor;
 import org.horizon.lifecycle.Lifecycle;
 import org.horizon.manager.CacheManager;
 import org.horizon.notifications.Listenable;
@@ -66,10 +64,6 @@
 
    Configuration getConfiguration();
 
-   InvocationContext getInvocationContext();
-
-   void setInvocationContext(InvocationContext ctx);
-
    ComponentStatus getCacheStatus();
 
    /**
@@ -84,48 +78,6 @@
    String getVersion();
 
    /**
-    * Adds a custom interceptor to the interceptor chain, at specified position, where the first interceptor in the
-    * chain is at position 0 and the last one at NUM_INTERCEPTORS - 1.
-    *
-    * @param i        the interceptor to add
-    * @param position the position to add the interceptor
-    */
-   void addInterceptor(CommandInterceptor i, int position);
-
-   /**
-    * Adds a custom interceptor to the interceptor chain, after an instance of the specified interceptor type. Throws a
-    * cache exception if it cannot find an interceptor of the specified type.
-    *
-    * @param i                interceptor to add
-    * @param afterInterceptor interceptor type after which to place custom interceptor
-    */
-   void addInterceptorAfter(CommandInterceptor i, Class<? extends CommandInterceptor> afterInterceptor);
-
-   /**
-    * Adds a custom interceptor to the interceptor chain, before an instance of the specified interceptor type. Throws a
-    * cache exception if it cannot find an interceptor of the specified type.
-    *
-    * @param i                 interceptor to add
-    * @param beforeInterceptor interceptor type before which to place custom interceptor
-    */
-   void addInterceptorBefore(CommandInterceptor i, Class<? extends CommandInterceptor> beforeInterceptor);
-
-   /**
-    * Removes the interceptor at a specified position, where the first interceptor in the chain is at position 0 and the
-    * last one at getInterceptorChain().size() - 1.
-    *
-    * @param position the position at which to remove an interceptor
-    */
-   void removeInterceptor(int position);
-
-   /**
-    * Removes the interceptor of specified type.
-    *
-    * @param interceptorType type of interceptor to remove
-    */
-   void removeInterceptor(Class<? extends CommandInterceptor> interceptorType);
-
-   /**
     * Retrieves the cache manager responsible for creating this cache instance.
     *
     * @return a cache manager
@@ -186,4 +138,6 @@
     * @return true if the value was replaced, false otherwise
     */
    boolean replace(K key, V oldValue, V value, long lifespan, TimeUnit unit);
+
+   AdvancedCache<K, V> getAdvancedCache();
 }

Modified: core/branches/flat/src/main/java/org/horizon/CacheDelegate.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/CacheDelegate.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/CacheDelegate.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -45,17 +45,13 @@
 import org.horizon.interceptors.InterceptorChain;
 import org.horizon.interceptors.base.CommandInterceptor;
 import org.horizon.invocation.InvocationContextContainer;
-import org.horizon.loader.CacheLoaderManager;
-import org.horizon.lock.LockManager;
+import org.horizon.invocation.Options;
 import org.horizon.logging.Log;
 import org.horizon.logging.LogFactory;
 import org.horizon.manager.CacheManager;
 import org.horizon.marshall.Marshaller;
 import org.horizon.notifications.cachelistener.CacheNotifier;
 import org.horizon.remoting.RPCManager;
-import org.horizon.statetransfer.StateTransferManager;
-import org.horizon.transaction.GlobalTransaction;
-import org.horizon.transaction.TransactionTable;
 
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
@@ -70,7 +66,7 @@
  * @since 1.0
  */
 @NonVolatile
-public class CacheDelegate<K, V> implements CacheSPI<K, V>, AtomicMapCache<K, V> {
+public class CacheDelegate<K, V> implements AdvancedCache<K, V>, AtomicMapCache<K, V> {
    protected InvocationContextContainer invocationContextContainer;
    protected CommandsFactory commandsFactory;
    protected InterceptorChain invoker;
@@ -84,7 +80,6 @@
    private String name;
    private EvictionManager evictionManager;
    private DataContainer dataContainer;
-   private LockManager lockManager;
    private static final Log log = LogFactory.getLog(CacheDelegate.class);
    private CacheManager cacheManager;
 
@@ -93,19 +88,18 @@
    }
 
    @Inject
-   private void injectDependencies(EvictionManager evictionManager,
-                                   InvocationContextContainer invocationContextContainer,
-                                   CommandsFactory commandsFactory,
-                                   InterceptorChain interceptorChain,
-                                   Configuration configuration,
-                                   CacheNotifier notifier,
-                                   ComponentRegistry componentRegistry,
-                                   TransactionManager transactionManager,
-                                   BatchContainer batchContainer,
-                                   RPCManager rpcManager, DataContainer dataContainer,
-                                   Marshaller marshaller,
-                                   LockManager lockManager,
-                                   CacheManager cacheManager) {
+   public void injectDependencies(EvictionManager evictionManager,
+                                  InvocationContextContainer invocationContextContainer,
+                                  CommandsFactory commandsFactory,
+                                  InterceptorChain interceptorChain,
+                                  Configuration configuration,
+                                  CacheNotifier notifier,
+                                  ComponentRegistry componentRegistry,
+                                  TransactionManager transactionManager,
+                                  BatchContainer batchContainer,
+                                  RPCManager rpcManager, DataContainer dataContainer,
+                                  Marshaller marshaller,
+                                  CacheManager cacheManager) {
       this.invocationContextContainer = invocationContextContainer;
       this.commandsFactory = commandsFactory;
       this.invoker = interceptorChain;
@@ -118,45 +112,46 @@
       this.evictionManager = evictionManager;
       this.dataContainer = dataContainer;
       this.marshaller = marshaller;
-      this.lockManager = lockManager;
       this.cacheManager = cacheManager;
    }
 
+   @SuppressWarnings("unchecked")
    public V putIfAbsent(K key, V value) {
       PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(key, value);
       command.setPutIfAbsent(true);
-      return (V) invoker.invoke(buildCtx(), command);
+      return (V) invoker.invoke(getInvocationContext(), command);
    }
 
    public boolean remove(Object key, Object value) {
       RemoveCommand command = commandsFactory.buildRemoveCommand(key, value);
-      return (Boolean) invoker.invoke(buildCtx(), command);
+      return (Boolean) invoker.invoke(getInvocationContext(), command);
    }
 
    public boolean replace(K key, V oldValue, V newValue) {
       ReplaceCommand command = commandsFactory.buildReplaceCommand(key, oldValue, newValue);
-      return (Boolean) invoker.invoke(buildCtx(), command);
+      return (Boolean) invoker.invoke(getInvocationContext(), command);
    }
 
+   @SuppressWarnings("unchecked")
    public V replace(K key, V value) {
       ReplaceCommand command = commandsFactory.buildReplaceCommand(key, null, value);
-      return (V) invoker.invoke(buildCtx(), command);
+      return (V) invoker.invoke(getInvocationContext(), command);
    }
 
    public int size() {
       SizeCommand command = commandsFactory.buildSizeCommand();
-      return (Integer) invoker.invoke(buildCtx(), command);
+      return (Integer) invoker.invoke(getInvocationContext(), command);
    }
 
    public boolean isEmpty() {
       SizeCommand command = commandsFactory.buildSizeCommand();
-      int size = (Integer) invoker.invoke(buildCtx(), command);
+      int size = (Integer) invoker.invoke(getInvocationContext(), command);
       return size == 0;
    }
 
    public boolean containsKey(Object key) {
       GetKeyValueCommand command = commandsFactory.buildGetKeyValueCommand(key);
-      Object response = invoker.invoke(buildCtx(), command);
+      Object response = invoker.invoke(getInvocationContext(), command);
       return response != null;
    }
 
@@ -164,30 +159,32 @@
       throw new UnsupportedOperationException("Go away");
    }
 
+   @SuppressWarnings("unchecked")
    public V get(Object key) {
       GetKeyValueCommand command = commandsFactory.buildGetKeyValueCommand(key);
-      return (V) invoker.invoke(buildCtx(), command);
+      return (V) invoker.invoke(getInvocationContext(), command);
    }
 
+   @SuppressWarnings("unchecked")
    public V put(K key, V value) {
       PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(key, value);
-      return (V) invoker.invoke(buildCtx(), command);
+      return (V) invoker.invoke(getInvocationContext(), command);
    }
 
+   @SuppressWarnings("unchecked")
    public V remove(Object key) {
       RemoveCommand command = commandsFactory.buildRemoveCommand(key, null);
-      V oldval = (V) invoker.invoke(buildCtx(), command);
-      return oldval;
+      return (V) invoker.invoke(getInvocationContext(), command);
    }
 
    public void putAll(Map<? extends K, ? extends V> t) {
       PutMapCommand command = commandsFactory.buildPutMapCommand(t);
-      invoker.invoke(buildCtx(), command);
+      invoker.invoke(getInvocationContext(), command);
    }
 
    public void clear() {
       ClearCommand command = commandsFactory.buildClearCommand();
-      invoker.invoke(buildCtx(), command);
+      invoker.invoke(getInvocationContext(), command);
    }
 
    public Set<K> keySet() {
@@ -203,7 +200,6 @@
    }
 
    public void putForExternalRead(K key, V value) {
-      InvocationContext ctx = invocationContextContainer.get();
       Transaction ongoingTransaction = null;
       try {
          if (transactionManager != null && (ongoingTransaction = transactionManager.getTransaction()) != null) {
@@ -211,10 +207,7 @@
          }
 
          // if the node exists then this should be a no-op.
-         ctx.getOptionOverrides().setFailSilently(true);
-         ctx.getOptionOverrides().setForceAsynchronous(true);
-         ctx.getOptionOverrides().setLockAcquisitionTimeout(0);
-         putIfAbsent(key, value);
+         putIfAbsent(key, value, Options.FAIL_SILENTLY, Options.FORCE_ASYNCHRONOUS, Options.ZERO_LOCK_ACQUISITION_TIMEOUT);
       }
       catch (Exception e) {
          if (log.isDebugEnabled()) log.debug("Caught exception while doing putForExternalRead()", e);
@@ -231,7 +224,7 @@
 
    public void evict(K key) {
       EvictCommand command = commandsFactory.buildEvictCommand(key);
-      invoker.invoke(buildCtx(), command);
+      invoker.invoke(getInvocationContext(), command);
    }
 
    public Configuration getConfiguration() {
@@ -250,15 +243,10 @@
       return notifier.getListeners();
    }
 
-   public InvocationContext getInvocationContext() {
+   private InvocationContext getInvocationContext() {
       return invocationContextContainer.get();
    }
 
-   public void setInvocationContext(InvocationContext ctx) {
-      if (ctx == null) invocationContextContainer.remove();
-      else invocationContextContainer.set(ctx);
-   }
-
    public void start() {
       componentRegistry.start();
    }
@@ -267,22 +255,10 @@
       componentRegistry.stop();
    }
 
-   private InvocationContext buildCtx() {
-      return invocationContextContainer.get();
-   }
-
-   public TransactionManager getTransactionManager() {
-      return transactionManager;
-   }
-
    public List<CommandInterceptor> getInterceptorChain() {
-      throw new IllegalStateException();//todo Implement me properly
+      return invoker.asList();
    }
 
-   public Marshaller getMarshaller() {
-      return marshaller;
-   }
-
    public void addInterceptor(CommandInterceptor i, int position) {
       invoker.addInterceptor(i, position);
    }
@@ -303,42 +279,74 @@
       invoker.removeInterceptor(interceptorType);
    }
 
-   public CacheLoaderManager getCacheLoaderManager() {
-      throw new IllegalStateException();//todo Implement me properly
+   public EvictionManager getEvictionManager() {
+      return evictionManager;
    }
 
-   public TransactionTable getTransactionTable() {
-      throw new IllegalStateException();//todo Implement me properly
+   public ComponentRegistry getComponentRegistry() {
+      return componentRegistry;
    }
 
-   public EvictionManager getEvictionManager() {
-      return evictionManager;
+   public void putForExternalRead(K key, V value, Options... options) {
+      getInvocationContext().setOptions(options);
+      putForExternalRead(key, value);
    }
 
-   public RPCManager getRPCManager() {
-      return rpcManager;
+   public V put(K key, V value, Options... options) {
+      getInvocationContext().setOptions(options);
+      return put(key, value);
    }
 
-   public StateTransferManager getStateTransferManager() {
-      throw new IllegalStateException();//todo Implement me properly
+   public V put(K key, V value, long lifespan, TimeUnit unit, Options... options) {
+      getInvocationContext().setOptions(options);
+      return put(key, value, lifespan, unit);
    }
 
-   public CacheNotifier getNotifier() {
-      return notifier;
+   public V putIfAbsent(K key, V value, Options... options) {
+      getInvocationContext().setOptions(options);
+      return putIfAbsent(key, value);
    }
 
-   public GlobalTransaction getCurrentTransaction(Transaction tx, boolean createIfNotExists) {
-      throw new IllegalStateException();//todo Implement me properly
+   public V putIfAbsent(K key, V value, long lifespan, TimeUnit unit, Options... options) {
+      getInvocationContext().setOptions(options);
+      return putIfAbsent(key, value, lifespan, unit);
    }
 
-   public GlobalTransaction getCurrentTransaction() {
-      throw new IllegalStateException();//todo Implement me properly
+   public void putAll(Map<? extends K, ? extends V> map, Options... options) {
+      getInvocationContext().setOptions(options);
+      putAll(map);
    }
 
-   public ComponentRegistry getComponentRegistry() {
-      return componentRegistry;
+   public void putAll(Map<? extends K, ? extends V> map, long lifespan, TimeUnit unit, Options... options) {
+      getInvocationContext().setOptions(options);
+      putAll(map, lifespan, unit);
    }
 
+   public V remove(Object key, Options... options) {
+      getInvocationContext().setOptions(options);
+      return remove(key);
+   }
+
+   public boolean remove(Object key, Object oldValue, Options... options) {
+      getInvocationContext().setOptions(options);
+      return remove(key, oldValue);
+   }
+
+   public void clear(Options... options) {
+      getInvocationContext().setOptions(options);
+      clear();
+   }
+
+   public boolean containsKey(Object key, Options... options) {
+      getInvocationContext().setOptions(options);
+      return containsKey(key);
+   }
+
+   public V get(Object key, Options... options) {
+      getInvocationContext().setOptions(options);
+      return get(key);
+   }
+
    public ComponentStatus getCacheStatus() {
       return componentRegistry.getState();
    }
@@ -355,14 +363,6 @@
       batchContainer.endBatch(successful);
    }
 
-   public Object getDirect(Object key) {
-      throw new UnsupportedOperationException("Not implemented");//todo please implement!
-   }
-
-   public LockManager getLockManager() {
-      return lockManager;
-   }
-
    public String getName() {
       return name;
    }
@@ -371,10 +371,6 @@
       return Version.version;
    }
 
-   public void setName(String name) {
-      this.name = name;
-   }
-
    @Override
    public String toString() {
       return dataContainer == null ? super.toString() : dataContainer.toString();
@@ -383,9 +379,10 @@
    public AtomicMap getAtomicMap(K key) throws ClassCastException {
       Object value = get(key);
       if (value == null) value = AtomicHashMap.newInstance(this, key);
-      return ((AtomicHashMap) value).getProxy(this, key);
+      return ((AtomicHashMap) value).getProxy(this, key, batchContainer, invocationContextContainer);
    }
 
+   @SuppressWarnings("unchecked")
    public <AMK, AMV> AtomicMap<AMK, AMV> getAtomicMap(K key, Class<AMK> atomicMapKeyType, Class<AMV> atomicMapValueType) throws ClassCastException {
       return getAtomicMap(key);
    }
@@ -394,33 +391,44 @@
       return batchContainer;
    }
 
+   public InvocationContextContainer getInvocationContextContainer() {
+      return invocationContextContainer;
+   }
+
    public CacheManager getCacheManager() {
       return cacheManager;
    }
 
+   @SuppressWarnings("unchecked")
    public V put(K key, V value, long lifespan, TimeUnit unit) {
       PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(key, value, unit.toMillis(lifespan));
-      return (V) invoker.invoke(buildCtx(), command);
+      return (V) invoker.invoke(getInvocationContext(), command);
    }
 
+   @SuppressWarnings("unchecked")
    public V putIfAbsent(K key, V value, long lifespan, TimeUnit unit) {
       PutKeyValueCommand command = commandsFactory.buildPutKeyValueCommand(key, value, unit.toMillis(lifespan));
       command.setPutIfAbsent(true);
-      return (V) invoker.invoke(buildCtx(), command);
+      return (V) invoker.invoke(getInvocationContext(), command);
    }
 
    public void putAll(Map<? extends K, ? extends V> map, long lifespan, TimeUnit unit) {
       PutMapCommand command = commandsFactory.buildPutMapCommand(map, unit.toMillis(lifespan));
-      invoker.invoke(buildCtx(), command);
+      invoker.invoke(getInvocationContext(), command);
    }
 
+   @SuppressWarnings("unchecked")
    public V replace(K key, V value, long lifespan, TimeUnit unit) {
       ReplaceCommand command = commandsFactory.buildReplaceCommand(key, null, value, unit.toMillis(lifespan));
-      return (V) invoker.invoke(buildCtx(), command);
+      return (V) invoker.invoke(getInvocationContext(), command);
    }
 
    public boolean replace(K key, V oldValue, V value, long lifespan, TimeUnit unit) {
       ReplaceCommand command = commandsFactory.buildReplaceCommand(key, oldValue, value, unit.toMillis(lifespan));
-      return (Boolean) invoker.invoke(buildCtx(), command);
+      return (Boolean) invoker.invoke(getInvocationContext(), command);
    }
+
+   public AdvancedCache<K, V> getAdvancedCache() {
+      return this;
+   }
 }

Deleted: core/branches/flat/src/main/java/org/horizon/CacheSPI.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/CacheSPI.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/CacheSPI.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,181 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon;
-
-import net.jcip.annotations.ThreadSafe;
-import org.horizon.batch.BatchContainer;
-import org.horizon.eviction.EvictionManager;
-import org.horizon.factories.ComponentRegistry;
-import org.horizon.interceptors.base.CommandInterceptor;
-import org.horizon.loader.CacheLoader;
-import org.horizon.loader.CacheLoaderManager;
-import org.horizon.lock.LockManager;
-import org.horizon.marshall.Marshaller;
-import org.horizon.notifications.cachelistener.CacheNotifier;
-import org.horizon.remoting.RPCManager;
-import org.horizon.statetransfer.StateTransferManager;
-import org.horizon.transaction.GlobalTransaction;
-import org.horizon.transaction.TransactionTable;
-
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.List;
-
-/**
- * A more detailed interface to {@link Cache}, which is used when writing plugins for or extending JBoss Cache.  A
- * reference to this interface should only be obtained when it is passed in to your code, for example when you write an
- * {@link org.horizon.interceptors.base.CommandInterceptor} or {@link CacheLoader}.
- * <p/>
- * <B><I>You should NEVER attempt to directly cast a {@link Cache} instance to this interface.  In future, the
- * implementation may not allow it.</I></B>
- * <p/>
- *
- * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- * @see Cache
- * @see CacheLoader
- * @since 1.0
- */
- at ThreadSafe
-public interface CacheSPI<K, V> extends Cache<K, V> {
-   /**
-    * Retrieves a reference to a running {@link javax.transaction.TransactionManager}, if one is configured.
-    * <p/>
-    * From 2.1.0, Interceptor authors should obtain this by injection rather than this method.  See the {@link
-    * org.horizon.factories.annotations.Inject} annotation.
-    *
-    * @return a TransactionManager
-    */
-   TransactionManager getTransactionManager();
-
-   /**
-    * Retrieves the current Interceptor chain.
-    * <p/>
-    * From 2.1.0, Interceptor authors should obtain this by injection rather than this method.  See the {@link
-    * org.horizon.factories.annotations.Inject} annotation.
-    *
-    * @return an immutable {@link List} of {@link org.horizon.interceptors.base.CommandInterceptor}s configured for this
-    *         cache
-    */
-   List<CommandInterceptor> getInterceptorChain();
-
-   /**
-    * Retrieves an instance of a {@link Marshaller}, which is capable of converting Java objects to bytestreams and back
-    * in an efficient manner, which is also interoperable with bytestreams produced/consumed by other versions of JBoss
-    * Cache.
-    * <p/>
-    * The use of this marshaller is the <b>recommended</b> way of creating efficient, compatible, byte streams from
-    * objects.
-    * <p/>
-    * From 2.1.0, Interceptor authors should obtain this by injection rather than this method.  See the {@link
-    * org.horizon.factories.annotations.Inject} annotation.
-    *
-    * @return an instance of {@link Marshaller}
-    */
-   Marshaller getMarshaller();
-
-   /**
-    * Retrieves the current CacheCacheLoaderManager instance associated with the current Cache instance.
-    * <p/>
-    * From 2.1.0, Interceptor authors should obtain this by injection rather than this method.  See the {@link
-    * org.horizon.factories.annotations.Inject} annotation.
-    *
-    * @return Retrieves a reference to the currently configured {@link CacheLoaderManager} if one or more cache loaders
-    *         are configured, null otherwise.
-    */
-   CacheLoaderManager getCacheLoaderManager();
-
-   /**
-    * Retrieves the current TransactionTable instance associated with the current Cache instance.
-    * <p/>
-    * From 2.1.0, Interceptor authors should obtain this by injection rather than this method.  See the {@link
-    * org.horizon.factories.annotations.Inject} annotation.
-    *
-    * @return the current {@link TransactionTable}
-    */
-   TransactionTable getTransactionTable();
-
-
-   EvictionManager getEvictionManager();
-
-   /**
-    * Gets a handle of the RPC manager.
-    * <p/>
-    * From 2.1.0, Interceptor authors should obtain this by injection rather than this method.  See the {@link
-    * org.horizon.factories.annotations.Inject} annotation.
-    *
-    * @return the {@link RPCManager} configured.
-    */
-   RPCManager getRPCManager();
-
-   /**
-    * Retrieves the current StateTransferManager instance associated with the current Cache instance.
-    * <p/>
-    * From 2.1.0, Interceptor authors should obtain this by injection rather than this method.  See the {@link
-    * org.horizon.factories.annotations.Inject} annotation.
-    *
-    * @return the current {@link org.horizon.statetransfer.StateTransferManager}
-    */
-   StateTransferManager getStateTransferManager();
-
-   /**
-    * Retrieves the current Notifier instance associated with the current Cache instance.
-    * <p/>
-    * From 2.1.0, Interceptor authors should obtain this by injection rather than this method.  See the {@link
-    * org.horizon.factories.annotations.Inject} annotation.
-    *
-    * @return the notifier attached with this instance of the cache.  See {@link org.horizon.notifications.cachelistener.CacheNotifier},
-    *         a class that is responsible for emitting notifications to registered CacheListeners.
-    */
-   CacheNotifier getNotifier();
-
-   /**
-    * Returns the global transaction for this local transaction. Optionally creates a new global transaction if it does
-    * not exist.
-    *
-    * @param tx                the current transaction
-    * @param createIfNotExists if true creates a new transaction if none exists
-    * @return a GlobalTransaction
-    */
-   GlobalTransaction getCurrentTransaction(Transaction tx, boolean createIfNotExists);
-
-   /**
-    * Returns the transaction associated with the current thread. If a local transaction exists, but doesn't yet have a
-    * mapping to a GlobalTransaction, a new GlobalTransaction will be created and mapped to the local transaction.  Note
-    * that if a local transaction exists, but is not ACTIVE or PREPARING, null is returned.
-    *
-    * @return A GlobalTransaction, or null if no (local) transaction was associated with the current thread
-    */
-   GlobalTransaction getCurrentTransaction();
-
-   /**
-    * Returns the component registry associated with this cache instance.
-    *
-    * @see org.horizon.factories.ComponentRegistry
-    */
-   ComponentRegistry getComponentRegistry();
-
-   Object getDirect(Object key);
-
-   LockManager getLockManager();
-
-   BatchContainer getBatchContainer();
-}

Modified: core/branches/flat/src/main/java/org/horizon/atomic/AtomicHashMap.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/atomic/AtomicHashMap.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/atomic/AtomicHashMap.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -23,6 +23,8 @@
 
 import net.jcip.annotations.NotThreadSafe;
 import org.horizon.Cache;
+import org.horizon.batch.BatchContainer;
+import org.horizon.invocation.InvocationContextContainer;
 import org.horizon.util.FastCopyHashMap;
 
 import java.util.Collection;
@@ -125,12 +127,14 @@
       return delegate.entrySet();
    }
 
-   public AtomicMap getProxy(Cache cache, Object mapKey) {
+   public AtomicMap getProxy(Cache cache, Object mapKey,
+                             BatchContainer batchContainer, InvocationContextContainer invocationContextContainer) {
       // construct the proxy lazily
       if (proxy == null)  // DCL is OK here since proxy is volatile (and we live in a post-JDK 5 world)
       {
          synchronized (this) {
-            if (proxy == null) proxy = new AtomicHashMapProxy(cache, mapKey);
+            if (proxy == null)
+               proxy = new AtomicHashMapProxy(cache, mapKey, batchContainer, invocationContextContainer);
          }
       }
       return proxy;

Modified: core/branches/flat/src/main/java/org/horizon/atomic/AtomicHashMapProxy.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/atomic/AtomicHashMapProxy.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/atomic/AtomicHashMapProxy.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -22,8 +22,10 @@
 package org.horizon.atomic;
 
 import org.horizon.Cache;
-import org.horizon.CacheSPI;
 import org.horizon.batch.AutoBatchSupport;
+import org.horizon.batch.BatchContainer;
+import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.invocation.Options;
 
 import java.util.Collection;
 import java.util.Map;
@@ -38,11 +40,13 @@
 public class AtomicHashMapProxy<K, V> extends AutoBatchSupport implements AtomicMap<K, V> {
    Object deltaMapKey;
    Cache cache;
+   InvocationContextContainer icc;
 
-   public AtomicHashMapProxy(Cache cache, Object deltaMapKey) {
+   public AtomicHashMapProxy(Cache cache, Object deltaMapKey, BatchContainer batchContainer, InvocationContextContainer icc) {
       this.cache = cache;
       this.deltaMapKey = deltaMapKey;
-      this.batchContainer = ((CacheSPI) cache).getBatchContainer();
+      this.batchContainer = batchContainer;
+      this.icc = icc;
    }
 
    // internal helper, reduces lots of casts.
@@ -55,23 +59,22 @@
          return (AtomicHashMap<K, V>) cache.get(deltaMapKey);
       } else {
          // acquire WL
-         boolean suppressLocks = cache.getInvocationContext().getOptionOverrides().isSuppressLocking();
-         if (!suppressLocks) {
-            cache.getInvocationContext().getOptionOverrides().setForceWriteLock(true);
-         }
+         boolean suppressLocks = icc.get().hasOption(Options.SKIP_LOCKING);
+         if (!suppressLocks) icc.get().setOptions(Options.FORCE_WRITE_LOCK);
+
          AtomicHashMap map = getDeltaMapForRead();
          // copy for write
          AtomicHashMap copy = map == null ? new AtomicHashMap() : map.copyForWrite();
          copy.initForWriting();
          // reinstate the option
-         cache.getInvocationContext().getOptionOverrides().setSuppressLocking(suppressLocks);
+         if (suppressLocks) icc.get().setOptions(Options.SKIP_LOCKING);
          cache.put(deltaMapKey, copy);
          return copy;
       }
    }
 
    private boolean ownsLock() {
-      return cache.getInvocationContext().hasLockedKey(deltaMapKey);
+      return icc.get().hasLockedKey(deltaMapKey);
    }
 
    // readers

Modified: core/branches/flat/src/main/java/org/horizon/commands/CommandsFactoryImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/commands/CommandsFactoryImpl.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/commands/CommandsFactoryImpl.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,7 +21,7 @@
  */
 package org.horizon.commands;
 
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
 import org.horizon.commands.read.GetKeyValueCommand;
 import org.horizon.commands.read.SizeCommand;
 import org.horizon.commands.remote.ReplicateCommand;
@@ -51,13 +51,13 @@
 public class CommandsFactoryImpl implements CommandsFactory {
    private DataContainer dataContainer;
    private CacheNotifier notifier;
-   private CacheSPI cache;
+   private Cache cache;
 
    // some stateless commands can be reused so that they aren't constructed again all the time.
    SizeCommand cachedSizeCommand;
 
    @Inject
-   public void setupDependencies(DataContainer container, CacheNotifier notifier, CacheSPI cache) {
+   public void setupDependencies(DataContainer container, CacheNotifier notifier, Cache cache) {
       this.dataContainer = container;
       this.notifier = notifier;
       this.cache = cache;

Deleted: core/branches/flat/src/main/java/org/horizon/config/Option.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/Option.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/config/Option.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,322 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.config;
-
-
-/**
- * Used to override characteristics of specific calls to the cache.  The javadocs of each of the setters below detail
- * functionality and behaviour.
- *
- * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
- * @since 1.0
- */
-public class Option {
-   private boolean failSilently;
-   private boolean cacheModeLocal;
-   private boolean suppressLocking;
-
-   private boolean forceWriteLock;
-   private boolean skipCacheStatusCheck;
-
-   private boolean forceAsynchronous;
-   private boolean forceSynchronous;
-
-   private long syncReplTimeout = -1;
-   private int lockAcquisitionTimeout = -1;
-   private boolean suppressPersistence;
-
-   /**
-    * @since 1.0
-    */
-   public boolean isSuppressLocking() {
-      return suppressLocking;
-   }
-
-   /**
-    * Suppresses acquiring locks for the given invocation.  Used with pessimistic locking only.  Use with extreme care,
-    * may lead to a breach in data integrity!
-    *
-    * @since 1.0
-    */
-   public void setSuppressLocking(boolean suppressLocking) {
-      this.suppressLocking = suppressLocking;
-   }
-
-
-   /**
-    * @since 1.0
-    */
-   public boolean isFailSilently() {
-      return failSilently;
-   }
-
-   /**
-    * suppress any failures in your cache operation, including version mismatches with optimistic locking, timeouts
-    * obtaining locks, transaction rollbacks.  If this is option is set, the method invocation will __never fail or
-    * throw an exception__, although it may not succeed.  With this option enabled the call will <b>not</b> participate
-    * in any ongoing transactions even if a transaction is running.
-    *
-    * @since 1.0
-    */
-   public void setFailSilently(boolean failSilently) {
-      this.failSilently = failSilently;
-   }
-
-   /**
-    * only applies to put() and remove() methods on the cache.
-    *
-    * @since 1.0
-    */
-   public boolean isCacheModeLocal() {
-      return cacheModeLocal;
-   }
-
-   /**
-    * overriding CacheMode from REPL_SYNC, REPL_ASYNC, INVALIDATION_SYNC, INVALIDATION_ASYNC to LOCAL.  Only applies to
-    * put() and remove() methods on the cache.
-    *
-    * @param cacheModeLocal
-    * @since 1.0
-    */
-   public void setCacheModeLocal(boolean cacheModeLocal) {
-      this.cacheModeLocal = cacheModeLocal;
-   }
-
-   /**
-    * Gets whether replication or invalidation should be done asynchronously, even if the cache is configured in a
-    * synchronous mode.  Has no effect if the call is occuring within a transactional context.
-    *
-    * @return <code>true</code> if replication/invalidation should be done asynchronously; <code>false</code> if the
-    *         default mode configured for the cache should be used.
-    */
-   public boolean isForceAsynchronous() {
-      return forceAsynchronous;
-   }
-
-   /**
-    * Sets whether replication or invalidation should be done asynchronously, even if the cache is configured in a
-    * synchronous mode.  Has no effect if the call is occuring within a transactional context.
-    *
-    * @param forceAsynchronous <code>true</code> if replication/invalidation should be done asynchronously;
-    *                          <code>false</code> if the default mode configured for the cache should be used.
-    */
-   public void setForceAsynchronous(boolean forceAsynchronous) {
-      this.forceAsynchronous = forceAsynchronous;
-   }
-
-   /**
-    * Gets whether replication or invalidation should be done synchronously, even if the cache is configured in an
-    * asynchronous mode.  Has no effect if the call is occuring within a transactional context.
-    *
-    * @return <code>true</code> if replication/invalidation should be done synchronously; <code>false</code> if the
-    *         default mode configured for the cache should be used.
-    */
-   public boolean isForceSynchronous() {
-      return forceSynchronous;
-   }
-
-   /**
-    * Sets whether replication or invalidation should be done synchronously, even if the cache is configured in an
-    * asynchronous mode.  Has no effect if the call is occuring within a transactional context.
-    *
-    * @param forceSynchronous <code>true</code> if replication/invalidation should be done synchronously;
-    *                         <code>false</code> if the default mode configured for the cache should be used.
-    */
-   public void setForceSynchronous(boolean forceSynchronous) {
-      this.forceSynchronous = forceSynchronous;
-   }
-
-   /**
-    * Gets any lock acquisition timeout configured for the call.
-    *
-    * @return the time in ms that lock acquisition attempts should block before failing with a TimeoutException.  A
-    *         value < 0 indicates that the cache's default timeout should be used.
-    */
-   public int getLockAcquisitionTimeout() {
-      return lockAcquisitionTimeout;
-   }
-
-   /**
-    * Sets any lock acquisition timeout configured for the call.
-    *
-    * @param lockAcquisitionTimeout the time in ms that lock acquisition attempts should block before failing with a
-    *                               TimeoutException.  A value < 0 indicates that the cache's default timeout should be
-    *                               used.
-    */
-   public void setLockAcquisitionTimeout(int lockAcquisitionTimeout) {
-      this.lockAcquisitionTimeout = lockAcquisitionTimeout;
-   }
-
-   @Override
-   public String toString() {
-      return "Option{" +
-            "failSilently=" + failSilently +
-            ", cacheModeLocal=" + cacheModeLocal +
-            ", suppressLocking=" + suppressLocking +
-            ", lockAcquisitionTimeout=" + lockAcquisitionTimeout +
-            ", forceAsynchronous=" + forceAsynchronous +
-            ", forceSynchronous=" + forceSynchronous +
-            '}';
-   }
-
-   /**
-    * @return a new Option instance with all fields shallow-copied.
-    */
-   public Option copy() {
-      try {
-         return (Option) super.clone();
-      }
-      catch (CloneNotSupportedException e) {
-         // should never happen
-         throw new RuntimeException(e);
-      }
-   }
-
-
-   @Override
-   public boolean equals(Object o) {
-      if (this == o) return true;
-      if (o == null || getClass() != o.getClass()) return false;
-
-      final Option option = (Option) o;
-
-      if (cacheModeLocal != option.cacheModeLocal) return false;
-      if (failSilently != option.failSilently) return false;
-      if (suppressLocking != option.suppressLocking) return false;
-      if (forceWriteLock != option.forceWriteLock) return false;
-      if (forceAsynchronous != option.forceAsynchronous) return false;
-      if (forceSynchronous != option.forceSynchronous) return false;
-      if (lockAcquisitionTimeout != option.lockAcquisitionTimeout) return false;
-      if (suppressPersistence != option.suppressPersistence) return false;
-      return true;
-   }
-
-   @Override
-   public int hashCode() {
-      int result;
-      result = (failSilently ? 1 : 0);
-      result = 29 * result + (cacheModeLocal ? 1 : 0);
-      result = 29 * result + (suppressLocking ? 1 : 0);
-      result = 29 * result + (forceWriteLock ? 0 : 1);
-      result = 29 * result + (forceAsynchronous ? 0 : 1);
-      result = 29 * result + (forceSynchronous ? 0 : 1);
-      result = 29 * result + (lockAcquisitionTimeout);
-      result = 29 * result + (suppressPersistence ? 0 : 1);
-      return result;
-   }
-
-   /**
-    * Resets this option to defaults.
-    */
-   public void reset() {
-      this.cacheModeLocal = false;
-      this.failSilently = false;
-      this.suppressLocking = false;
-      this.forceWriteLock = false;
-      this.forceAsynchronous = false;
-      this.forceSynchronous = false;
-      this.lockAcquisitionTimeout = -1;
-      this.suppressPersistence = false;
-   }
-
-   /**
-    * Forces a write lock to be acquired on the call, regardless of whether it is a read or write.
-    *
-    * @param forceWriteLock
-    * @since 1.0
-    */
-   public void setForceWriteLock(boolean forceWriteLock) {
-      this.forceWriteLock = forceWriteLock;
-   }
-
-
-   /**
-    * Tests whether a write lock has been forced on the call, regardless of whether it is a read or write.
-    *
-    * @since 1.0
-    */
-   public boolean isForceWriteLock() {
-      return forceWriteLock;
-   }
-
-   /**
-    * If set to true, cache lifecycle checks will be skipped.  DO NOT USE unless you really know what you're doing.
-    *
-    * @since 1.0
-    */
-   public void setSkipCacheStatusCheck(boolean skipCacheStatusCheck) {
-      this.skipCacheStatusCheck = skipCacheStatusCheck;
-   }
-
-   /**
-    * @return true if skipCacheStatusCheck is true
-    * @since 1.0
-    */
-   public boolean isSkipCacheStatusCheck() {
-      return skipCacheStatusCheck;
-   }
-
-   /**
-    * @return the value of the sync replication timeout (used when cache mode is either {@link
-    *         org.horizon.config.Configuration.CacheMode#REPL_SYNC} or {@link org.horizon.config.Configuration.CacheMode#INVALIDATION_SYNC})
-    *         to be used for this specific call, or -1 (default) if the default value in {@link
-    *         Configuration#getSyncReplTimeout()} is to be used instead.
-    * @since 1.0
-    */
-   public long getSyncReplTimeout() {
-      return syncReplTimeout;
-   }
-
-   /**
-    * Used to override the value in {@link Configuration#getSyncReplTimeout()} (used when cache mode is either {@link
-    * org.horizon.config.Configuration.CacheMode#REPL_SYNC} or {@link org.horizon.config.Configuration.CacheMode#INVALIDATION_SYNC})
-    * for this specific invocation.  Defaults to -1, which means use the default in the configuration.
-    *
-    * @param syncReplTimeout new timeout value for this invocation.
-    * @since 1.0
-    */
-   public void setSyncReplTimeout(long syncReplTimeout) {
-      this.syncReplTimeout = syncReplTimeout;
-   }
-
-   /**
-    * If set to true, any persistence to a cache loader will be suppressed for the current invocation only.  Does not
-    * apply to transactional calls.
-    *
-    * @return true if persistence is suppressed.
-    * @since 1.0
-    */
-   public boolean isSuppressPersistence() {
-      return suppressPersistence;
-   }
-
-   /**
-    * If set to true, any persistence to a cache loader will be suppressed for the current invocation only.  Does not
-    * apply to transactional calls.
-    *
-    * @param suppressPersistence if true, will suppress persistence.
-    * @since 1.0
-    */
-   public void setSuppressPersistence(boolean suppressPersistence) {
-      this.suppressPersistence = suppressPersistence;
-   }
-}

Added: core/branches/flat/src/main/java/org/horizon/context/AbstractContext.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/context/AbstractContext.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/context/AbstractContext.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -0,0 +1,188 @@
+package org.horizon.context;
+
+import org.horizon.container.MVCCEntry;
+import org.horizon.invocation.Options;
+import org.horizon.util.FastCopyHashMap;
+import org.horizon.util.Immutables;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Common features of transaction and invocation contexts
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public abstract class AbstractContext {
+
+   protected EnumSet<Options> options;
+   protected byte contextFlags;
+   /**
+    * LinkedHashSet of locks acquired by the invocation. We use a LinkedHashSet because we need efficient Set semantics
+    * but also need guaranteed ordering for use by lock release code (see JBCCACHE-874).
+    */
+   protected LinkedHashSet<Object> locks;
+   protected FastCopyHashMap<Object, MVCCEntry> lookedUpEntries = null;
+
+
+   protected static enum ContextFlags {
+      FORCE_SYNCHRONOUS(0x1), FORCE_ASYNCHRONOUS(0x2), ORIGIN_LOCAL(0x4), LOCAL_ROLLBACK_ONLY(0x8);
+      final byte mask;
+
+      ContextFlags(int mask) {
+         this.mask = (byte) mask;
+      }
+   }
+
+   protected final boolean isFlagSet(ContextFlags flag) {
+      return (contextFlags & flag.mask) != 0;
+   }
+
+   protected final void setFlag(ContextFlags flag) {
+      contextFlags |= flag.mask;
+   }
+
+   protected final void unsetFlag(ContextFlags flag) {
+      contextFlags &= ~flag.mask;
+   }
+
+   protected final void setFlag(ContextFlags flag, boolean value) {
+      if (value)
+         setFlag(flag);
+      else
+         unsetFlag(flag);
+   }
+
+   public boolean hasOption(Options o) {
+      return options != null && options.contains(o);
+   }
+
+   public Set<Options> getOptions() {
+      return options;
+   }
+
+   public void setOptions(Options... options) {
+      if (options == null || options.length == 0) return;
+      if (this.options == null)
+         this.options = EnumSet.copyOf(Arrays.asList(options));
+      else
+         this.options.addAll(Arrays.asList(options));
+   }
+
+   public void setOptions(Collection<Options> options) {
+      if (options == null || options.size() == 0) return;
+      if (this.options == null)
+         this.options = EnumSet.copyOf(options);
+      else
+         this.options.addAll(options);
+   }
+
+   public void resetOptions() {
+      options = null;
+   }
+
+   public boolean isOptionsUninit() {
+      return options == null;
+   }
+
+   protected abstract int getLockSetSize();
+
+   public void addKeyLocked(Object lock) {
+      // no need to worry about concurrency here - a context is only valid for a single thread.
+      if (locks == null) locks = new LinkedHashSet<Object>(getLockSetSize());
+      locks.add(lock);
+   }
+
+   public void removeKeyLocked(Object lock) {
+      if (locks != null) locks.remove(lock);
+   }
+
+   public void clearKeysLocked() {
+      if (locks != null) locks.clear();
+   }
+
+   public void addAllKeysLocked(List<Object> newLocks) {
+      // no need to worry about concurrency here - a context is only valid for a single thread.
+      if (locks == null) locks = new LinkedHashSet<Object>(getLockSetSize());
+      locks.addAll(newLocks);
+   }
+
+   public List<Object> getKeysLocked() {
+      return locks == null || locks.isEmpty() ? Collections.emptyList() : Immutables.immutableListConvert(locks);
+   }
+
+   public boolean hasLockedKey(Object lock) {
+      return locks != null && locks.contains(lock);
+   }
+
+   public MVCCEntry lookupEntry(Object key) {
+      return lookedUpEntries.get(key);
+   }
+
+   public void removeLookedUpEntry(Object key) {
+      lookedUpEntries.remove(key);
+   }
+
+   public void putLookedUpEntry(Object key, MVCCEntry entry) {
+      lookedUpEntries.put(key, entry);
+   }
+
+   public void clearLookedUpEntries() {
+      lookedUpEntries.clear();
+   }
+
+   public Map<Object, MVCCEntry> getLookedUpEntries() {
+      return lookedUpEntries;
+   }
+
+   public void putLookedUpEntries(Map<Object, MVCCEntry> lookedUpEntries) {
+      lookedUpEntries.putAll(lookedUpEntries);
+   }
+
+   public void reset() {
+      if (lookedUpEntries != null) lookedUpEntries.clear();
+      if (locks != null) locks.clear();
+      options = null;
+      contextFlags = 0;
+   }
+
+   @Override
+   public boolean equals(Object o) {
+      if (this == o) return true;
+      if (!(o instanceof AbstractContext)) return false;
+
+      AbstractContext that = (AbstractContext) o;
+
+      if (contextFlags != that.contextFlags) return false;
+      if (locks != null ? !locks.equals(that.locks) : that.locks != null) return false;
+      if (lookedUpEntries != null ? !lookedUpEntries.equals(that.lookedUpEntries) : that.lookedUpEntries != null)
+         return false;
+      if (options != null ? !options.equals(that.options) : that.options != null) return false;
+
+      return true;
+   }
+
+   @Override
+   public int hashCode() {
+      int result = options != null ? options.hashCode() : 0;
+      result = 31 * result + (int) contextFlags;
+      result = 31 * result + (locks != null ? locks.hashCode() : 0);
+      result = 31 * result + (lookedUpEntries != null ? lookedUpEntries.hashCode() : 0);
+      return result;
+   }
+
+   @SuppressWarnings("unchecked")
+   protected void copyInto(AbstractContext ctx) {
+      if (options != null) ctx.options = EnumSet.copyOf(options);
+      ctx.contextFlags = contextFlags;
+      if (locks != null) ctx.locks = new LinkedHashSet<Object>(locks);
+      if (lookedUpEntries != null) ctx.lookedUpEntries = (FastCopyHashMap<Object, MVCCEntry>) lookedUpEntries.clone();
+   }
+}

Modified: core/branches/flat/src/main/java/org/horizon/context/EntryLookup.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/context/EntryLookup.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/context/EntryLookup.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -23,6 +23,7 @@
 
 import org.horizon.container.MVCCEntry;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -32,15 +33,108 @@
  * @since 1.0
  */
 public interface EntryLookup {
+   /**
+    * Retrieves an entry from the collection of looked up entries in the current scope.
+    * <p/>
+    * If a transaction is in progress, implementations should delegate to {@link org.horizon.context.TransactionContext#lookupEntry(Object)}
+    * <p/>
+    *
+    * @param key key to look up
+    * @return an entry, or null if it cannot be found.
+    */
    MVCCEntry lookupEntry(Object key);
 
+   /**
+    * Retrieves a map of entries looked up within the current scope.
+    * <p/>
+    * If a transaction is in progress, implementations should delegate to {@link org.horizon.context.TransactionContext#getLookedUpEntries()}.
+    * <p/>
+    *
+    * @return a map of looked up entries.
+    */
    Map<Object, MVCCEntry> getLookedUpEntries();
 
+   /**
+    * Puts an entry in the registry of looked up nodes in the current scope.
+    * <p/>
+    * If a transaction is in progress, implementations should delegate to {@link TransactionContext#putLookedUpEntry(Object,
+    * org.horizon.container.MVCCEntry)}
+    * <p/>
+    *
+    * @param key key to store
+    * @param e   entry to store
+    */
    void putLookedUpEntry(Object key, MVCCEntry e);
 
    void putLookedUpEntries(Map<Object, MVCCEntry> lookedUpEntries);
 
    void removeLookedUpEntry(Object key);
 
+   /**
+    * Clears the collection of entries looked up
+    */
    void clearLookedUpEntries();
+
+   /**
+    * Returns an immutable,  defensive copy of the List of locks currently maintained for the current scope.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should retrieve these locks from the {@link
+    * TransactionContext}. Retrieving locks from this method should always ensure they are retrieved from  the
+    * appropriate scope.
+    *
+    * @return keys locked in current scope.
+    */
+   List<Object> getKeysLocked();
+
+   /**
+    * Adds a List of locks to the currently maintained collection of locks acquired.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should record locks on the {@link TransactionContext}.
+    * Adding locks using this method should always ensure they are applied to the appropriate scope.
+    * <p/>
+    *
+    * @param keys keys locked
+    */
+   void addAllKeysLocked(List<Object> keys);
+
+   /**
+    * Adds a lock to the currently maintained collection of locks acquired.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should record this lock on the {@link TransactionContext}.
+    * Using this method should always ensure that the appropriate scope is used.
+    * <p/>
+    *
+    * @param key key that was locked
+    */
+   void addKeyLocked(Object key);
+
+   /**
+    * Removes a lock from the currently maintained collection of locks acquired.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should remove this lock from the {@link
+    * TransactionContext}. Using this method should always ensure that the lock is removed from the appropriate scope.
+    * <p/>
+    *
+    * @param key key that was unlocked
+    */
+   void removeKeyLocked(Object key);
+
+   /**
+    * Clears all locks from the currently maintained collection of locks acquired.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should clear locks from the {@link TransactionContext}.
+    * Using this method should always ensure locks are cleared in the appropriate scope.
+    * <p/>
+    */
+   void clearKeysLocked();
+
+   /**
+    * Note that if a transaction is in scope, implementations should test this lock from on {@link TransactionContext}.
+    * Using this method should always ensure locks checked in the appropriate scope.
+    *
+    * @param key lock to test
+    * @return true if the lock being tested is already held in the current scope, false otherwise.
+    */
+   boolean hasLockedKey(Object key);
+
 }

Modified: core/branches/flat/src/main/java/org/horizon/context/InvocationContext.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/context/InvocationContext.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/context/InvocationContext.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,19 +21,19 @@
  */
 package org.horizon.context;
 
-import org.horizon.config.Option;
 import org.horizon.transaction.GlobalTransaction;
 
 import javax.transaction.Transaction;
-import java.util.List;
 
 /**
- * // TODO: MANIK: Document this
+ * A context that contains information pertaining to a given invocation.  These contexts typically have the lifespan of
+ * a single invocation.
  *
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 1.0
  */
-public interface InvocationContext extends EntryLookup {
+public interface InvocationContext extends EntryLookup, OptionContainer {
+
    void setLocalRollbackOnly(boolean localRollbackOnly);
 
    Transaction getTransaction();
@@ -48,28 +48,8 @@
 
    void setGlobalTransaction(GlobalTransaction globalTransaction);
 
-   Option getOptionOverrides();
-
-   boolean isOptionsUninitialised();
-
-   void setOptionOverrides(Option optionOverrides);
-
    boolean isOriginLocal();
 
-   List<Object> getKeysLocked();
-
-   void addAllKeysLocked(List<Object> keysLocked);
-
-   void addKeyLocked(Object keyLocked);
-
-   void removeKeyLocked(Object keyLocked);
-
-   void clearKeysLocked();
-
-   boolean hasLockedKey(Object key);
-
-   boolean isLockingSuppressed();
-
    void setOriginLocal(boolean originLocal);
 
    boolean isLocalRollbackOnly();
@@ -80,9 +60,5 @@
 
    void setState(InvocationContext template);
 
-   long getLockAcquisitionTimeout(long timeout);
-
    boolean isValidTransaction();
-
-   void throwIfNeeded(Throwable e) throws Throwable;
 }

Modified: core/branches/flat/src/main/java/org/horizon/context/InvocationContextImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/context/InvocationContextImpl.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/context/InvocationContextImpl.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,55 +21,36 @@
  */
 package org.horizon.context;
 
-import org.horizon.config.Option;
 import org.horizon.container.MVCCEntry;
-import org.horizon.logging.Log;
-import org.horizon.logging.LogFactory;
 import org.horizon.transaction.GlobalTransaction;
 import org.horizon.transaction.TransactionTable;
 import org.horizon.util.FastCopyHashMap;
-import org.horizon.util.Immutables;
 
 import javax.transaction.Transaction;
 import java.util.Collections;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 
-/**
- * // TODO: MANIK: Document this
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 1.0
- */
-public class InvocationContextImpl implements InvocationContext {
-   private static final Log log = LogFactory.getLog(InvocationContext.class);
-   private static final boolean trace = log.isTraceEnabled();
-
+public class InvocationContextImpl extends AbstractContext implements InvocationContext {
    private Transaction transaction;
    private GlobalTransaction globalTransaction;
    protected volatile TransactionContext transactionContext;
-   private Option optionOverrides;
-   // defaults to true.
-   private boolean originLocal = true;
-   private boolean localRollbackOnly;
 
-   /**
-    * LinkedHashSet of locks acquired by the invocation. We use a LinkedHashSet because we need efficient Set semantics
-    * but also need guaranteed ordering for use by lock release code (see JBCCACHE-874).
-    */
-   protected LinkedHashSet<Object> invocationLocks;
-   private FastCopyHashMap<Object, MVCCEntry> lookedUpEntries = null;
+   public InvocationContextImpl() {
+      // set this to true by default
+      setFlag(ContextFlags.ORIGIN_LOCAL);
+   }
 
-   /**
-    * Retrieves a node from the registry of looked up nodes in the current scope.
-    * <p/>
-    * If a transaction is in progress, implementations should delegate to {@link org.horizon.context.TransactionContext#lookupEntry(Object)}
-    * <p/>
-    *
-    * @param k key to look up
-    * @return a node, or null if it cannot be found.
-    */
+   protected final int getLockSetSize() {
+      // always use 4 for invocation locks
+      return 4;
+   }
+
+   private void initLookedUpEntries() {
+      if (lookedUpEntries == null) lookedUpEntries = new FastCopyHashMap<Object, MVCCEntry>(4);
+   }
+
+   @Override
    public MVCCEntry lookupEntry(Object k) {
       if (transactionContext != null) {
          return transactionContext.lookupEntry(k);
@@ -78,6 +59,7 @@
       }
    }
 
+   @Override
    public void removeLookedUpEntry(Object key) {
       if (transactionContext != null) {
          transactionContext.removeLookedUpEntry(key);
@@ -86,50 +68,31 @@
       }
    }
 
-   /**
-    * Puts an entry in the registry of looked up nodes in the current scope.
-    * <p/>
-    * If a transaction is in progress, implementations should delegate to {@link TransactionContext#putLookedUpEntry(Object,
-    * org.horizon.container.MVCCEntry)}
-    * <p/>
-    *
-    * @param key
-    */
+   @Override
    public void putLookedUpEntry(Object key, MVCCEntry e) {
       if (transactionContext != null)
          transactionContext.putLookedUpEntry(key, e);
       else {
-         if (lookedUpEntries == null) lookedUpEntries = new FastCopyHashMap<Object, MVCCEntry>(4);
+         initLookedUpEntries();
          lookedUpEntries.put(key, e);
       }
    }
 
+   @Override
    public void putLookedUpEntries(Map<Object, MVCCEntry> lookedUpEntries) {
       if (transactionContext != null)
          transactionContext.putLookedUpEntries(lookedUpEntries);
       else {
-         if (this.lookedUpEntries == null)
-            this.lookedUpEntries = new FastCopyHashMap<Object, MVCCEntry>();
-
-         this.lookedUpEntries.putAll(lookedUpEntries);
+         initLookedUpEntries();
+         lookedUpEntries.putAll(lookedUpEntries);
       }
    }
 
-   /**
-    * Clears the registry of looked up nodes.
-    */
+   @Override
    public void clearLookedUpEntries() {
       if (lookedUpEntries != null) lookedUpEntries.clear();
    }
 
-   /**
-    * Retrieves a map of nodes looked up within the current invocation's scope.
-    * <p/>
-    * If a transaction is in progress, implementations should delegate to {@link org.horizon.context.TransactionContext#getLookedUpEntries()}.
-    * <p/>
-    *
-    * @return a map of looked up nodes.
-    */
    @SuppressWarnings("unchecked")
    public Map<Object, MVCCEntry> getLookedUpEntries() {
       if (transactionContext != null) return transactionContext.getLookedUpEntries();
@@ -139,8 +102,10 @@
    @SuppressWarnings("unchecked")
    public InvocationContext copy() {
       InvocationContextImpl copy = new InvocationContextImpl();
-      doCopy(copy);
-      if (lookedUpEntries != null) copy.lookedUpEntries = (FastCopyHashMap<Object, MVCCEntry>) lookedUpEntries.clone();
+      copyInto(copy);
+      copy.globalTransaction = globalTransaction;
+      copy.transaction = transaction;
+      copy.transactionContext = transactionContext;
       return copy;
    }
 
@@ -151,7 +116,7 @@
     * @param localRollbackOnly if true, the context is only rolling back.
     */
    public void setLocalRollbackOnly(boolean localRollbackOnly) {
-      this.localRollbackOnly = localRollbackOnly;
+      setFlag(ContextFlags.LOCAL_ROLLBACK_ONLY, localRollbackOnly);
    }
 
    /**
@@ -209,192 +174,95 @@
       this.globalTransaction = globalTransaction;
    }
 
-
    /**
-    * Retrieves the option overrides associated with this invocation
-    *
-    * @return the option overrides associated with this invocation
-    */
-   public Option getOptionOverrides() {
-      if (optionOverrides == null) {
-         optionOverrides = new Option();
-      }
-      return optionOverrides;
-   }
-
-   /**
-    * @return true of no options have been set on this context, false otherwise.
-    */
-   public boolean isOptionsUninitialised() {
-      return optionOverrides == null;
-   }
-
-   /**
-    * Sets the option overrides to be associated with this invocation
-    *
-    * @param optionOverrides options to set
-    */
-   public void setOptionOverrides(Option optionOverrides) {
-      this.optionOverrides = optionOverrides;
-   }
-
-   /**
     * Tests if this invocation originated locally or from a remote cache.
     *
     * @return true if the invocation originated locally.
     */
    public boolean isOriginLocal() {
-      return originLocal;
+      return isFlagSet(ContextFlags.ORIGIN_LOCAL);
    }
 
-   /**
-    * Returns an immutable,  defensive copy of the List of locks currently maintained for the current scope.
-    * <p/>
-    * Note that if a transaction is in scope, implementations should retrieve these locks from the {@link
-    * TransactionContext}. Retrieving locks from this method should always ensure they are retrieved from  the
-    * appropriate scope.
-    *
-    * @return locks held in current scope.
-    */
-   @SuppressWarnings("unchecked")
+   @Override
    public List<Object> getKeysLocked() {
       // first check transactional scope
       if (transactionContext != null) return transactionContext.getKeysLocked();
-      return invocationLocks == null || invocationLocks.isEmpty() ? Collections.emptyList() : Immutables.immutableListConvert(invocationLocks);
+      return super.getKeysLocked();
    }
 
-   /**
-    * Adds a List of locks to the currently maintained collection of locks acquired.
-    * <p/>
-    * Note that if a transaction is in scope, implementations should record locks on the {@link TransactionContext}.
-    * Adding locks using this method should always ensure they are applied to the appropriate scope.
-    * <p/>
-    *
-    * @param locks locks to add
-    */
-   @SuppressWarnings("unchecked")
-   public void addAllKeysLocked(List<Object> locks) {
+   @Override
+   public void addAllKeysLocked(List<Object> keys) {
       // first check transactional scope
-      if (transactionContext != null) {
-         transactionContext.addAllKeysLocked(locks);
-      } else {
-         // no need to worry about concurrency here - a context is only valid for a single thread.
-         if (invocationLocks == null) invocationLocks = new LinkedHashSet(4);
-         invocationLocks.addAll(locks);
-      }
+      if (transactionContext != null)
+         transactionContext.addAllKeysLocked(keys);
+      else
+         super.addAllKeysLocked(keys);
+
    }
 
-   /**
-    * Adds a lock to the currently maintained collection of locks acquired.
-    * <p/>
-    * Note that if a transaction is in scope, implementations should record this lock on the {@link TransactionContext}.
-    * Using this method should always ensure that the appropriate scope is used.
-    * <p/>
-    *
-    * @param lock lock to add
-    */
-   @SuppressWarnings("unchecked")
-   public void addKeyLocked(Object lock) {
+   @Override
+   public void addKeyLocked(Object key) {
       // first check transactional scope
-      if (transactionContext != null) {
-         transactionContext.addKeyLocked(lock);
-      } else {
-         // no need to worry about concurrency here - a context is only valid for a single thread.
-         if (invocationLocks == null) invocationLocks = new LinkedHashSet(4);
-         invocationLocks.add(lock);
-      }
+      if (transactionContext != null)
+         transactionContext.addKeyLocked(key);
+      else
+         super.addKeyLocked(key);
    }
 
-   /**
-    * Removes a lock from the currently maintained collection of locks acquired.
-    * <p/>
-    * Note that if a transaction is in scope, implementations should remove this lock from the {@link
-    * TransactionContext}. Using this method should always ensure that the lock is removed from the appropriate scope.
-    * <p/>
-    *
-    * @param lock lock to remove
-    */
-   @SuppressWarnings("unchecked")
-   public void removeKeyLocked(Object lock) {
+   @Override
+   public void removeKeyLocked(Object key) {
       // first check transactional scope
-      if (transactionContext != null) {
-         transactionContext.removeKeyLocked(lock);
-      } else {
-         // no need to worry about concurrency here - a context is only valid for a single thread.
-         if (invocationLocks != null) invocationLocks.remove(lock);
-      }
+      if (transactionContext != null)
+         transactionContext.removeKeyLocked(key);
+      else
+         super.removeKeyLocked(key);
    }
 
-   /**
-    * Clears all locks from the currently maintained collection of locks acquired.
-    * <p/>
-    * Note that if a transaction is in scope, implementations should clear locks from the {@link TransactionContext}.
-    * Using this method should always ensure locks are cleared in the appropriate scope.
-    * <p/>
-    */
+   @Override
    public void clearKeysLocked() {
       // first check transactional scope
-      if (transactionContext != null) {
+      if (transactionContext != null)
          transactionContext.clearKeysLocked();
-      } else {
-         // no need to worry about concurrency here - a context is only valid for a single thread.
-         if (invocationLocks != null) invocationLocks.clear();
-      }
+      else
+         super.clearKeysLocked();
    }
 
-   /**
-    * Note that if a transaction is in scope, implementations should test this lock from on {@link TransactionContext}.
-    * Using this method should always ensure locks checked in the appropriate scope.
-    *
-    * @param lock lock to test
-    * @return true if the lock being tested is already held in the current scope, false otherwise.
-    */
-   public boolean hasLockedKey(Object lock) {
+   @Override
+   public boolean hasLockedKey(Object key) {
       // first check transactional scope
-      if (transactionContext != null) {
-         return transactionContext.hasLockedKey(lock);
-      } else {
-         return invocationLocks != null && invocationLocks.contains(lock);
-      }
+      if (transactionContext != null)
+         return transactionContext.hasLockedKey(key);
+      else
+         return super.hasLockedKey(key);
    }
 
    /**
-    * @return true if options exist to suppress locking - false otherwise.
-    */
-   public boolean isLockingSuppressed() {
-      return getOptionOverrides() != null && getOptionOverrides().isSuppressLocking();
-   }
-
-   /**
     * If set to true, the invocation is assumed to have originated locally.  If set to false, assumed to have originated
     * from a remote cache.
     *
     * @param originLocal flag to set
     */
    public void setOriginLocal(boolean originLocal) {
-      this.originLocal = originLocal;
+      setFlag(ContextFlags.ORIGIN_LOCAL, originLocal);
    }
 
    /**
     * @return true if the current transaction is set to rollback only.
     */
    public boolean isLocalRollbackOnly() {
-      return localRollbackOnly;
+      return isFlagSet(ContextFlags.LOCAL_ROLLBACK_ONLY);
    }
 
    /**
     * Resets the context, freeing up any references.
     */
    public void reset() {
+      super.reset();
       transaction = null;
       globalTransaction = null;
-      optionOverrides = null;
-      originLocal = true;
-      invocationLocks = null;
-      if (lookedUpEntries != null) {
-         lookedUpEntries.clear();
-         lookedUpEntries = null;
-      }
+      transactionContext = null;
+      setFlag(ContextFlags.ORIGIN_LOCAL);
+      lookedUpEntries = null;
    }
 
    /**
@@ -409,28 +277,12 @@
 
       this.setGlobalTransaction(template.getGlobalTransaction());
       this.setLocalRollbackOnly(template.isLocalRollbackOnly());
-      this.setOptionOverrides(template.getOptionOverrides());
+      this.setOptions(template.getOptions());
       this.setOriginLocal(template.isOriginLocal());
       this.setTransaction(template.getTransaction());
    }
 
    /**
-    * If the lock acquisition timeout is overridden for current call using an option, then return that one. If not
-    * overridden, return default value.
-    *
-    * @param timeout timeout to fall back to
-    * @return timeout to use
-    */
-   public long getLockAcquisitionTimeout(long timeout) {
-      // TODO: this stuff really doesn't belong here.  Put it somewhere else.
-      if (getOptionOverrides() != null
-            && getOptionOverrides().getLockAcquisitionTimeout() >= 0) {
-         timeout = getOptionOverrides().getLockAcquisitionTimeout();
-      }
-      return timeout;
-   }
-
-   /**
     * @return true if there is current transaction associated with the invocation, and this transaction is in a valid
     *         state.
     */
@@ -439,53 +291,16 @@
       return transaction != null && TransactionTable.isValid(transaction);
    }
 
-   /**
-    * Throws the given throwable provided no options suppress or prevent this from happening.
-    *
-    * @param e throwable to throw
-    * @throws Throwable if allowed to throw one.
-    */
-   public void throwIfNeeded(Throwable e) throws Throwable {
-      // TODO: this stuff really doesn't belong here.  Put it somewhere else.
-      Option optionOverride = getOptionOverrides();
-      boolean shouldRethtrow = optionOverride == null || !optionOverride.isFailSilently();
-      if (!shouldRethtrow) {
-         if (trace)
-            log.trace("There was a problem handling this request, but failSilently was set, so suppressing exception", e);
-         return;
-      }
-      throw e;
-   }
-
-   @SuppressWarnings("unchecked")
-   protected void doCopy(InvocationContext c) {
-      InvocationContextImpl copy = (InvocationContextImpl) c;
-      copy.globalTransaction = globalTransaction;
-      copy.invocationLocks = invocationLocks == null ? null : new LinkedHashSet(invocationLocks);
-      copy.localRollbackOnly = localRollbackOnly;
-      copy.optionOverrides = optionOverrides == null ? null : optionOverrides.copy();
-      copy.originLocal = originLocal;
-      copy.transaction = transaction;
-      copy.transactionContext = transactionContext;
-   }
-
    @Override
    public boolean equals(Object o) {
       if (this == o) return true;
       if (o == null || getClass() != o.getClass()) return false;
+      if (!super.equals(o)) return false;
 
       InvocationContextImpl that = (InvocationContextImpl) o;
 
-      if (localRollbackOnly != that.localRollbackOnly) return false;
-      if (originLocal != that.originLocal) return false;
       if (globalTransaction != null ? !globalTransaction.equals(that.globalTransaction) : that.globalTransaction != null)
          return false;
-      if (invocationLocks != null ? !invocationLocks.equals(that.invocationLocks) : that.invocationLocks != null)
-         return false;
-      if (lookedUpEntries != null ? !lookedUpEntries.equals(that.lookedUpEntries) : that.lookedUpEntries != null)
-         return false;
-      if (optionOverrides != null ? !optionOverrides.equals(that.optionOverrides) : that.optionOverrides != null)
-         return false;
       if (transaction != null ? !transaction.equals(that.transaction) : that.transaction != null) return false;
       if (transactionContext != null ? !transactionContext.equals(that.transactionContext) : that.transactionContext != null)
          return false;
@@ -495,14 +310,10 @@
 
    @Override
    public int hashCode() {
-      int result = transaction != null ? transaction.hashCode() : 0;
+      int result = super.hashCode();
+      result = 31 * result + (transaction != null ? transaction.hashCode() : 0);
       result = 31 * result + (globalTransaction != null ? globalTransaction.hashCode() : 0);
       result = 31 * result + (transactionContext != null ? transactionContext.hashCode() : 0);
-      result = 31 * result + (optionOverrides != null ? optionOverrides.hashCode() : 0);
-      result = 31 * result + (originLocal ? 1 : 0);
-      result = 31 * result + (localRollbackOnly ? 1 : 0);
-      result = 31 * result + (invocationLocks != null ? invocationLocks.hashCode() : 0);
-      result = 31 * result + (lookedUpEntries != null ? lookedUpEntries.hashCode() : 0);
       return result;
    }
 
@@ -512,10 +323,9 @@
             "transaction=" + transaction +
             ", globalTransaction=" + globalTransaction +
             ", transactionContext=" + transactionContext +
-            ", optionOverrides=" + optionOverrides +
-            ", originLocal=" + originLocal +
-            ", localRollbackOnly=" + localRollbackOnly +
-            ", invocationLocks=" + invocationLocks +
+            ", options=" + options +
+            ", contextFlags=" + contextFlags +
+            ", invocationLocks=" + locks +
             ", lookedUpEntries=" + lookedUpEntries +
             '}';
    }

Added: core/branches/flat/src/main/java/org/horizon/context/OptionContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/context/OptionContainer.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/context/OptionContainer.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -0,0 +1,27 @@
+package org.horizon.context;
+
+import org.horizon.invocation.Options;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * Interface that defines access to and manipulation of {@link Options}.
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public interface OptionContainer {
+
+   boolean hasOption(Options o);
+
+   Set<Options> getOptions();
+
+   void setOptions(Options... options);
+
+   void setOptions(Collection<Options> options);
+
+   void resetOptions();
+
+   boolean isOptionsUninit();
+}

Modified: core/branches/flat/src/main/java/org/horizon/context/TransactionContext.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/context/TransactionContext.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/context/TransactionContext.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -22,23 +22,20 @@
 package org.horizon.context;
 
 import org.horizon.commands.VisitableCommand;
-import org.horizon.config.Option;
 import org.horizon.transaction.GlobalTransaction;
 
 import javax.transaction.Transaction;
 import java.util.List;
 
 /**
- * Captures information pertaining to a specific JTA transaction.
- * <p/>
- * This was a concrete class called TransactionEntry prior to 3.0.
- * <p/>
+ * A context that contains information pertaining to a given transaction.  These contexts typically have the lifespan of
+ * the entire transaction.
  *
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @see InvocationContext
  * @since 1.0
  */
-public interface TransactionContext extends EntryLookup {
+public interface TransactionContext extends EntryLookup, OptionContainer {
    /**
     * Adds a modification to the modification list.
     *
@@ -103,69 +100,6 @@
    Transaction getTransaction();
 
    /**
-    * Adds a lock to the currently maintained collection of locks acquired.
-    * <p/>
-    * Most code could not use this method directly, but use {@link InvocationContext#addKeyLocked(Object)} instead,
-    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
-    *
-    * @param lock lock to add
-    */
-   @SuppressWarnings("unchecked")
-   void addKeyLocked(Object lock);
-
-   /**
-    * Removes a lock from the currently maintained collection of locks acquired.
-    * <p/>
-    * Most code could not use this method directly, but use {@link InvocationContext#removeKeyLocked(Object)}  instead,
-    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
-    *
-    * @param lock lock to remove
-    */
-   @SuppressWarnings("unchecked")
-   void removeKeyLocked(Object lock);
-
-   /**
-    * Clears all locks from the currently maintained collection of locks acquired.
-    * <p/>
-    * Most code could not use this method directly, but use {@link InvocationContext#clearKeysLocked()} instead, which
-    * would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
-    */
-   void clearKeysLocked();
-
-   /**
-    * Adds a List of locks to the currently maintained collection of locks acquired.
-    * <p/>
-    * Most code could not use this method directly, but use {@link InvocationContext#addAllKeysLocked(java.util.List)}
-    * instead, which would delegate to this method if a transaction is in scope or otherwise use invocation-specific
-    * locks.
-    *
-    * @param newLocks locks to add
-    */
-   @SuppressWarnings("unchecked")
-   void addAllKeysLocked(List<Object> newLocks);
-
-   /**
-    * Returns an immutable,  defensive copy of the List of locks currently maintained for the transaction.
-    * <p/>
-    * Most code could not use this method directly, but use {@link org.horizon.context.InvocationContext#getKeysLocked()}
-    * instead, which would delegate to this method if a transaction is in scope or otherwise use invocation-specific
-    * locks.
-    *
-    * @return locks held in current scope.
-    */
-   @SuppressWarnings("unchecked")
-   List<Object> getKeysLocked();
-
-   /**
-    * Most code could not use this method directly, but use {@link InvocationContext#hasLockedKey(Object)} ()} instead,
-    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
-    *
-    * @param lock lock to test
-    * @return true if the lock being tested is already held in the current scope, false otherwise.
-    */
-   boolean hasLockedKey(Object lock);
-
-   /**
     * Gets the value of the forceAsyncReplication flag.
     *
     * @return true if the forceAsyncReplication flag is set to true.
@@ -206,20 +140,6 @@
    List<Object> getDummyEntriesCreatedByCacheLoader();
 
    /**
-    * Sets a transaction-scope option override
-    *
-    * @param o option to set
-    */
-   void setOption(Option o);
-
-   /**
-    * Retrieves a transaction scope option override
-    *
-    * @return option
-    */
-   Option getOption();
-
-   /**
     * @return true if modifications were registered.
     */
    boolean hasModifications();

Modified: core/branches/flat/src/main/java/org/horizon/context/TransactionContextImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/context/TransactionContextImpl.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/context/TransactionContextImpl.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -22,18 +22,15 @@
 package org.horizon.context;
 
 import org.horizon.commands.VisitableCommand;
-import org.horizon.config.Option;
 import org.horizon.container.MVCCEntry;
 import org.horizon.transaction.GlobalTransaction;
 import org.horizon.util.FastCopyHashMap;
-import org.horizon.util.Immutables;
 
 import javax.transaction.RollbackException;
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -44,14 +41,11 @@
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 1.0
  */
-public class TransactionContextImpl implements TransactionContext {
+public class TransactionContextImpl extends AbstractContext implements TransactionContext {
    /**
     * Local transaction
     */
    private Transaction ltx = null;
-   private Option option;
-   private boolean forceAsyncReplication = false;
-   private boolean forceSyncReplication = false;
 
    /**
     * List&lt;VisitableCommand&gt; of modifications. They will be replicated on TX commit
@@ -64,12 +58,6 @@
    private List<VisitableCommand> localModifications;
 
    /**
-    * LinkedHashSet of locks acquired by the transaction. We use a LinkedHashSet because we need efficient Set semantics
-    * but also need guaranteed ordering for use by lock release code (see JBCCACHE-874).
-    */
-   private LinkedHashSet<Object> transactionLocks;
-
-   /**
     * A list of dummy uninitialised entries created by the cache loader interceptor to load data for a given entry in
     * this tx.
     */
@@ -80,41 +68,25 @@
     */
    private List<Object> removedKeys = null;
 
-   private final FastCopyHashMap<Object, MVCCEntry> lookedUpEntries = new FastCopyHashMap<Object, MVCCEntry>(8);
    private GlobalTransaction gtx;
 
+   protected final int getLockSetSize() {
+      // always initialize the lock collection to 8 entries
+      return 8;
+   }
+
    public TransactionContextImpl(Transaction tx) throws SystemException, RollbackException {
       ltx = tx;
+      lookedUpEntries = new FastCopyHashMap<Object, MVCCEntry>(8);
    }
 
-   public MVCCEntry lookupEntry(Object key) {
-      return lookedUpEntries.get(key);
-   }
-
-   public void removeLookedUpEntry(Object key) {
-      lookedUpEntries.remove(key);
-   }
-
-   public void putLookedUpEntry(Object key, MVCCEntry entry) {
-      lookedUpEntries.put(key, entry);
-   }
-
-   public void clearLookedUpEntries() {
-      lookedUpEntries.clear();
-   }
-
-   public Map<Object, MVCCEntry> getLookedUpEntries() {
-      return lookedUpEntries;
-   }
-
    public void reset() {
+      super.reset();
       modificationList = null;
       localModifications = null;
-      option = null;
-      if (transactionLocks != null) transactionLocks.clear();
       if (dummyEntriesCreatedByCacheLoader != null) dummyEntriesCreatedByCacheLoader.clear();
       if (removedKeys != null) removedKeys.clear();
-      lookedUpEntries.clear();
+      lookedUpEntries = new FastCopyHashMap<Object, MVCCEntry>(8);
    }
 
    public GlobalTransaction getGobalTransaction() {
@@ -171,59 +143,22 @@
       return ltx;
    }
 
-   @SuppressWarnings("unchecked")
-   public void addKeyLocked(Object lock) {
-      // no need to worry about concurrency here - a context is only valid for a single thread.
-      if (transactionLocks == null) transactionLocks = new LinkedHashSet(5);
-      transactionLocks.add(lock);
-   }
-
-   @SuppressWarnings("unchecked")
-   public void removeKeyLocked(Object lock) {
-      // no need to worry about concurrency here - a context is only valid for a single thread.
-      if (transactionLocks != null) transactionLocks.remove(lock);
-   }
-
-   public void clearKeysLocked() {
-      if (transactionLocks != null) transactionLocks.clear();
-   }
-
-   @SuppressWarnings("unchecked")
-   public void addAllKeysLocked(List<Object> newLocks) {
-      // no need to worry about concurrency here - a context is only valid for a single thread.
-      if (transactionLocks == null) transactionLocks = new LinkedHashSet(5);
-      transactionLocks.addAll(newLocks);
-   }
-
-   @SuppressWarnings("unchecked")
-   public List<Object> getKeysLocked() {
-      return transactionLocks == null || transactionLocks.isEmpty() ? Collections.emptyList() : Immutables.immutableListConvert(transactionLocks);
-   }
-
-   public boolean hasLockedKey(Object lock) {
-      return transactionLocks != null && transactionLocks.contains(lock);
-   }
-
    public boolean isForceAsyncReplication() {
-      return forceAsyncReplication;
+      return isFlagSet(ContextFlags.FORCE_ASYNCHRONOUS);
    }
 
    public void setForceAsyncReplication(boolean forceAsyncReplication) {
-      this.forceAsyncReplication = forceAsyncReplication;
-      if (forceAsyncReplication) {
-         forceSyncReplication = false;
-      }
+      setFlag(ContextFlags.FORCE_ASYNCHRONOUS, forceAsyncReplication);
+      if (forceAsyncReplication) unsetFlag(ContextFlags.FORCE_SYNCHRONOUS);
    }
 
    public boolean isForceSyncReplication() {
-      return forceSyncReplication;
+      return isFlagSet(ContextFlags.FORCE_SYNCHRONOUS);
    }
 
    public void setForceSyncReplication(boolean forceSyncReplication) {
-      this.forceSyncReplication = forceSyncReplication;
-      if (forceSyncReplication) {
-         forceAsyncReplication = false;
-      }
+      setFlag(ContextFlags.FORCE_SYNCHRONOUS, forceSyncReplication);
+      if (forceSyncReplication) unsetFlag(ContextFlags.FORCE_ASYNCHRONOUS);
    }
 
    /**
@@ -247,14 +182,6 @@
       return dummyEntriesCreatedByCacheLoader;
    }
 
-   public void setOption(Option o) {
-      this.option = o;
-   }
-
-   public Option getOption() {
-      return this.option;
-   }
-
    public boolean hasModifications() {
       return modificationList != null && !modificationList.isEmpty();
    }
@@ -266,4 +193,37 @@
    public boolean hasAnyModifications() {
       return hasModifications() || hasLocalModifications();
    }
+
+   @Override
+   public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+      if (!super.equals(o)) return false;
+
+      TransactionContextImpl that = (TransactionContextImpl) o;
+
+      if (dummyEntriesCreatedByCacheLoader != null ? !dummyEntriesCreatedByCacheLoader.equals(that.dummyEntriesCreatedByCacheLoader) : that.dummyEntriesCreatedByCacheLoader != null)
+         return false;
+      if (gtx != null ? !gtx.equals(that.gtx) : that.gtx != null) return false;
+      if (localModifications != null ? !localModifications.equals(that.localModifications) : that.localModifications != null)
+         return false;
+      if (ltx != null ? !ltx.equals(that.ltx) : that.ltx != null) return false;
+      if (modificationList != null ? !modificationList.equals(that.modificationList) : that.modificationList != null)
+         return false;
+      if (removedKeys != null ? !removedKeys.equals(that.removedKeys) : that.removedKeys != null) return false;
+
+      return true;
+   }
+
+   @Override
+   public int hashCode() {
+      int result = super.hashCode();
+      result = 31 * result + (ltx != null ? ltx.hashCode() : 0);
+      result = 31 * result + (modificationList != null ? modificationList.hashCode() : 0);
+      result = 31 * result + (localModifications != null ? localModifications.hashCode() : 0);
+      result = 31 * result + (dummyEntriesCreatedByCacheLoader != null ? dummyEntriesCreatedByCacheLoader.hashCode() : 0);
+      result = 31 * result + (removedKeys != null ? removedKeys.hashCode() : 0);
+      result = 31 * result + (gtx != null ? gtx.hashCode() : 0);
+      return result;
+   }
 }

Modified: core/branches/flat/src/main/java/org/horizon/factories/BootstrapFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/BootstrapFactory.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/factories/BootstrapFactory.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,9 +21,9 @@
  */
 package org.horizon.factories;
 
+import org.horizon.AdvancedCache;
 import org.horizon.Cache;
 import org.horizon.CacheException;
-import org.horizon.CacheSPI;
 import org.horizon.config.Configuration;
 import org.horizon.factories.annotations.DefaultFactoryFor;
 import org.horizon.factories.annotations.NonVolatile;
@@ -34,22 +34,22 @@
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 1.0
  */
- at DefaultFactoryFor(classes = {Cache.class, CacheSPI.class, Configuration.class, ComponentRegistry.class})
+ at DefaultFactoryFor(classes = {Cache.class, AdvancedCache.class, Configuration.class, ComponentRegistry.class})
 @NonVolatile
 public class BootstrapFactory extends AbstractNamedCacheComponentFactory {
-   CacheSPI cacheSPI;
+   AdvancedCache advancedCache;
 
-   public BootstrapFactory(CacheSPI cacheSPI, Configuration configuration, ComponentRegistry componentRegistry) {
+   public BootstrapFactory(AdvancedCache advancedCache, Configuration configuration, ComponentRegistry componentRegistry) {
       this.componentRegistry = componentRegistry;
       this.configuration = configuration;
-      this.cacheSPI = cacheSPI;
+      this.advancedCache = advancedCache;
    }
 
    @Override
    public <T> T construct(Class<T> componentType) {
       Object comp = null;
-      if (componentType.isAssignableFrom(CacheSPI.class)) {
-         comp = cacheSPI;
+      if (componentType.isAssignableFrom(AdvancedCache.class)) {
+         comp = advancedCache;
       } else if (componentType.isAssignableFrom(Configuration.class)) {
          comp = configuration;
       } else if (componentType.isAssignableFrom(ComponentRegistry.class)) {

Modified: core/branches/flat/src/main/java/org/horizon/factories/ComponentRegistry.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/ComponentRegistry.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/factories/ComponentRegistry.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,7 +1,7 @@
 package org.horizon.factories;
 
+import org.horizon.AdvancedCache;
 import org.horizon.CacheException;
-import org.horizon.CacheSPI;
 import org.horizon.ComponentStatus;
 import org.horizon.config.Configuration;
 import org.horizon.config.ConfigurationException;
@@ -39,7 +39,7 @@
     * @param cache            cache
     * @param globalComponents Shared Component Registry to delegate to
     */
-   public ComponentRegistry(String cacheName, Configuration configuration, CacheSPI cache, GlobalComponentRegistry globalComponents) {
+   public ComponentRegistry(String cacheName, Configuration configuration, AdvancedCache cache, GlobalComponentRegistry globalComponents) {
 
       try {
          this.cacheName = cacheName;

Modified: core/branches/flat/src/main/java/org/horizon/factories/DefaultCacheFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/DefaultCacheFactory.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/factories/DefaultCacheFactory.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,9 +21,9 @@
  */
 package org.horizon.factories;
 
+import org.horizon.AdvancedCache;
 import org.horizon.Cache;
 import org.horizon.CacheDelegate;
-import org.horizon.CacheSPI;
 import org.horizon.config.Configuration;
 import org.horizon.config.ConfigurationException;
 import org.horizon.jmx.PlatformMBeanServerRegistration;
@@ -54,7 +54,7 @@
     */
    public Cache<K, V> createCache(Configuration configuration, GlobalComponentRegistry globalComponentRegistry, String cacheName) throws ConfigurationException {
       try {
-         CacheSPI<K, V> cache = createAndWire(configuration, globalComponentRegistry, cacheName);
+         AdvancedCache<K, V> cache = createAndWire(configuration, globalComponentRegistry, cacheName);
          cache.start();
          return cache;
       }
@@ -73,8 +73,8 @@
       return createCache(configuration, null, DefaultCacheManager.DEFAULT_CACHE_NAME);
    }
 
-   protected CacheSPI<K, V> createAndWire(Configuration configuration, GlobalComponentRegistry globalComponentRegistry, String cacheName) throws Exception {
-      CacheSPI<K, V> spi = new CacheDelegate<K, V>(cacheName);
+   protected AdvancedCache<K, V> createAndWire(Configuration configuration, GlobalComponentRegistry globalComponentRegistry, String cacheName) throws Exception {
+      AdvancedCache<K, V> spi = new CacheDelegate<K, V>(cacheName);
       bootstrap(cacheName, spi, configuration, globalComponentRegistry);
       return spi;
    }
@@ -82,13 +82,13 @@
    /**
     * Bootstraps this factory with a Configuration and a ComponentRegistry.
     */
-   private void bootstrap(String cacheName, CacheSPI spi, Configuration configuration, GlobalComponentRegistry globalComponentRegistry) {
+   private void bootstrap(String cacheName, AdvancedCache spi, Configuration configuration, GlobalComponentRegistry globalComponentRegistry) {
       this.configuration = configuration;
 
       // injection bootstrap stuff
       componentRegistry = new ComponentRegistry(cacheName, configuration, spi, globalComponentRegistry);
       componentRegistry.registerDefaultClassLoader(defaultClassLoader);
-      componentRegistry.registerComponent(spi, CacheSPI.class);
+      componentRegistry.registerComponent(spi, AdvancedCache.class);
       componentRegistry.registerComponent(new PlatformMBeanServerRegistration(), PlatformMBeanServerRegistration.class);
    }
 

Modified: core/branches/flat/src/main/java/org/horizon/factories/EntryFactoryImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/EntryFactoryImpl.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/factories/EntryFactoryImpl.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -30,6 +30,7 @@
 import org.horizon.context.InvocationContext;
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.Start;
+import org.horizon.invocation.Options;
 import org.horizon.lock.IsolationLevel;
 import org.horizon.lock.LockManager;
 import org.horizon.lock.TimeoutException;
@@ -37,12 +38,6 @@
 import org.horizon.logging.LogFactory;
 import org.horizon.notifications.cachelistener.CacheNotifier;
 
-/**
- * // TODO: MANIK: Document this
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 1.0
- */
 public class EntryFactoryImpl implements EntryFactory {
    private boolean useRepeatableRead;
    private static final NullMarkerEntry NULL_MARKER = new NullMarkerEntry();
@@ -50,7 +45,6 @@
    boolean writeSkewCheck;
    LockManager lockManager;
    Configuration configuration;
-   long defaultLockAcquisitionTimeout;
    CacheNotifier notifier;
 
    private static final Log log = LogFactory.getLog(EntryFactoryImpl.class);
@@ -67,7 +61,6 @@
    @Start
    public void init() {
       useRepeatableRead = configuration.getIsolationLevel() == IsolationLevel.REPEATABLE_READ;
-      defaultLockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
       writeSkewCheck = configuration.isWriteSkewCheck();
    }
 
@@ -168,18 +161,24 @@
       // nothing wrong, just means that we fail to record the lock.  And that is a problem.
       // Better to check our records and lock again if necessary.
       if (!ctx.hasLockedKey(key)) {
-         if (ctx.getOptionOverrides().isSuppressLocking()) {
+         if (ctx.hasOption(Options.SKIP_LOCKING)) {
             // just record this in the ctx and rtn
             ctx.addKeyLocked(key);
          } else if (!lockManager.lockAndRecord(key, ctx)) {
             Object owner = lockManager.getOwner(key);
-            throw new TimeoutException("Unable to acquire lock on key [" + key + "] after [" + ctx.getLockAcquisitionTimeout(defaultLockAcquisitionTimeout) + "] milliseconds for requestor [" + lockManager.getLockOwner(ctx) + "]! Lock held by [" + owner + "]");
+            throw new TimeoutException("Unable to acquire lock on key [" + key + "] after [" + getLockAcquisitionTImeout(ctx)
+                  + "] milliseconds for requestor [" + lockManager.getLockOwner(ctx) + "]! Lock held by [" + owner + "]");
          }
          return true;
       }
       return false;
    }
 
+   private long getLockAcquisitionTImeout(InvocationContext ctx) {
+      return ctx.hasOption(Options.ZERO_LOCK_ACQUISITION_TIMEOUT) ?
+            0 : configuration.getLockAcquisitionTimeout();
+   }
+
    public void releaseLock(Object key) {
       lockManager.unlock(key, lockManager.getOwner(key));
    }

Modified: core/branches/flat/src/main/java/org/horizon/factories/annotations/NonVolatile.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/annotations/NonVolatile.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/factories/annotations/NonVolatile.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -28,11 +28,11 @@
 
 /**
  * This annotation is used for components that will be registered in the {@link org.horizon.factories.ComponentRegistry},
- * that are resilient to changes in configuration.  Examples are the {@link org.horizon.CacheSPI} implementation used,
- * which does not change regardless of the configuration.  Components such as the {@link org.horizon.lock.LockManager},
- * though, should <b>never</b> be marked as <tt>@NonVolatile</tt> since based on the configuration, different lock
- * manager implementations may be selected.  LockManager is, hence, <b>not</b> resilient to changes in the
- * configuration.
+ * that are resilient to changes in configuration.  Examples are the {@link org.horizon.factories.ComponentRegistry}
+ * implementation used, which does not change regardless of the configuration.  Components such as the {@link
+ * org.horizon.lock.LockManager}, though, should <b>never</b> be marked as <tt>@NonVolatile</tt> since based on the
+ * configuration, different lock manager implementations may be selected.  LockManager is, hence, <b>not</b> resilient
+ * to changes in the configuration.
  *
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 1.0

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/CacheStoreInterceptor.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/CacheStoreInterceptor.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -36,6 +36,7 @@
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.Start;
 import org.horizon.interceptors.base.JmxStatsCommandInterceptor;
+import org.horizon.invocation.Options;
 import org.horizon.jmx.annotations.ManagedAttribute;
 import org.horizon.jmx.annotations.ManagedOperation;
 import org.horizon.loader.CacheLoader;
@@ -96,7 +97,7 @@
     * if this is a shared cache loader and the call is of remote origin, pass up the chain
     */
    public final boolean skip(InvocationContext ctx, VisitableCommand command) {
-      if ((!ctx.isOriginLocal() && loaderConfig.isShared()) || ctx.getOptionOverrides().isSuppressPersistence()) {
+      if ((!ctx.isOriginLocal() && loaderConfig.isShared()) || ctx.hasOption(Options.SKIP_CACHE_STORE)) {
          if (trace)
             log.trace("Passing up method call and bypassing this interceptor since the cache loader is shared and this call originated remotely.");
          return true;

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/InvalidationInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/InvalidationInterceptor.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/InvalidationInterceptor.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -36,7 +36,6 @@
 import org.horizon.commands.write.RemoveCommand;
 import org.horizon.commands.write.ReplaceCommand;
 import org.horizon.commands.write.WriteCommand;
-import org.horizon.config.Option;
 import org.horizon.context.InvocationContext;
 import org.horizon.context.TransactionContext;
 import org.horizon.factories.annotations.Inject;
@@ -101,7 +100,7 @@
    public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
       // just broadcast the clear command - this is simplest!
       Object retval = invokeNextInterceptor(ctx, command);
-      if (ctx.isOriginLocal()) replicateCall(ctx, command, defaultSynchronous, ctx.getOptionOverrides());
+      if (ctx.isOriginLocal()) replicateCall(ctx, command, defaultSynchronous);
       return retval;
    }
 
@@ -147,14 +146,13 @@
       Object retval = invokeNextInterceptor(ctx, command);
       if (command.isSuccessful()) {
          Transaction tx = ctx.getTransaction();
-         Option optionOverride = ctx.getOptionOverrides();
          if (log.isDebugEnabled()) log.debug("Is a CRUD method");
          if (keys != null && keys.length != 0) {
             // could be potentially TRANSACTIONAL.  Ignore if it is, until we see a prepare().
             if (tx == null || !TransactionTable.isValid(tx)) {
                // the no-tx case:
                //replicate an evict call.
-               invalidateAcrossCluster(isSynchronous(optionOverride), ctx, keys);
+               invalidateAcrossCluster(isSynchronous(ctx), ctx, keys);
             } else {
                if (isLocalModeForced(ctx)) ctx.getTransactionContext().addLocalModification(command);
             }
@@ -221,7 +219,7 @@
          InvalidateCommand command = commandsFactory.buildInvalidateCommand(keys);
          if (log.isDebugEnabled()) log.debug("Cache [" + rpcManager.getAddress() + "] replicating " + command);
          // voila, invalidated!
-         replicateCall(ctx, command, synchronous, ctx.getOptionOverrides());
+         replicateCall(ctx, command, synchronous);
       }
    }
 

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/InvocationContextInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/InvocationContextInterceptor.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/InvocationContextInterceptor.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -31,10 +31,10 @@
 import org.horizon.commands.write.PutMapCommand;
 import org.horizon.commands.write.RemoveCommand;
 import org.horizon.commands.write.ReplaceCommand;
-import org.horizon.config.Option;
 import org.horizon.context.InvocationContext;
 import org.horizon.context.TransactionContext;
 import org.horizon.factories.annotations.Inject;
+import org.horizon.invocation.Options;
 import org.horizon.remoting.RPCManager;
 import org.horizon.transaction.GlobalTransaction;
 import org.horizon.transaction.TransactionTable;
@@ -96,7 +96,6 @@
    }
 
    private Object handleAll(InvocationContext ctx, VisitableCommand command, GlobalTransaction gtx, boolean scrubContextOnCompletion) throws Throwable {
-      Option optionOverride = ctx.getOptionOverrides();
       boolean suppressExceptions = false;
       Transaction suspendedTransaction = null;
       boolean resumeSuspended = false;
@@ -113,18 +112,16 @@
             setTransactionalContext(null, null, null, ctx);
          }
 
-         if (optionOverride != null) {
-            if (optionOverride.isFailSilently()) {
-               log.debug("FAIL_SILENTLY Option is present - suspending any ongoing transaction.");
-               suppressExceptions = true;
-               if (ctx.getTransaction() != null) {
-                  suspendedTransaction = txManager.suspend();
-                  setTransactionalContext(null, null, null, ctx);
-                  if (trace) log.trace("Suspending transaction " + suspendedTransaction);
-                  resumeSuspended = true;
-               } else {
-                  if (trace) log.trace("No ongoing transaction to suspend");
-               }
+         if (ctx.hasOption(Options.FAIL_SILENTLY)) {
+            log.debug("FAIL_SILENTLY Option is present - suspending any ongoing transaction.");
+            suppressExceptions = true;
+            if (ctx.getTransaction() != null) {
+               suspendedTransaction = txManager.suspend();
+               setTransactionalContext(null, null, null, ctx);
+               if (trace) log.trace("Suspending transaction " + suspendedTransaction);
+               resumeSuspended = true;
+            } else {
+               if (trace) log.trace("No ongoing transaction to suspend");
             }
          }
 
@@ -156,7 +153,7 @@
 
          // clean up any invocation-scope options set up
          if (trace) log.trace("Resetting invocation-scope options");
-         ctx.getOptionOverrides().reset();
+         ctx.resetOptions();
 
          // if this is a prepare, opt prepare or
 
@@ -205,10 +202,8 @@
       // notify the transaction tCtx that this override is in place.
       TransactionContext tCtx = ctx.getTransactionContext();
       if (tCtx != null) {
-         Option txScopeOption = new Option();
-         txScopeOption.setCacheModeLocal(ctx.getOptionOverrides() != null && ctx.getOptionOverrides().isCacheModeLocal());
-         txScopeOption.setSkipCacheStatusCheck(ctx.getOptionOverrides() != null && ctx.getOptionOverrides().isSkipCacheStatusCheck());
-         tCtx.setOption(txScopeOption);
+         if (ctx.hasOption(Options.CACHE_MODE_LOCAL)) tCtx.setOptions(Options.CACHE_MODE_LOCAL);
+         if (ctx.hasOption(Options.SKIP_CACHE_STATUS_CHECK)) tCtx.setOptions(Options.SKIP_CACHE_STATUS_CHECK);
       }
    }
 }
\ No newline at end of file

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/LockingInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/LockingInterceptor.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/LockingInterceptor.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -165,8 +165,7 @@
    public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
       try {
          entryFactory.wrapEntryForWriting(ctx, command.getKey(), true, false, command.getLifespanMillis());
-         Object o = invokeNextInterceptor(ctx, command);
-         return o;
+         return invokeNextInterceptor(ctx, command);
       }
       finally {
          doAfterCall(ctx);

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/ReplicationInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/ReplicationInterceptor.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/ReplicationInterceptor.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -48,7 +48,7 @@
    @Override
    public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
       if (!skipReplicationOfTransactionMethod(ctx))
-         replicateCall(ctx, command, configuration.isSyncCommitPhase(), ctx.getOptionOverrides(), true);
+         replicateCall(ctx, command, configuration.isSyncCommitPhase(), true);
       return invokeNextInterceptor(ctx, command);
    }
 
@@ -69,7 +69,7 @@
    @Override
    public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
       if (!skipReplicationOfTransactionMethod(ctx) && !ctx.isLocalRollbackOnly()) {
-         replicateCall(ctx, command, configuration.isSyncRollbackPhase(), ctx.getOptionOverrides());
+         replicateCall(ctx, command, configuration.isSyncRollbackPhase());
       }
       return invokeNextInterceptor(ctx, command);
    }
@@ -118,7 +118,7 @@
                      configuration.getSyncReplTimeout());
             }
 
-            replicateCall(ctx, command, isSynchronous(ctx.getOptionOverrides()), ctx.getOptionOverrides());
+            replicateCall(ctx, command, isSynchronous(ctx));
          } else {
             if (local) ctx.getTransactionContext().addLocalModification(command);
          }
@@ -143,6 +143,6 @@
       }
 
       // this method will return immediately if we're the only member (because exclude_self=true)
-      replicateCall(ctx, prepareMethod, !async, ctx.getOptionOverrides());
+      replicateCall(ctx, prepareMethod, !async);
    }
 }
\ No newline at end of file

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -30,13 +30,13 @@
 import org.horizon.commands.tx.CommitCommand;
 import org.horizon.commands.tx.PrepareCommand;
 import org.horizon.commands.tx.RollbackCommand;
-import org.horizon.config.Option;
 import org.horizon.context.InvocationContext;
 import org.horizon.context.TransactionContext;
 import org.horizon.factories.ComponentRegistry;
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.context.ContextFactory;
 import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.invocation.Options;
 import org.horizon.lock.LockManager;
 import org.horizon.manager.CacheManager;
 import org.horizon.notifications.cachelistener.CacheNotifier;
@@ -116,12 +116,19 @@
          }
       }
       catch (Throwable e) {
-         ctx.throwIfNeeded(e);
+         throwIfNeeded(ctx, e);
       }
 
       return result;
    }
 
+   private void throwIfNeeded(InvocationContext ctx, Throwable throwable) throws Throwable {
+      if (ctx.hasOption(Options.FAIL_SILENTLY))
+         log.trace("There was a problem handling this request, but FAIL_SLIENTLY was set, so suppressing exception", throwable);
+      else
+         throw throwable;
+   }
+
    @Override
    public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
       if (!ctx.getGlobalTransaction().isRemote()) {
@@ -160,7 +167,7 @@
          if (log.isDebugEnabled()) log.debug("Finished remote rollback method for " + gtx);
       }
       catch (Throwable throwable) {
-         ctx.throwIfNeeded(throwable);
+         throwIfNeeded(ctx, throwable);
       }
       return null;
    }
@@ -210,7 +217,7 @@
          if (log.isDebugEnabled()) log.debug("Finished remote commit/rollback method for " + gtx);
       }
       catch (Throwable throwable) {
-         ctx.throwIfNeeded(throwable);
+         throwIfNeeded(ctx, throwable);
       }
 
       return null;
@@ -222,7 +229,7 @@
          return attachGtxAndPassUpChain(ctx, command);
       }
       catch (Throwable throwable) {
-         ctx.throwIfNeeded(throwable);
+         throwIfNeeded(ctx, throwable);
          return null;
       }
    }
@@ -639,8 +646,7 @@
          ctx = invocationContextContainer.get();
          setTransactionalContext(tx, gtx, transactionContext, ctx);
 
-         if (ctx.isOptionsUninitialised() && transactionContext.getOption() != null)
-            ctx.setOptionOverrides(transactionContext.getOption());
+         if (ctx.isOptionsUninit()) ctx.setOptions(transactionContext.getOptions());
 
          assertCanContinue();
 
@@ -655,9 +661,9 @@
             ctx = invocationContextContainer.get();
             setTransactionalContext(tx, gtx, transactionContext, ctx);
 
-            if (ctx.isOptionsUninitialised() && transactionContext != null && transactionContext.getOption() != null) {
+            if (ctx.isOptionsUninit() && transactionContext != null) {
                // use the options from the transaction entry instead
-               ctx.setOptionOverrides(transactionContext.getOption());
+               ctx.setOptions(transactionContext.getOptions());
             }
          }
 
@@ -677,7 +683,7 @@
             if (transactionContext != null) {
                // this should ideally be set in beforeCompletion(), after compacting the list.
                if (modifications == null) modifications = transactionContext.getModifications();
-               ctx.setOptionOverrides(transactionContext.getOption());
+               ctx.setOptions(transactionContext.getOptions());
             }
             if (tx != null) transactions.remove(tx);
 
@@ -714,7 +720,7 @@
       }
 
       private void assertCanContinue() {
-         if (!componentRegistry.invocationsAllowed(true) && (ctx.getOptionOverrides() == null || !ctx.getOptionOverrides().isSkipCacheStatusCheck()))
+         if (!componentRegistry.invocationsAllowed(true) && !ctx.hasOption(Options.SKIP_CACHE_STATUS_CHECK))
             throw new IllegalStateException("Cache not in STARTED state!");
       }
 
@@ -752,7 +758,7 @@
       // This is STILL remotely originating though and this needs to be made explicit here.
       // this can be checked by inspecting the InvocationContext.isOriginLocal() at the time of registering the sync.
       private boolean remoteLocal = false;
-      private Option originalOptions, transactionalOptions;
+      private Set<Options> originalOptions, transactionalOptions;
 
       /**
        * A Synchronization for locally originating txs.
@@ -787,9 +793,9 @@
          }
 
          // set any transaction wide options as current for this thread, caching original options that would then be reset
-         originalOptions = ctx.getOptionOverrides();
-         transactionalOptions = transactionContext.getOption();
-         ctx.setOptionOverrides(transactionalOptions);
+         originalOptions = ctx.getOptions();
+         transactionalOptions = transactionContext.getOptions();
+         ctx.setOptions(transactionalOptions);
 
          try {
             switch (tx.getStatus()) {
@@ -827,7 +833,7 @@
          finally {
             localRollbackOnly = false;
             setTransactionalContext(null, null, null, ctx);
-            ctx.setOptionOverrides(originalOptions);
+            ctx.setOptions(originalOptions);
          }
       }
 
@@ -837,12 +843,12 @@
          if (ctx == null) ctx = invocationContextContainer.get();
          ctx.setLocalRollbackOnly(localRollbackOnly);
          setTransactionalContext(tx, gtx, transactionContext, ctx);
-         if (transactionalOptions != null) ctx.setOptionOverrides(transactionalOptions);
+         if (transactionalOptions != null) ctx.setOptions(transactionalOptions);
          try {
             super.afterCompletion(status);
          }
          finally {
-            ctx.setOptionOverrides(originalOptions);
+            ctx.setOptions(originalOptions);
          }
       }
 

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/base/BaseRpcInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/base/BaseRpcInterceptor.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/base/BaseRpcInterceptor.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -25,11 +25,11 @@
 import org.horizon.commands.CommandsFactory;
 import org.horizon.commands.RPCCommand;
 import org.horizon.commands.ReplicableCommand;
-import org.horizon.config.Option;
 import org.horizon.context.InvocationContext;
 import org.horizon.context.TransactionContext;
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.Start;
+import org.horizon.invocation.Options;
 import org.horizon.remoting.RPCManager;
 import org.horizon.remoting.ResponseMode;
 import org.horizon.remoting.transport.Address;
@@ -83,33 +83,28 @@
       }
    }
 
-   protected void replicateCall(InvocationContext ctx, RPCCommand call, boolean sync, Option o, boolean useOutOfBandMessage) throws Throwable {
-      replicateCall(ctx, null, call, sync, o, useOutOfBandMessage);
+   protected void replicateCall(InvocationContext ctx, RPCCommand call, boolean sync, boolean useOutOfBandMessage) throws Throwable {
+      replicateCall(ctx, null, call, sync, useOutOfBandMessage);
    }
 
-   protected void replicateCall(InvocationContext ctx, ReplicableCommand call, boolean sync, Option o, boolean useOutOfBandMessage) throws Throwable {
-      replicateCall(ctx, null, commandsFactory.buildReplicateCommand(call), sync, o, useOutOfBandMessage);
+   protected void replicateCall(InvocationContext ctx, ReplicableCommand call, boolean sync, boolean useOutOfBandMessage) throws Throwable {
+      replicateCall(ctx, null, commandsFactory.buildReplicateCommand(call), sync, useOutOfBandMessage);
    }
 
-   protected void replicateCall(InvocationContext ctx, RPCCommand call, boolean sync, Option o) throws Throwable {
-      replicateCall(ctx, null, call, sync, o, false);
+   protected void replicateCall(InvocationContext ctx, RPCCommand call, boolean sync) throws Throwable {
+      replicateCall(ctx, null, call, sync, false);
    }
 
-   protected void replicateCall(InvocationContext ctx, ReplicableCommand call, boolean sync, Option o) throws Throwable {
-      replicateCall(ctx, null, commandsFactory.buildReplicateCommand(call), sync, o, false);
+   protected void replicateCall(InvocationContext ctx, ReplicableCommand call, boolean sync) throws Throwable {
+      replicateCall(ctx, null, commandsFactory.buildReplicateCommand(call), sync, false);
    }
 
-   protected void replicateCall(InvocationContext ctx, List<Address> recipients, RPCCommand c, boolean sync, Option o, boolean useOutOfBandMessage) throws Throwable {
+   protected void replicateCall(InvocationContext ctx, List<Address> recipients, RPCCommand c, boolean sync, boolean useOutOfBandMessage) throws Throwable {
       long syncReplTimeout = configuration.getSyncReplTimeout();
 
-      // test for option overrides
-      if (o != null) {
-         if (o.isForceAsynchronous()) sync = false;
-         else if (o.isForceSynchronous()) sync = true;
+      if (ctx.hasOption(Options.FORCE_ASYNCHRONOUS)) sync = false;
+      else if (ctx.hasOption(Options.FORCE_SYNCHRONOUS)) sync = true;
 
-         if (o.getSyncReplTimeout() > 0) syncReplTimeout = o.getSyncReplTimeout();
-      }
-
       // tx-level overrides are more important
       Transaction tx = ctx.getTransaction();
       if (tx != null) {
@@ -157,32 +152,32 @@
     *    - the current transaction did not modify any data
     * </pre>
     */
-   protected boolean skipReplicationOfTransactionMethod(InvocationContext ctx) {
+   protected final boolean skipReplicationOfTransactionMethod(InvocationContext ctx) {
       GlobalTransaction gtx = ctx.getGlobalTransaction();
-      return ctx.getTransaction() == null || gtx == null || gtx.isRemote() || ctx.getOptionOverrides().isCacheModeLocal() || !ctx.getTransactionContext().hasModifications();
+      return ctx.getTransaction() == null || gtx == null || gtx.isRemote() || ctx.hasOption(Options.CACHE_MODE_LOCAL)
+            || !ctx.getTransactionContext().hasModifications();
    }
 
    /**
     * The call runs in a transaction and it was initiated on this node of the cluster.
     */
-   protected boolean isTransactionalAndLocal(InvocationContext ctx) {
+   protected final boolean isTransactionalAndLocal(InvocationContext ctx) {
       GlobalTransaction gtx = ctx.getGlobalTransaction();
       boolean isInitiatedHere = gtx != null && !gtx.isRemote();
       return isInitiatedHere && (ctx.getTransaction() != null);
    }
 
-   protected boolean isSynchronous(Option option) {
-      if (option != null) {
-         if (option.isForceSynchronous())
-            return true;
-         else if (option.isForceAsynchronous())
-            return false;
-      }
+   protected final boolean isSynchronous(InvocationContext ctx) {
+      if (ctx.hasOption(Options.FORCE_SYNCHRONOUS))
+         return true;
+      else if (ctx.hasOption(Options.FORCE_ASYNCHRONOUS))
+         return false;
+
       return defaultSynchronous;
    }
 
-   protected boolean isLocalModeForced(InvocationContext ctx) {
-      if (ctx.getOptionOverrides() != null && ctx.getOptionOverrides().isCacheModeLocal()) {
+   protected final boolean isLocalModeForced(InvocationContext ctx) {
+      if (ctx.hasOption(Options.CACHE_MODE_LOCAL)) {
          if (log.isDebugEnabled()) log.debug("LOCAL mode forced on invocation.  Suppressing clustered events.");
          return true;
       }

Modified: core/branches/flat/src/main/java/org/horizon/invocation/InvocationContextContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/invocation/InvocationContextContainer.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/invocation/InvocationContextContainer.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -46,8 +46,12 @@
    }
 
    @Override
-   protected InvocationContext initialValue() {
+   protected final InvocationContext initialValue() {
       // create if this is initially unset
       return contextFactory.createInvocationContext();
    }
+
+   public void reset() {
+      set(initialValue());
+   }
 }
\ No newline at end of file

Added: core/branches/flat/src/main/java/org/horizon/invocation/Options.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/invocation/Options.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/invocation/Options.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -0,0 +1,20 @@
+package org.horizon.invocation;
+
+/**
+ * Available options, which may be set on a per-invocation basis
+ *
+ * @author Manik Surtani
+ * @since 1.0
+ */
+public enum Options {
+   ZERO_LOCK_ACQUISITION_TIMEOUT,
+   CACHE_MODE_LOCAL,
+   SKIP_LOCKING,
+   FORCE_WRITE_LOCK,
+   SKIP_CACHE_STATUS_CHECK,
+   FORCE_ASYNCHRONOUS,
+   FORCE_SYNCHRONOUS,
+   SKIP_CACHE_STORE,
+   FAIL_SILENTLY
+
+}

Modified: core/branches/flat/src/main/java/org/horizon/jmx/JmxRegistrationManager.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/jmx/JmxRegistrationManager.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/jmx/JmxRegistrationManager.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,9 +21,8 @@
  */
 package org.horizon.jmx;
 
-import org.horizon.Cache;
+import org.horizon.AdvancedCache;
 import org.horizon.CacheException;
-import org.horizon.CacheSPI;
 import org.horizon.config.Configuration;
 import org.horizon.factories.ComponentRegistry;
 import org.horizon.logging.Log;
@@ -75,7 +74,7 @@
 
    private String objectNameBase;
 
-   private CacheSPI cacheSpi;
+   private AdvancedCache cache;
 
    /**
     * C-tor.
@@ -84,18 +83,18 @@
     * @param cache          cache that needs to be monitored
     * @param objectNameBase path in the MBeanServer where to register cache MBeans
     */
-   public JmxRegistrationManager(MBeanServer mBeanServer, Cache cache, ObjectName objectNameBase) {
+   public JmxRegistrationManager(MBeanServer mBeanServer, AdvancedCache cache, ObjectName objectNameBase) {
       this.mBeanServer = mBeanServer;
-      this.cacheSpi = (CacheSPI) cache;
+      this.cache = cache;
       processBaseName(objectNameBase);
    }
 
    /**
     * @throws IllegalArgumentException if the supplied objectNameBase name isn't valid
     */
-   public JmxRegistrationManager(MBeanServer mBeanServer, Cache cache, String objectNameBase) {
+   public JmxRegistrationManager(MBeanServer mBeanServer, AdvancedCache cache, String objectNameBase) {
       this.mBeanServer = mBeanServer;
-      this.cacheSpi = (CacheSPI) cache;
+      this.cache = cache;
       try {
          processBaseName(new ObjectName(objectNameBase));
       }
@@ -111,11 +110,11 @@
     * @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/management/mxbeans.html#mbean_server">platform
     *      MBeanServer</a>
     */
-   public JmxRegistrationManager(Cache cache, ObjectName objectNameBase) {
+   public JmxRegistrationManager(AdvancedCache cache, ObjectName objectNameBase) {
       this(ManagementFactory.getPlatformMBeanServer(), cache, objectNameBase);
    }
 
-   public JmxRegistrationManager(Cache cache) {
+   public JmxRegistrationManager(AdvancedCache cache) {
       this(cache, null);
    }
 
@@ -161,7 +160,7 @@
 
    private List<ResourceDMBean> getResourceDMBeans() {
       List<ResourceDMBean> resourceDMBeans = new ArrayList<ResourceDMBean>();
-      for (ComponentRegistry.Component component : cacheSpi.getComponentRegistry().getRegisteredComponents()) {
+      for (ComponentRegistry.Component component : cache.getComponentRegistry().getRegisteredComponents()) {
          ResourceDMBean resourceDMBean = new ResourceDMBean(component.getInstance());
          if (resourceDMBean.isManagedResource()) {
             resourceDMBeans.add(resourceDMBean);
@@ -175,13 +174,13 @@
          this.objectNameBase = baseName.getCanonicalName();
          return;
       }
-      if (cacheSpi.getConfiguration().getCacheMode().equals(Configuration.CacheMode.LOCAL)) {
-         objectNameBase = LOCAL_CACHE_PREFIX + ",instance=" + Integer.toHexString(System.identityHashCode(cacheSpi));
+      if (cache.getConfiguration().getCacheMode().equals(Configuration.CacheMode.LOCAL)) {
+         objectNameBase = LOCAL_CACHE_PREFIX + ",instance=" + Integer.toHexString(System.identityHashCode(cache));
       } else //the cache is clustered
       {
-         objectNameBase = REPLICATED_CACHE_PREFIX + cacheSpi.getConfiguration().getGlobalConfiguration().getClusterName();
+         objectNameBase = REPLICATED_CACHE_PREFIX + cache.getConfiguration().getGlobalConfiguration().getClusterName();
       }
-      objectNameBase = objectNameBase + ",cacheName=" + cacheSpi.getName();
+      objectNameBase = objectNameBase + ",cacheName=" + cache.getName();
    }
 
    public String getObjectName(String resourceName) {

Modified: core/branches/flat/src/main/java/org/horizon/jmx/PlatformMBeanServerRegistration.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/jmx/PlatformMBeanServerRegistration.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/jmx/PlatformMBeanServerRegistration.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,7 +21,7 @@
  */
 package org.horizon.jmx;
 
-import org.horizon.CacheSPI;
+import org.horizon.AdvancedCache;
 import org.horizon.config.Configuration;
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.NonVolatile;
@@ -31,7 +31,7 @@
 import org.horizon.logging.LogFactory;
 
 /**
- * If {@link Configuration#getExposeManagementStatistics()} is true, then class will register all the MBeans from the
+ * If {@link Configuration#isExposeManagementStatistics()} is true, then class will register all the MBeans from the
  * ConfigurationRegistry to the pltform MBean server.
  * <p/>
  * Note: to enable platform MBeanServer the following system property should be passet to the JVM:
@@ -45,10 +45,10 @@
 public class PlatformMBeanServerRegistration {
    private static final Log log = LogFactory.getLog(PlatformMBeanServerRegistration.class);
 
-   private CacheSPI cache;
+   private AdvancedCache cache;
 
    @Inject
-   public void initialize(CacheSPI cache) {
+   public void initialize(AdvancedCache cache) {
       this.cache = cache;
    }
 

Modified: core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheLoader.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheLoader.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheLoader.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,8 +21,8 @@
  */
 package org.horizon.loader;
 
+import org.horizon.Cache;
 import org.horizon.CacheException;
-import org.horizon.CacheSPI;
 import org.horizon.logging.Log;
 import org.horizon.logging.LogFactory;
 import org.horizon.marshall.EntryData;
@@ -51,7 +51,7 @@
  * @since 1.0
  */
 public abstract class AbstractCacheLoader<K, V> implements CacheLoader<K, V> {
-   protected CacheSPI<K, V> cache;
+   protected Cache<K, V> cache;
    private static final Log log = LogFactory.getLog(AbstractCacheLoader.class);
    private static final boolean trace = log.isTraceEnabled();
    /**
@@ -62,13 +62,14 @@
 
    public void storeEntireState(ObjectInputStream in) {
       // store new state
-      Object objectFromStream;
-      try {
-         objectFromStream = cache.getMarshaller().objectFromObjectStream(in);
-      }
-      catch (Exception e) {
-         throw new CacheException(e.getMessage(), e);
-      }
+      Object objectFromStream = null;
+      // TODO fix me
+//      try {
+//         objectFromStream = cache.getMarshaller().objectFromObjectStream(in);
+//      }
+//      catch (Exception e) {
+//         throw new CacheException(e.getMessage(), e);
+//      }
 
       if (objectFromStream instanceof EntryDataMarker) {
          // no persistent state sent across; return?
@@ -90,16 +91,17 @@
    public void loadEntireState(ObjectOutputStream os) {
       List<EntryData<K, V>> list = getAllEntries();
       if (trace) log.trace("Loading state of " + list.size() + " nodes into stream");
-      try {
-         cache.getMarshaller().objectToObjectStream(list, os);
-      }
-      catch (Exception e) {
-         throw new CacheException(e.getMessage(), e);
-      }
+      // TODO fix me
+//      try {
+//         cache.getMarshaller().objectToObjectStream(list, os);
+//      }
+//      catch (Exception e) {
+//         throw new CacheException(e.getMessage(), e);
+//      }
    }
 
 
-   public void setCache(CacheSPI<K, V> c) {
+   public void setCache(Cache<K, V> c) {
       this.cache = c;
    }
 
@@ -122,7 +124,9 @@
    }
 
    protected Marshaller getMarshaller() {
-      return cache.getMarshaller();
+      return null;
+      // todo fix me
+//      return cache.getMarshaller();
    }
 
    // empty implementations for loaders that do not wish to implement lifecycle.

Modified: core/branches/flat/src/main/java/org/horizon/loader/AbstractDelegatingCacheLoader.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/AbstractDelegatingCacheLoader.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/loader/AbstractDelegatingCacheLoader.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,7 +21,7 @@
  */
 package org.horizon.loader;
 
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
 import org.horizon.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
 import org.horizon.marshall.EntryData;
 
@@ -103,7 +103,7 @@
       cacheLoader.rollback(tx);
    }
 
-   public void setCache(CacheSPI<K, V> c) {
+   public void setCache(Cache<K, V> c) {
       cacheLoader.setCache(c);
    }
 

Modified: core/branches/flat/src/main/java/org/horizon/loader/CacheLoader.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/CacheLoader.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/loader/CacheLoader.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -22,7 +22,7 @@
 package org.horizon.loader;
 
 import net.jcip.annotations.ThreadSafe;
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
 import org.horizon.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
 import org.horizon.factories.scopes.Scope;
 import org.horizon.factories.scopes.Scopes;
@@ -75,13 +75,13 @@
    IndividualCacheLoaderConfig getConfig();
 
    /**
-    * Sets the {@link CacheSPI} that is maintaining this CacheLoader. This method allows this CacheLoader to set a
-    * reference to the {@link CacheSPI}. This method is called be called after the CacheLoader instance has been
+    * Sets the {@link Cache} that is maintaining this CacheLoader. This method allows this CacheLoader to set a
+    * reference to the {@link Cache}. This method is called be called after the CacheLoader instance has been
     * constructed.
     *
     * @param c The cache on which this loader works
     */
-   void setCache(CacheSPI<K, V> c);
+   void setCache(Cache<K, V> c);
 
    /**
     * Returns all keys and values from the persistent store, given a {@link Fqn}

Modified: core/branches/flat/src/main/java/org/horizon/loader/CacheLoaderManager.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/CacheLoaderManager.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/loader/CacheLoaderManager.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,8 +21,8 @@
  */
 package org.horizon.loader;
 
+import org.horizon.Cache;
 import org.horizon.CacheException;
-import org.horizon.CacheSPI;
 import org.horizon.config.CacheLoaderConfig;
 import org.horizon.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
 import org.horizon.config.CacheLoaderConfig.IndividualCacheLoaderConfig.SingletonStoreConfig;
@@ -57,14 +57,14 @@
 public class CacheLoaderManager {
    private static final Log log = LogFactory.getLog(CacheLoaderManager.class);
    private CacheLoaderConfig config;
-   private CacheSPI<Object, Object> cache;
+   private Cache<Object, Object> cache;
    private CacheLoader<Object, Object> loader;
    private boolean fetchPersistentState;
    private Configuration configuration;
    private ComponentRegistry registry;
 
    @Inject
-   public void injectDependencies(CacheSPI<Object, Object> cache, Configuration configuration, ComponentRegistry registry) {
+   public void injectDependencies(Cache<Object, Object> cache, Configuration configuration, ComponentRegistry registry) {
       // TODO: Inject CacheSPI once we have the cache loaders not relying on a tree structure
       this.config = configuration.getCacheLoaderConfig();
       this.cache = cache;
@@ -88,7 +88,7 @@
     * @param cache
     * @throws CacheException
     */
-   public void setConfig(CacheLoaderConfig config, CacheSPI<Object, Object> cache, Configuration configuration) throws CacheException {
+   public void setConfig(CacheLoaderConfig config, Cache<Object, Object> cache, Configuration configuration) throws CacheException {
       this.config = config == null ? configuration.getCacheLoaderConfig() : config;
       this.cache = cache;
       this.configuration = configuration;
@@ -177,7 +177,7 @@
     * @return a cache loader
     * @throws Exception
     */
-   private CacheLoader<Object, Object> createCacheLoader(CacheLoaderConfig.IndividualCacheLoaderConfig cfg, CacheSPI<Object, Object> cache) throws Exception {
+   private CacheLoader<Object, Object> createCacheLoader(CacheLoaderConfig.IndividualCacheLoaderConfig cfg, Cache<Object, Object> cache) throws Exception {
       // create loader
       CacheLoader<Object, Object> tmpLoader = cfg.getCacheLoader() == null ? createInstance(cfg.getClassName()) : cfg.getCacheLoader();
 
@@ -233,7 +233,7 @@
     * @param c      instance of cache to be set in cache loader
     * @param loader cache loader to which assign the cache instance
     */
-   protected void setCacheInLoader(CacheSPI<Object, Object> c, CacheLoader<Object, Object> loader) {
+   protected void setCacheInLoader(Cache<Object, Object> c, CacheLoader<Object, Object> loader) {
       loader.setCache(c);
    }
 

Modified: core/branches/flat/src/main/java/org/horizon/loader/ClusteredCacheLoader.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/ClusteredCacheLoader.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/loader/ClusteredCacheLoader.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -115,8 +115,12 @@
       return null;  // TODO: Manik: Customise this generated block
    }
 
+   private boolean isOriginLocal() {
+      return cache.getAdvancedCache().getInvocationContextContainer().get().isOriginLocal();
+   }
+
    public Set getChildrenNames(Fqn fqn) throws Exception {
-      if (!isCacheReady() || !cache.getInvocationContext().isOriginLocal()) return Collections.emptySet();
+      if (!isCacheReady() || !isOriginLocal()) return Collections.emptySet();
       lock.acquireLock(fqn, true);
 //      try
 //      {
@@ -188,7 +192,7 @@
 
    protected Map get0(Fqn name) throws Exception {
       // DON'T make a remote call if this is a remote call in the first place - leads to deadlocks - JBCACHE-1103
-      if (!isCacheReady() || !cache.getInvocationContext().isOriginLocal()) return Collections.emptyMap();
+      if (!isCacheReady() || !isOriginLocal()) return Collections.emptyMap();
       lock.acquireLock(name, true);
 //      try
 //      {
@@ -205,7 +209,7 @@
 
    public boolean exists(Fqn name) throws Exception {
       // DON'T make a remote call if this is a remote call in the first place - leads to deadlocks - JBCACHE-1103
-      if (!isCacheReady() || !cache.getInvocationContext().isOriginLocal()) return false;
+      if (!isCacheReady() || !isOriginLocal()) return false;
 
       lock.acquireLock(name, false);
 //      try
@@ -223,7 +227,7 @@
 
    public Object put(Fqn name, Object key, Object value) throws Exception {
       // DON'T make a remote call if this is a remote call in the first place - leads to deadlocks - JBCACHE-1103
-      if (!isCacheReady() || !cache.getInvocationContext().isOriginLocal()) return null;
+      if (!isCacheReady() || !isOriginLocal()) return null;
       lock.acquireLock(name, true);
       try {
 //         NodeSPI n = cache.peek(name, false);
@@ -263,7 +267,7 @@
     */
    public Object remove(Fqn name, Object key) throws Exception {
       // DON'T make a remote call if this is a remote call in the first place - leads to deadlocks - JBCACHE-1103
-      if (!isCacheReady() || !cache.getInvocationContext().isOriginLocal()) return false;
+      if (!isCacheReady() || !isOriginLocal()) return false;
       lock.acquireLock(name, true);
       try {
 //         NodeSPI n = cache.peek(name, true);

Modified: core/branches/flat/src/main/java/org/horizon/loader/SingletonStoreCacheLoader.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/SingletonStoreCacheLoader.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/loader/SingletonStoreCacheLoader.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -458,7 +458,7 @@
       @CacheStarted
       public void cacheStarted(Event e) {
          localAddress = cache.getCacheManager().getAddress();
-         active = cache.getRPCManager().isCoordinator();
+         active = cache.getCacheManager().isCoordinator();
          if (log.isDebugEnabled()) log.debug("cache started: " + this);
       }
 

Modified: core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/lock/StripedLockManager.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -26,6 +26,7 @@
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.Start;
 import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.invocation.Options;
 import org.horizon.logging.Log;
 import org.horizon.logging.LogFactory;
 import org.horizon.util.concurrent.locks.LockContainer;
@@ -84,7 +85,7 @@
    public boolean lockAndRecord(Object key, InvocationContext ctx) throws InterruptedException {
       if (trace) log.trace("Attempting to lock " + key);
       Lock lock = lockContainer.getLock(key);
-      if (lock.tryLock(ctx.getLockAcquisitionTimeout(configuration.getLockAcquisitionTimeout()), MILLISECONDS)) {
+      if (lock.tryLock(getLockAcquisitionTimeout(ctx), MILLISECONDS)) {
          ctx.addKeyLocked(key);
          return true;
       }
@@ -93,6 +94,11 @@
       return false;
    }
 
+   private long getLockAcquisitionTimeout(InvocationContext ctx) {
+      return ctx.hasOption(Options.ZERO_LOCK_ACQUISITION_TIMEOUT) ?
+            0 : configuration.getLockAcquisitionTimeout();
+   }
+
    public void unlock(Object key, Object owner) {
       if (trace) log.trace("Attempting to unlock " + key);
       Lock lock = lockContainer.getLock(key);

Modified: core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifierImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifierImpl.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifierImpl.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -22,9 +22,9 @@
 package org.horizon.notifications.cachelistener;
 
 import org.horizon.Cache;
-import org.horizon.CacheSPI;
 import org.horizon.context.InvocationContext;
 import org.horizon.factories.annotations.Inject;
+import org.horizon.invocation.InvocationContextContainer;
 import org.horizon.logging.Log;
 import org.horizon.logging.LogFactory;
 import org.horizon.notifications.AbstractListenerImpl;
@@ -77,6 +77,7 @@
    final List<ListenerInvocation> transactionRegisteredListeners = new CopyOnWriteArrayList<ListenerInvocation>();
    final List<ListenerInvocation> transactionCompletedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
 
+   private InvocationContextContainer icc;
    private Cache cache;
 
    public CacheNotifierImpl() {
@@ -95,7 +96,8 @@
    }
 
    @Inject
-   void injectDependencies(CacheSPI cache) {
+   void injectDependencies(InvocationContextContainer icc, Cache cache) {
+      this.icc = icc;
       this.cache = cache;
    }
 
@@ -288,10 +290,7 @@
    }
 
    private void restoreInvocationContext(InvocationContext backup) {
-      InvocationContext currentIC = cache.getInvocationContext();
-      backup.clearLookedUpEntries();
-      backup.putLookedUpEntries(currentIC.getLookedUpEntries());
-      cache.setInvocationContext(backup);
+      icc.set(backup);
    }
 
    /**
@@ -303,10 +302,11 @@
     */
    private InvocationContext resetInvocationContext(InvocationContext ctx) {
       // wipe current context.
-      cache.setInvocationContext(null);
+      icc.reset();
       // get a new Invocation Context
-      InvocationContext newContext = cache.getInvocationContext();
+      InvocationContext newContext = icc.get();
       newContext.putLookedUpEntries(ctx.getLookedUpEntries());
+      newContext.addAllKeysLocked(ctx.getKeysLocked());
       return ctx;
    }
 }

Modified: core/branches/flat/src/main/java/org/horizon/statetransfer/DefaultStateTransferManager.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/statetransfer/DefaultStateTransferManager.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/statetransfer/DefaultStateTransferManager.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,7 +21,6 @@
  */
 package org.horizon.statetransfer;
 
-import org.horizon.CacheSPI;
 import org.horizon.config.Configuration;
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.Start;
@@ -48,7 +47,7 @@
 
    public static final String PARTIAL_STATE_DELIMITER = "_PARTIAL_STATE_DELIMITER";
 
-   protected CacheSPI cache;
+   //   protected CacheSPI cache;
    protected Marshaller marshaller;
    //   protected RegionManager regionManager;
    protected Configuration configuration;
@@ -62,7 +61,7 @@
 
    @Inject
    public void injectDependencies() {
-      this.cache = cache;
+//      this.cache = cache;
 //      this.regionManager = regionManager;
       this.marshaller = marshaller;
       this.configuration = configuration;

Modified: core/branches/flat/src/main/java/org/horizon/tree/Node.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/tree/Node.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/tree/Node.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -22,6 +22,7 @@
 package org.horizon.tree;
 
 import net.jcip.annotations.ThreadSafe;
+import org.horizon.invocation.Options;
 
 import java.util.Map;
 import java.util.Set;
@@ -53,6 +54,8 @@
     */
    Node<K, V> getParent();
 
+   Node<K, V> getParent(Options... options);
+
    /**
     * Returns an immutable set of children nodes.
     *
@@ -60,6 +63,8 @@
     */
    Set<Node<K, V>> getChildren();
 
+   Set<Node<K, V>> getChildren(Options... options);
+
    /**
     * Returns an immutable set of children node names.
     *
@@ -67,6 +72,8 @@
     */
    Set<Object> getChildrenNames();
 
+   Set<Object> getChildrenNames(Options... options);
+
    /**
     * Returns a map containing the data in this {@link Node}.
     *
@@ -75,6 +82,8 @@
     */
    Map<K, V> getData();
 
+   Map<K, V> getData(Options... options);
+
    /**
     * Returns a {@link Set} containing the data in this {@link Node}.
     *
@@ -83,6 +92,8 @@
     */
    Set<K> getKeys();
 
+   Set<K> getKeys(Options... options);
+
    /**
     * Returns the {@link Fqn} which represents the location of this {@link Node} in the cache structure.  The {@link
     * Fqn} returned is absolute.
@@ -105,16 +116,20 @@
     */
    Node<K, V> addChild(Fqn f);
 
+   Node<K, V> addChild(Fqn f, Options... options);
+
    /**
     * Removes a child node specified by the given relative {@link Fqn}.
     * <p/>
-    * If you wish to remove children based on absolute {@link Fqn}s, use the {@link Cache} interface instead.
+    * If you wish to remove children based on absolute {@link Fqn}s, use the {@link TreeCache} interface instead.
     *
     * @param f {@link Fqn} of the child node, relative to the current node.
     * @return true if the node was found and removed, false otherwise
     */
    boolean removeChild(Fqn f);
 
+   boolean removeChild(Fqn f, Options... options);
+
    /**
     * Removes a child node specified by the given name.
     *
@@ -123,6 +138,7 @@
     */
    boolean removeChild(Object childName);
 
+   boolean removeChild(Object childName, Options... options);
 
    /**
     * Returns the child node
@@ -132,12 +148,17 @@
     */
    Node<K, V> getChild(Fqn f);
 
+   Node<K, V> getChild(Fqn f, Options... options);
+
    /**
     * @param name name of the child
     * @return a direct child of the current node.
     */
    Node<K, V> getChild(Object name);
 
+   Node<K, V> getChild(Object name, Options... options);
+
+
    /**
     * Associates the specified value with the specified key for this node. If this node previously contained a mapping
     * for this key, the old value is replaced by the specified value.
@@ -148,6 +169,8 @@
     */
    V put(K key, V value);
 
+   V put(K key, V value, Options... options);
+
    /**
     * If the specified key is not already associated with a value, associate it with the given value, and returns the
     * Object (if any) that occupied the space, or null.
@@ -168,6 +191,8 @@
     */
    V putIfAbsent(K key, V value);
 
+   V putIfAbsent(K key, V value, Options... options);
+
    /**
     * Replace entry for key only if currently mapped to some value. Acts as
     * <pre>
@@ -187,6 +212,8 @@
     */
    V replace(K key, V value);
 
+   V replace(K key, V value, Options... options);
+
    /**
     * Replace entry for key only if currently mapped to given value. Acts as
     * <pre>
@@ -208,7 +235,9 @@
     */
    boolean replace(K key, V oldValue, V newValue);
 
+   boolean replace(K key, V oldValue, V value, Options... options);
 
+
    /**
     * Copies all of the mappings from the specified map to this node's map. If any data exists, existing keys are
     * overwritten with the keys in the new map. The behavior is equivalent to:
@@ -222,6 +251,8 @@
     */
    void putAll(Map<? extends K, ? extends V> map);
 
+   void putAll(Map<? extends K, ? extends V> map, Options... options);
+
    /**
     * Similar to {@link #putAll(java.util.Map)} except that it removes any entries that exists in the data map first.
     * Note that this happens atomically, under a single lock.  This is the analogous to doing a {@link #clearData()}
@@ -231,6 +262,7 @@
     */
    void replaceAll(Map<? extends K, ? extends V> map);
 
+   void replaceAll(Map<? extends K, ? extends V> map, Options... options);
 
    /**
     * Returns the value to which this node maps the specified key. Returns <code>null</code> if the node contains no
@@ -242,6 +274,8 @@
     */
    V get(K key);
 
+   V get(K key, Options... options);
+
    /**
     * Removes the mapping for this key from this node if it is present. Returns the value to which the node previously
     * associated the key, or <code>null</code> if the node contained no mapping for this key
@@ -251,16 +285,22 @@
     */
    V remove(K key);
 
+   V remove(K key, Options... options);
+
    /**
     * Removes all mappings from the node's data map.
     */
    void clearData();
 
+   void clearData(Options... options);
+
    /**
     * @return the number of elements (key/value pairs) in the node's data map.
     */
    int dataSize();
 
+   int dataSize(Options... options);
+
    /**
     * Returns true if the child node denoted by the relative {@link Fqn} passed in exists.
     *
@@ -269,6 +309,8 @@
     */
    boolean hasChild(Fqn f);
 
+   boolean hasChild(Fqn f, Options... options);
+
    /**
     * Returns true if the child node denoted by the Object name passed in exists.
     *
@@ -277,6 +319,8 @@
     */
    boolean hasChild(Object o);
 
+   boolean hasChild(Object o, Options... options);
+
    /**
     * Tests if a node reference is still valid.  A node reference may become invalid if it has been removed, invalidated
     * or moved, either locally or remotely.  If a node is invalid, it should be fetched again from the cache or a valid
@@ -286,7 +330,7 @@
     */
    boolean isValid();
 
-   void evict();
+   void removeChildren();
 
-   void removeChildren();
+   void removeChildren(Options... options);
 }

Modified: core/branches/flat/src/main/java/org/horizon/tree/NodeImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/tree/NodeImpl.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/tree/NodeImpl.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -23,6 +23,9 @@
 
 import org.horizon.Cache;
 import org.horizon.atomic.AtomicMap;
+import org.horizon.batch.BatchContainer;
+import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.invocation.Options;
 import org.horizon.util.Immutables;
 import org.horizon.util.Util;
 
@@ -42,8 +45,8 @@
    Fqn fqn;
    NodeKey dataKey, structureKey;
 
-   public NodeImpl(Fqn fqn, Cache cache) {
-      super(cache);
+   public NodeImpl(Fqn fqn, Cache cache, BatchContainer batchContainer, InvocationContextContainer icc) {
+      super(cache, batchContainer, icc);
       this.fqn = fqn;
       dataKey = new NodeKey(fqn, NodeKey.Type.DATA);
       structureKey = new NodeKey(fqn, NodeKey.Type.STRUCTURE);
@@ -51,15 +54,20 @@
 
    public Node<K, V> getParent() {
       if (fqn.isRoot()) return this;
-      return new NodeImpl(fqn.getParent(), cache);
+      return new NodeImpl<K, V>(fqn.getParent(), cache, batchContainer, icc);
    }
 
+   public Node<K, V> getParent(Options... options) {
+      icc.get().setOptions(options);
+      return getParent();
+   }
+
    public Set<Node<K, V>> getChildren() {
       startAtomic();
       try {
-         Set set = new HashSet();
+         Set<Node<K, V>> set = new HashSet<Node<K, V>>();
          for (Fqn f : getStructure().values()) {
-            NodeImpl n = new NodeImpl(f, cache);
+            NodeImpl<K, V> n = new NodeImpl<K, V>(f, cache, batchContainer, icc);
             set.add(n);
          }
          return Immutables.immutableSetWrap(set);
@@ -69,16 +77,30 @@
       }
    }
 
+   public Set<Node<K, V>> getChildren(Options... options) {
+      icc.get().setOptions(options);
+      return getChildren();
+   }
+
    public Set<Object> getChildrenNames() {
       return Immutables.immutableSetCopy(getStructure().keySet());
    }
 
+   public Set<Object> getChildrenNames(Options... options) {
+      icc.get().setOptions(options);
+      return getChildrenNames();
+   }
+
    @SuppressWarnings("unchecked")
    public Map<K, V> getData() {
       return Collections.unmodifiableMap(new HashMap(getDataInternal()));
-//      return Immutables.immutableMapCopy(getDataInternal());
    }
 
+   public Map<K, V> getData(Options... options) {
+      icc.get().setOptions(options);
+      return getData();
+   }
+
    public Set<K> getKeys() {
       startAtomic();
       try {
@@ -89,6 +111,11 @@
       }
    }
 
+   public Set<K> getKeys(Options... options) {
+      icc.get().setOptions(options);
+      return getKeys();
+   }
+
    public Fqn getFqn() {
       return fqn;
    }
@@ -97,10 +124,9 @@
       startAtomic();
       try {
          Fqn absoluteChildFqn = Fqn.fromRelativeFqn(fqn, f);
-         NodeImpl child = new NodeImpl(absoluteChildFqn, cache);
+         NodeImpl<K, V> child = new NodeImpl<K, V>(absoluteChildFqn, cache, batchContainer, icc);
          AtomicMap<Object, Fqn> s = getStructure();
          s.put(f.getLastElement(), absoluteChildFqn);
-//         updateStructure(s);
          createNodeInCache(absoluteChildFqn);
          return child;
       }
@@ -109,17 +135,27 @@
       }
    }
 
+   public Node<K, V> addChild(Fqn f, Options... options) {
+      icc.get().setOptions(options);
+      return addChild(f);
+   }
+
    public boolean removeChild(Fqn f) {
       return removeChild(f.getLastElement());
    }
 
+   public boolean removeChild(Fqn f, Options... options) {
+      icc.get().setOptions(options);
+      return removeChild(f);
+   }
+
    public boolean removeChild(Object childName) {
       startAtomic();
       try {
          AtomicMap<Object, Fqn> s = getStructure();
          Fqn childFqn = s.remove(childName);
          if (childFqn != null) {
-            Node child = new NodeImpl(childFqn, cache);
+            Node<K, V> child = new NodeImpl<K, V>(childFqn, cache, batchContainer, icc);
             child.removeChildren();
             child.clearData();  // this is necessary in case we have a remove and then an add on the same node, in the same tx.
             cache.remove(new NodeKey(childFqn, NodeKey.Type.DATA));
@@ -134,11 +170,16 @@
       }
    }
 
+   public boolean removeChild(Object childName, Options... options) {
+      icc.get().setOptions(options);
+      return removeChild(childName);
+   }
+
    public Node<K, V> getChild(Fqn f) {
       startAtomic();
       try {
          if (hasChild(f))
-            return new NodeImpl(Fqn.fromRelativeFqn(fqn, f), cache);
+            return new NodeImpl<K, V>(Fqn.fromRelativeFqn(fqn, f), cache, batchContainer, icc);
          else
             return null;
       }
@@ -147,11 +188,16 @@
       }
    }
 
+   public Node<K, V> getChild(Fqn f, Options... options) {
+      icc.get().setOptions(options);
+      return getChild(f);
+   }
+
    public Node<K, V> getChild(Object name) {
       startAtomic();
       try {
          if (hasChild(name))
-            return new NodeImpl(Fqn.fromRelativeElements(fqn, name), cache);
+            return new NodeImpl<K, V>(Fqn.fromRelativeElements(fqn, name), cache, batchContainer, icc);
          else
             return null;
       }
@@ -160,6 +206,11 @@
       }
    }
 
+   public Node<K, V> getChild(Object name, Options... options) {
+      icc.get().setOptions(options);
+      return getChild(name);
+   }
+
    public V put(K key, V value) {
       startAtomic();
       try {
@@ -170,6 +221,11 @@
       }
    }
 
+   public V put(K key, V value, Options... options) {
+      icc.get().setOptions(options);
+      return put(key, value);
+   }
+
    public V putIfAbsent(K key, V value) {
       startAtomic();
       try {
@@ -183,6 +239,11 @@
       }
    }
 
+   public V putIfAbsent(K key, V value, Options... options) {
+      icc.get().setOptions(options);
+      return putIfAbsent(key, value);
+   }
+
    public V replace(K key, V value) {
       startAtomic();
       try {
@@ -197,6 +258,11 @@
       }
    }
 
+   public V replace(K key, V value, Options... options) {
+      icc.get().setOptions(options);
+      return replace(key, value);
+   }
+
    public boolean replace(K key, V oldValue, V newValue) {
       startAtomic();
       try {
@@ -213,6 +279,11 @@
       }
    }
 
+   public boolean replace(K key, V oldValue, V value, Options... options) {
+      icc.get().setOptions(options);
+      return replace(key, oldValue, value);
+   }
+
    public void putAll(Map<? extends K, ? extends V> map) {
       startAtomic();
       try {
@@ -223,6 +294,11 @@
       }
    }
 
+   public void putAll(Map<? extends K, ? extends V> map, Options... options) {
+      icc.get().setOptions(options);
+      putAll(map);
+   }
+
    public void replaceAll(Map<? extends K, ? extends V> map) {
       startAtomic();
       try {
@@ -235,10 +311,20 @@
       }
    }
 
+   public void replaceAll(Map<? extends K, ? extends V> map, Options... options) {
+      icc.get().setOptions(options);
+      replaceAll(map);
+   }
+
    public V get(K key) {
       return getData().get(key);
    }
 
+   public V get(K key, Options... options) {
+      icc.get().setOptions(options);
+      return get(key);
+   }
+
    public V remove(K key) {
       startAtomic();
       try {
@@ -249,14 +335,29 @@
       }
    }
 
+   public V remove(K key, Options... options) {
+      icc.get().setOptions(options);
+      return remove(key);
+   }
+
    public void clearData() {
       getDataInternal().clear();
    }
 
+   public void clearData(Options... options) {
+      icc.get().setOptions(options);
+      clearData();
+   }
+
    public int dataSize() {
       return getData().size();
    }
 
+   public int dataSize(Options... options) {
+      icc.get().setOptions(options);
+      return dataSize();
+   }
+
    public boolean hasChild(Fqn f) {
       if (f.size() > 1) {
          // indirect child.
@@ -267,10 +368,20 @@
       }
    }
 
+   public boolean hasChild(Fqn f, Options... options) {
+      icc.get().setOptions(options);
+      return hasChild(f);
+   }
+
    public boolean hasChild(Object o) {
       return getStructure().containsKey(o);
    }
 
+   public boolean hasChild(Object o, Options... options) {
+      icc.get().setOptions(options);
+      return hasChild(o);
+   }
+
    public boolean isValid() {
       return cache.containsKey(dataKey);
    }
@@ -286,26 +397,15 @@
       }
    }
 
-   public void evict() {
-      startAtomic();
-      try {
-         cache.evict(structureKey);
-         cache.evict(dataKey);
-      }
-      finally {
-         endAtomic();
-      }
+   public void removeChildren(Options... options) {
+      icc.get().setOptions(options);
+      removeChildren();
    }
 
    AtomicMap<K, V> getDataInternal() {
       return (AtomicMap<K, V>) cache.getAtomicMap(dataKey);
    }
 
-//   void updateStructure(FastCopyHashMap<Object, Fqn> s)
-//   {
-//      cache.put(structureKey, s.clone());
-//   }
-
    AtomicMap<Object, Fqn> getStructure() {
       return cache.getAtomicMap(structureKey, Object.class, Fqn.class);
    }

Modified: core/branches/flat/src/main/java/org/horizon/tree/TreeCache.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/tree/TreeCache.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/tree/TreeCache.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -23,6 +23,7 @@
 
 import org.horizon.Cache;
 import org.horizon.CacheException;
+import org.horizon.invocation.Options;
 import org.horizon.lifecycle.Lifecycle;
 
 import java.util.Map;
@@ -56,6 +57,8 @@
     */
    Node<K, V> getRoot();
 
+   Node<K, V> getRoot(Options... options);
+
    /**
     * Associates the specified value with the specified key for a {@link Node} in this cache. If the {@link Node}
     * previously contained a mapping for this key, the old value is replaced by the specified value.
@@ -70,6 +73,8 @@
     */
    V put(Fqn fqn, K key, V value);
 
+   V put(Fqn fqn, K key, V value, Options... options);
+
    /**
     * Convenience method that takes a string representation of an Fqn.  Otherwise identical to {@link #put(Fqn, Object,
     * Object)}
@@ -85,31 +90,7 @@
 
    V put(String fqn, K key, V value);
 
-   /**
-    * Under special operating behavior, associates the value with the specified key for a node identified by the Fqn
-    * passed in. <ul> <li> Only goes through if the node specified does not exist; no-op otherwise.</i> <li> Force
-    * asynchronous mode for replication to prevent any blocking.</li> <li> invalidation does not take place. </li> <li>
-    * 0ms lock timeout to prevent any blocking here either. If the lock is not acquired, this method is a no-op, and
-    * swallows the timeout exception.</li> <li> Ongoing transactions are suspended before this call, so failures here
-    * will not affect any ongoing transactions.</li> <li> Errors and exceptions are 'silent' - logged at a much lower
-    * level than normal, and this method does not throw exceptions</li> </ul> This method is for caching data that has
-    * an external representation in storage, where, concurrent modification and transactions are not a consideration,
-    * and failure to put the data in the cache should be treated as a 'suboptimal outcome' rather than a 'failing
-    * outcome'.
-    * <p/>
-    * An example of when this method is useful is when data is read from, for example, a legacy datastore, and is cached
-    * before returning the data to the caller.  Subsequent calls would prefer to get the data from the cache and if the
-    * data doesn't exist in the cache, fetch again from the legacy datastore.
-    * <p/>
-    * See <a href="http://jira.jboss.com/jira/browse/JBCACHE-848">JBCACHE-848</a> for details around this feature.
-    * <p/>
-    *
-    * @param fqn   <b><i>absolute</i></b> {@link Fqn} to the {@link Node} to be accessed.
-    * @param key   key with which the specified value is to be associated.
-    * @param value value to be associated with the specified key.
-    * @throws IllegalStateException if {@link #getCacheStatus()} would not return {@link org.horizon.ComponentStatus#STARTED}.
-    */
-   void putForExternalRead(Fqn fqn, K key, V value);
+   V put(String fqn, K key, V value, Options... options);
 
    /**
     * Copies all of the mappings from the specified map to a {@link Node}.
@@ -120,6 +101,8 @@
     */
    void put(Fqn fqn, Map<? extends K, ? extends V> data);
 
+   void put(Fqn fqn, Map<? extends K, ? extends V> data, Options... options);
+
    /**
     * Convenience method that takes a string representation of an Fqn.  Otherwise identical to {@link #put(Fqn,
     * java.util.Map)}
@@ -130,6 +113,8 @@
     */
    void put(String fqn, Map<? extends K, ? extends V> data);
 
+   void put(String fqn, Map<? extends K, ? extends V> data, Options... options);
+
    /**
     * Removes the mapping for this key from a Node. Returns the value to which the Node previously associated the key,
     * or <code>null</code> if the Node contained no mapping for this key.
@@ -141,6 +126,8 @@
     */
    V remove(Fqn fqn, K key);
 
+   V remove(Fqn fqn, K key, Options... options);
+
    /**
     * Convenience method that takes a string representation of an Fqn.  Otherwise identical to {@link #remove(Fqn,
     * Object)}
@@ -152,6 +139,8 @@
     */
    V remove(String fqn, K key);
 
+   V remove(String fqn, K key, Options... options);
+
    /**
     * Removes a {@link Node} indicated by absolute {@link Fqn}.
     *
@@ -161,6 +150,8 @@
     */
    boolean removeNode(Fqn fqn);
 
+   boolean removeNode(Fqn fqn, Options... options);
+
    /**
     * Convenience method that takes a string representation of an Fqn.  Otherwise identical to {@link #removeNode(Fqn)}
     *
@@ -170,6 +161,8 @@
     */
    boolean removeNode(String fqn);
 
+   boolean removeNode(String fqn, Options... options);
+
    /**
     * A convenience method to retrieve a node directly from the cache.  Equivalent to calling
     * cache.getRoot().getChild(fqn).
@@ -180,6 +173,8 @@
     */
    Node<K, V> getNode(Fqn fqn);
 
+   Node<K, V> getNode(Fqn fqn, Options... options);
+
    /**
     * Convenience method that takes a string representation of an Fqn.  Otherwise identical to {@link #getNode(Fqn)}
     *
@@ -189,7 +184,9 @@
     */
    Node<K, V> getNode(String fqn);
 
+   Node<K, V> getNode(String fqn, Options... options);
 
+
    /**
     * Convenience method that allows for direct access to the data in a {@link Node}.
     *
@@ -200,6 +197,8 @@
     */
    V get(Fqn fqn, K key);
 
+   V get(Fqn fqn, K key, Options... options);
+
    /**
     * Convenience method that takes a string representation of an Fqn.  Otherwise identical to {@link #get(Fqn,
     * Object)}
@@ -211,24 +210,9 @@
     */
    V get(String fqn, K key);
 
-   /**
-    * Eviction call that evicts the specified {@link Node} from memory.
-    *
-    * @param fqn       <b><i>absolute</i></b> {@link Fqn} to the {@link Node} to be evicted.
-    * @param recursive evicts children as well
-    * @throws IllegalStateException if the cache is not in a started state
-    */
-   void evict(Fqn fqn, boolean recursive);
+   V get(String fqn, K key, Options... options);
 
    /**
-    * Eviction call that evicts the specified {@link Node} from memory.  Not recursive.
-    *
-    * @param fqn <b><i>absolute</i></b> {@link Fqn} to the {@link Node} to be evicted.
-    * @throws IllegalStateException if the cache is not in a started state
-    */
-   void evict(Fqn fqn);
-
-   /**
     * Moves a part of the cache to a different subtree.
     * <p/>
     * E.g.:
@@ -280,17 +264,23 @@
     * @param newParent  new location under which to attach the node being moved.
     * @throws NodeNotExistsException may throw one of these if the target node does not exist or if a different thread
     *                                has moved this node elsewhere already.
-    * @throws IllegalStateException  if {@link #getCacheStatus()} would not return {@link org.horizon.ComponentStatus#STARTED}.
+    * @throws IllegalStateException  if {@link Cache#getCacheStatus()} would not return {@link
+    *                                org.horizon.ComponentStatus#STARTED}.
     */
    void move(Fqn nodeToMove, Fqn newParent) throws NodeNotExistsException;
 
+   void move(Fqn nodeToMove, Fqn newParent, Options... options) throws NodeNotExistsException;
+
    /**
     * Convenience method that takes in string representations of Fqns.  Otherwise identical to {@link #move(Fqn, Fqn)}
     *
-    * @throws IllegalStateException if {@link #getCacheStatus()} would not return {@link org.horizon.ComponentStatus#STARTED}.
+    * @throws IllegalStateException if {@link Cache#getCacheStatus()} would not return {@link
+    *                               org.horizon.ComponentStatus#STARTED}.
     */
    void move(String nodeToMove, String newParent) throws NodeNotExistsException;
 
+   void move(String nodeToMove, String newParent, Options... options) throws NodeNotExistsException;
+
    /**
     * Retrieves a defensively copied data map of the underlying node.  A convenience method to retrieving a node and
     * getting data from the node directly.
@@ -298,16 +288,21 @@
     * @param fqn
     * @return map of data, or an empty map
     * @throws CacheException
-    * @throws IllegalStateException if {@link #getCacheStatus()} would not return {@link org.horizon.ComponentStatus#STARTED}.
+    * @throws IllegalStateException if {@link Cache#getCacheStatus()} would not return {@link
+    *                               org.horizon.ComponentStatus#STARTED}.
     */
    Map<K, V> getData(Fqn fqn);
 
+   Map<K, V> getData(Fqn fqn, Options... options);
+
    /**
     * Convenience method that takes in a String represenation of the Fqn.  Otherwise identical to {@link
     * #getKeys(Fqn)}.
     */
    Set<K> getKeys(String fqn);
 
+   Set<K> getKeys(String fqn, Options... options);
+
    /**
     * Returns a set of attribute keys for the Fqn. Returns null if the node is not found, otherwise a Set. The set is a
     * copy of the actual keys for this node.
@@ -315,28 +310,37 @@
     * A convenience method to retrieving a node and getting keys from the node directly.
     *
     * @param fqn name of the node
-    * @throws IllegalStateException if {@link #getCacheStatus()} would not return {@link org.horizon.ComponentStatus#STARTED}.
+    * @throws IllegalStateException if {@link Cache#getCacheStatus()} would not return {@link
+    *                               org.horizon.ComponentStatus#STARTED}.
     */
    Set<K> getKeys(Fqn fqn);
 
+   Set<K> getKeys(Fqn fqn, Options... options);
+
    /**
     * Convenience method that takes in a String represenation of the Fqn.  Otherwise identical to {@link
     * #clearData(Fqn)}.
     *
-    * @throws IllegalStateException if {@link #getCacheStatus()} would not return {@link org.horizon.ComponentStatus#STARTED}.
+    * @throws IllegalStateException if {@link Cache#getCacheStatus()} would not return {@link
+    *                               org.horizon.ComponentStatus#STARTED}.
     */
    void clearData(String fqn);
 
+   void clearData(String fqn, Options... options);
+
    /**
     * Removes the keys and properties from a named node.
     * <p/>
     * A convenience method to retrieving a node and getting keys from the node directly.
     *
     * @param fqn name of the node
-    * @throws IllegalStateException if {@link #getCacheStatus()} would not return {@link org.horizon.ComponentStatus#STARTED}.
+    * @throws IllegalStateException if {@link Cache#getCacheStatus()} would not return {@link
+    *                               org.horizon.ComponentStatus#STARTED}.
     */
    void clearData(Fqn fqn);
 
+   void clearData(Fqn fqn, Options... options);
+
    /**
     * @return a reference to the underlying cache instance
     */
@@ -350,6 +354,8 @@
     */
    boolean exists(String fqn);
 
+   boolean exists(String fqn, Options... options);
+
    /**
     * Tests if an Fqn exists.
     *
@@ -357,4 +363,6 @@
     * @return true if the fqn exists, false otherwise
     */
    boolean exists(Fqn fqn);
+
+   boolean exists(Fqn fqn, Options... options);
 }

Modified: core/branches/flat/src/main/java/org/horizon/tree/TreeCacheImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/tree/TreeCacheImpl.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/tree/TreeCacheImpl.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,9 +21,11 @@
  */
 package org.horizon.tree;
 
+import org.horizon.AdvancedCache;
 import org.horizon.Cache;
 import org.horizon.CacheException;
 import org.horizon.atomic.AtomicMap;
+import org.horizon.invocation.Options;
 import org.horizon.logging.Log;
 import org.horizon.logging.LogFactory;
 
@@ -39,21 +41,28 @@
    private static final boolean trace = log.isTraceEnabled();
 
    public TreeCacheImpl(Cache<K, V> cache) {
-      super(cache);
+      super(cache, ((AdvancedCache) cache).getBatchContainer(),
+            ((AdvancedCache) cache).getInvocationContextContainer());
       assertBatchingSupported(cache.getConfiguration());
       createRoot();
    }
 
    public Node<K, V> getRoot() {
-      return new NodeImpl(Fqn.ROOT, cache);
+      return new NodeImpl<K, V>(Fqn.ROOT, cache, batchContainer, icc);
    }
 
+   public Node<K, V> getRoot(Options... options) {
+      icc.get().setOptions(options);
+      return getRoot();
+   }
+
    public V put(String fqn, K key, V value) {
       return put(Fqn.fromString(fqn), key, value);
    }
 
-   public void putForExternalRead(Fqn fqn, K key, V value) {
-      put(fqn, key, value); // TODO implement this properly
+   public V put(String fqn, K key, V value, Options... options) {
+      icc.get().setOptions(options);
+      return put(fqn, key, value);
    }
 
    public void put(Fqn fqn, Map<? extends K, ? extends V> data) {
@@ -66,10 +75,20 @@
       }
    }
 
+   public void put(Fqn fqn, Map<? extends K, ? extends V> data, Options... options) {
+      icc.get().setOptions(options);
+      put(fqn, data);
+   }
+
    public void put(String fqn, Map<? extends K, ? extends V> data) {
       put(Fqn.fromString(fqn), data);
    }
 
+   public void put(String fqn, Map<? extends K, ? extends V> data, Options... options) {
+      icc.get().setOptions(options);
+      put(fqn, data);
+   }
+
    @SuppressWarnings("unchecked")
    public V remove(Fqn fqn, K key) {
       startAtomic();
@@ -82,10 +101,20 @@
       }
    }
 
+   public V remove(Fqn fqn, K key, Options... options) {
+      icc.get().setOptions(options);
+      return remove(fqn, key);
+   }
+
    public V remove(String fqn, K key) {
       return remove(Fqn.fromString(fqn), key);
    }
 
+   public V remove(String fqn, K key, Options... options) {
+      icc.get().setOptions(options);
+      return remove(fqn, key);
+   }
+
    public boolean removeNode(Fqn fqn) {
       if (fqn.isRoot()) return false;
       startAtomic();
@@ -98,15 +127,25 @@
       }
    }
 
+   public boolean removeNode(Fqn fqn, Options... options) {
+      icc.get().setOptions(options);
+      return removeNode(fqn);
+   }
+
    public boolean removeNode(String fqn) {
       return removeNode(Fqn.fromString(fqn));
    }
 
+   public boolean removeNode(String fqn, Options... options) {
+      icc.get().setOptions(options);
+      return removeNode(fqn);
+   }
+
    public Node<K, V> getNode(Fqn fqn) {
       startAtomic();
       try {
          if (exists(fqn))
-            return new NodeImpl(fqn, cache);
+            return new NodeImpl<K, V>(fqn, cache, batchContainer, icc);
          else return null;
       }
       finally {
@@ -114,10 +153,20 @@
       }
    }
 
+   public Node<K, V> getNode(Fqn fqn, Options... options) {
+      icc.get().setOptions(options);
+      return getNode(fqn);
+   }
+
    public Node<K, V> getNode(String fqn) {
       return getNode(Fqn.fromString(fqn));
    }
 
+   public Node<K, V> getNode(String fqn, Options... options) {
+      icc.get().setOptions(options);
+      return getNode(fqn);
+   }
+
    @SuppressWarnings("unchecked")
    public V get(Fqn fqn, K key) {
       Map m = cache.getAtomicMap(new NodeKey(fqn, NodeKey.Type.DATA));
@@ -125,68 +174,34 @@
       return (V) m.get(key);
    }
 
+   public V get(Fqn fqn, K key, Options... options) {
+      icc.get().setOptions(options);
+      return get(fqn, key);
+   }
+
    public boolean exists(String f) {
       return exists(Fqn.fromString(f));
    }
 
-   public V get(String fqn, K key) {
-      return get(Fqn.fromString(fqn), key);
+   public boolean exists(String fqn, Options... options) {
+      icc.get().setOptions(options);
+      return exists(fqn);
    }
 
-   public void evict(Fqn fqn, boolean recursive) {
-      boolean removeFromParent;
-      if (recursive) {
-         childFirstEvict(fqn);
-         removeFromParent = true;
-      } else {
-         removeFromParent = evictNode((NodeImpl) getNode(fqn), false);
-      }
-
-      if (!fqn.isRoot() && removeFromParent) {
-         Node parent = getNode(fqn.getParent());
-         parent.removeChild(fqn.getLastElement());
-      }
+   public boolean exists(Fqn fqn, Options... options) {
+      icc.get().setOptions(options);
+      return exists(fqn);
    }
 
-   private void childFirstEvict(Fqn fqn) {
-      Node n = getNode(fqn);
-      if (n != null) {
-         for (Object childName : n.getChildrenNames()) {
-            childFirstEvict(Fqn.fromRelativeElements(fqn, childName));
-         }
-      }
-      evictNode((NodeImpl) n, true);
+   public V get(String fqn, K key) {
+      return get(Fqn.fromString(fqn), key);
    }
 
-   /**
-    * Returns true if the node was completely removed; false if just the data was evicted.
-    *
-    * @param node
-    * @param recursive
-    * @return
-    */
-   private boolean evictNode(NodeImpl node, boolean recursive) {
-      boolean retval = false;
-      if (node != null) {
-         if (recursive || node.getChildrenNames().isEmpty()) {
-            cache.evict(node.structureKey);
-            retval = true;
-         }
-         cache.evict(node.dataKey);
-      }
-      return retval;
+   public V get(String fqn, K key, Options... options) {
+      icc.get().setOptions(options);
+      return get(fqn, key);
    }
 
-   public void evict(Fqn fqn) {
-      startAtomic();
-      try {
-         getNode(fqn).evict();
-      }
-      finally {
-         endAtomic();
-      }
-   }
-
    public void move(Fqn nodeToMove, Fqn newParent) throws NodeNotExistsException {
       if (nodeToMove == null || newParent == null) throw new NullPointerException("Cannot accept null parameters!");
 
@@ -224,10 +239,20 @@
       }
    }
 
+   public void move(Fqn nodeToMove, Fqn newParent, Options... options) throws NodeNotExistsException {
+      icc.get().setOptions(options);
+      move(nodeToMove, newParent);
+   }
+
    public void move(String nodeToMove, String newParent) throws NodeNotExistsException {
       move(Fqn.fromString(nodeToMove), Fqn.fromString(newParent));
    }
 
+   public void move(String nodeToMove, String newParent, Options... options) throws NodeNotExistsException {
+      icc.get().setOptions(options);
+      move(nodeToMove, newParent);
+   }
+
    public Map<K, V> getData(Fqn fqn) {
       startAtomic();
       try {
@@ -238,10 +263,20 @@
       }
    }
 
+   public Map<K, V> getData(Fqn fqn, Options... options) {
+      icc.get().setOptions(options);
+      return getData(fqn);
+   }
+
    public Set<K> getKeys(String fqn) {
       return getKeys(Fqn.fromString(fqn));
    }
 
+   public Set<K> getKeys(String fqn, Options... options) {
+      icc.get().setOptions(options);
+      return getKeys(fqn);
+   }
+
    public Set<K> getKeys(Fqn fqn) {
       startAtomic();
       try {
@@ -252,10 +287,19 @@
       }
    }
 
+   public Set<K> getKeys(Fqn fqn, Options... options) {
+      icc.get().setOptions(options);
+      return getKeys(fqn);
+   }
+
    public void clearData(String fqn) {
       clearData(Fqn.fromString(fqn));
    }
 
+   public void clearData(String fqn, Options... options) {
+      icc.get().setOptions(options);
+   }
+
    public void clearData(Fqn fqn) {
       startAtomic();
       try {
@@ -266,6 +310,10 @@
       }
    }
 
+   public void clearData(Fqn fqn, Options... options) {
+      icc.get().setOptions(options);
+   }
+
    @SuppressWarnings("unchecked")
    public V put(Fqn fqn, K key, V value) {
       if (trace) log.trace("Start: Putting value under key [" + key + "] for node [" + fqn + "]");
@@ -280,6 +328,11 @@
       }
    }
 
+   public V put(Fqn fqn, K key, V value, Options... options) {
+      icc.get().setOptions(options);
+      return put(fqn, key, value);
+   }
+
    // ------------------ nothing different; just delegate to the cache
    public Cache getCache() {
       return cache;

Modified: core/branches/flat/src/main/java/org/horizon/tree/TreeStructureSupport.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/tree/TreeStructureSupport.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/tree/TreeStructureSupport.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -22,17 +22,22 @@
 package org.horizon.tree;
 
 import org.horizon.Cache;
-import org.horizon.CacheSPI;
 import org.horizon.atomic.AtomicMap;
 import org.horizon.atomic.AtomicMapCache;
 import org.horizon.batch.AutoBatchSupport;
+import org.horizon.batch.BatchContainer;
+import org.horizon.invocation.InvocationContextContainer;
+import org.horizon.invocation.Options;
+import org.horizon.lock.LockManager;
 
 public class TreeStructureSupport extends AutoBatchSupport {
    AtomicMapCache cache;
+   InvocationContextContainer icc;
 
-   public TreeStructureSupport(Cache cache) {
+   public TreeStructureSupport(Cache cache, BatchContainer batchContainer, InvocationContextContainer icc) {
       this.cache = (AtomicMapCache) cache;
-      batchContainer = ((CacheSPI) cache).getBatchContainer();
+      this.batchContainer = batchContainer;
+      this.icc = icc;
    }
 
    public boolean exists(Fqn f) {
@@ -60,7 +65,7 @@
             if (!exists(parent)) createNodeInCache(parent);
             AtomicMap<Object, Fqn> parentStructure = getStructure(parent);
             // don't lock parents for child insert/removes!
-            cache.getInvocationContext().getOptionOverrides().setSuppressLocking(true);
+            icc.get().setOptions(Options.SKIP_LOCKING);
             parentStructure.put(fqn.getLastElement(), fqn);
          }
          cache.getAtomicMap(structureKey);
@@ -81,8 +86,7 @@
 //      cache.put(new NodeKey(fqn, NodeKey.Type.STRUCTURE), structure.clone());
 //   }
 
-   public static boolean isLocked(Cache c, Fqn fqn) {
-      org.horizon.lock.LockManager lockManager = ((CacheSPI) c).getLockManager();
+   public static boolean isLocked(Cache c, LockManager lockManager, Fqn fqn) {
       return lockManager.isLocked(new NodeKey(fqn, NodeKey.Type.STRUCTURE)) &&
             lockManager.isLocked(new NodeKey(fqn, NodeKey.Type.DATA));
    }

Modified: core/branches/flat/src/main/java/org/horizon/util/TestingUtil.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/util/TestingUtil.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/main/java/org/horizon/util/TestingUtil.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -7,9 +7,9 @@
 
 package org.horizon.util;
 
+import org.horizon.AdvancedCache;
 import org.horizon.Cache;
 import org.horizon.CacheDelegate;
-import org.horizon.CacheSPI;
 import org.horizon.ComponentStatus;
 import org.horizon.commands.CommandsFactory;
 import org.horizon.commands.VisitableCommand;
@@ -82,8 +82,8 @@
       }
    }
 
-   public static <T extends CommandInterceptor> T findInterceptor(CacheSPI<?, ?> cache, Class<T> interceptorToFind) {
-      for (CommandInterceptor i : cache.getInterceptorChain()) {
+   public static <T extends CommandInterceptor> T findInterceptor(Cache<?, ?> cache, Class<T> interceptorToFind) {
+      for (CommandInterceptor i : cache.getAdvancedCache().getInterceptorChain()) {
          if (interceptorToFind.isInstance(i)) return interceptorToFind.cast(i);
       }
       return null;
@@ -147,20 +147,20 @@
     * @throws RuntimeException if <code>timeout</code> ms have elapse without all caches having the same number of
     *                          members.
     */
-   public static void blockUntilViewsReceived(CacheSPI[] caches, long timeout) {
-      long failTime = System.currentTimeMillis() + timeout;
+//   public static void blockUntilViewsReceived(Cache[] caches, long timeout) {
+//      long failTime = System.currentTimeMillis() + timeout;
+//
+//      while (System.currentTimeMillis() < failTime) {
+//         sleepThread(100);
+//         if (areCacheViewsComplete(caches)) {
+//            return;
+//         }
+//      }
+//
+//      throw new RuntimeException("timed out before caches had complete views");
+//   }
 
-      while (System.currentTimeMillis() < failTime) {
-         sleepThread(100);
-         if (areCacheViewsComplete(caches)) {
-            return;
-         }
-      }
 
-      throw new RuntimeException("timed out before caches had complete views");
-   }
-
-
    /**
     * An overloaded version of {@link #blockUntilViewsReceived(long,Cache[])} that allows for 'shrinking' clusters.
     * I.e., the usual method barfs if there are more members than expected.  This one takes a param
@@ -193,11 +193,11 @@
     * @throws RuntimeException if <code>timeout</code> ms have elapse without all caches having the same number of
     *                          members.
     */
-   public static void blockUntilViewReceived(CacheSPI cache, int groupSize, long timeout) {
+   public static void blockUntilViewReceived(Cache cache, int groupSize, long timeout) {
       blockUntilViewReceived(cache, groupSize, timeout, true);
    }
 
-   public static void blockUntilViewReceived(CacheSPI cache, int groupSize, long timeout, boolean barfIfTooManyMembersInView) {
+   public static void blockUntilViewReceived(Cache cache, int groupSize, long timeout, boolean barfIfTooManyMembersInView) {
       long failTime = System.currentTimeMillis() + timeout;
 
       while (System.currentTimeMillis() < failTime) {
@@ -234,21 +234,6 @@
       return true;
    }
 
-   /**
-    * Checks each cache to see if the number of elements in the array returned by {@link RPCManager#getMembers()}
-    * matches the size of the <code>caches</code> parameter.
-    *
-    * @param caches caches that should form a View
-    * @return <code>true</code> if all caches have <code>caches.length</code> members; false otherwise
-    * @throws IllegalStateException if any of the caches have MORE view members than caches.length
-    */
-   public static boolean areCacheViewsComplete(CacheSPI[] caches) {
-      if (caches == null) throw new NullPointerException("Cache impl array is null");
-      Cache[] c = new Cache[caches.length];
-      for (int i = 0; i < caches.length; i++) c[i] = caches[i];
-      return areCacheViewsComplete(c);
-   }
-
    public static boolean areCacheViewsComplete(boolean barfIfTooManyMembers, CacheManager... cacheManagers) {
       if (cacheManagers == null) throw new NullPointerException("Cache Manager array is null");
       int memberCount = cacheManagers.length;
@@ -262,37 +247,37 @@
       return true;
    }
 
-   /**
-    * @param cache
-    * @param memberCount
-    */
-   public static boolean isCacheViewComplete(CacheSPI cache, int memberCount) {
-      List members = cache.getRPCManager().getMembers();
-      if (members == null || memberCount > members.size()) {
-         return false;
-      } else if (memberCount < members.size()) {
-         // This is an exceptional condition
-         StringBuilder sb = new StringBuilder("Cache at address ");
-         sb.append(cache.getCacheManager().getAddress());
-         sb.append(" had ");
-         sb.append(members.size());
-         sb.append(" members; expecting ");
-         sb.append(memberCount);
-         sb.append(". Members were (");
-         for (int j = 0; j < members.size(); j++) {
-            if (j > 0) {
-               sb.append(", ");
-            }
-            sb.append(members.get(j));
-         }
-         sb.append(')');
+//   /**
+//    * @param cache
+//    * @param memberCount
+//    */
+//   public static boolean isCacheViewComplete(Cache cache, int memberCount) {
+//      List members = cache.getCacheManager().getMembers();
+//      if (members == null || memberCount > members.size()) {
+//         return false;
+//      } else if (memberCount < members.size()) {
+//         // This is an exceptional condition
+//         StringBuilder sb = new StringBuilder("Cache at address ");
+//         sb.append(cache.getCacheManager().getAddress());
+//         sb.append(" had ");
+//         sb.append(members.size());
+//         sb.append(" members; expecting ");
+//         sb.append(memberCount);
+//         sb.append(". Members were (");
+//         for (int j = 0; j < members.size(); j++) {
+//            if (j > 0) {
+//               sb.append(", ");
+//            }
+//            sb.append(members.get(j));
+//         }
+//         sb.append(')');
+//
+//         throw new IllegalStateException(sb.toString());
+//      }
+//
+//      return true;
+//   }
 
-         throw new IllegalStateException(sb.toString());
-      }
-
-      return true;
-   }
-
    /**
     * @param c
     * @param memberCount
@@ -399,16 +384,16 @@
       for (Cache c : caches) {
          try {
             if (c != null && c.getCacheStatus() == ComponentStatus.STARTED) {
-               CacheSPI spi = (CacheSPI) c;
-               if (spi.getTransactionManager() != null) {
+               TransactionManager tm = getTransactionManager(c);
+               if (tm != null) {
                   try {
-                     spi.getTransactionManager().rollback();
+                     tm.rollback();
                   }
                   catch (Exception e) {
                      // don't care
                   }
                }
-               spi.stop();
+               c.stop();
             }
          }
          catch (Throwable t) {
@@ -440,10 +425,10 @@
    public static void killTransactions(Cache... caches) {
       for (Cache c : caches) {
          if (c != null && c.getCacheStatus() == ComponentStatus.STARTED) {
-            CacheSPI ci = (CacheSPI) c;
-            if (ci.getTransactionManager() != null) {
+            TransactionManager tm = getTransactionManager(c);
+            if (tm != null) {
                try {
-                  ci.getTransactionManager().rollback();
+                  tm.rollback();
                }
                catch (Exception e) {
                   // don't care
@@ -489,7 +474,7 @@
     * @param cache       cache that needs to be altered
     * @param interceptor the first interceptor in the new chain.
     */
-   public static void replaceInterceptorChain(CacheSPI<?, ?> cache, CommandInterceptor interceptor) {
+   public static void replaceInterceptorChain(Cache<?, ?> cache, CommandInterceptor interceptor) {
       ComponentRegistry cr = extractComponentRegistry(cache);
       // make sure all interceptors here are wired.
       CommandInterceptor i = interceptor;
@@ -509,9 +494,8 @@
     * @param cache cache instance for which a remote delegate is to be retrieved
     * @return remote delegate, or null if the cacge is not configured for replication.
     */
-   public static CacheDelegate getInvocationDelegate(CacheSPI cache) {
-      ComponentRegistry cr = extractComponentRegistry(cache);
-      return cr.getComponent(CacheDelegate.class);
+   public static CacheDelegate getInvocationDelegate(Cache cache) {
+      return (CacheDelegate) cache;
    }
 
    /**
@@ -522,7 +506,7 @@
     * @param timeout     timeout to wait for
     */
    public static void blockUntilCacheStatusAchieved(Cache cache, ComponentStatus cacheStatus, long timeout) {
-      CacheSPI spi = (CacheSPI) cache;
+      AdvancedCache spi = cache.getAdvancedCache();
       long killTime = System.currentTimeMillis() + timeout;
       while (System.currentTimeMillis() < killTime) {
          if (spi.getCacheStatus() == cacheStatus) return;
@@ -531,7 +515,7 @@
       throw new RuntimeException("Timed out waiting for condition");
    }
 
-   public static void replicateCommand(CacheSPI cache, VisitableCommand command) throws Throwable {
+   public static void replicateCommand(Cache cache, VisitableCommand command) throws Throwable {
       ComponentRegistry cr = extractComponentRegistry(cache);
       InterceptorChain ic = cr.getComponent(InterceptorChain.class);
       ic.invoke(command);
@@ -542,7 +526,7 @@
    }
 
 
-   public static CommandsFactory extractCommandsFactory(CacheSPI<Object, Object> cache) {
+   public static CommandsFactory extractCommandsFactory(Cache<Object, Object> cache) {
       return (CommandsFactory) extractField(cache, "commandsFactory");
    }
 
@@ -550,7 +534,7 @@
       System.out.println("**** START: Cache Contents ****");
       int count = 1;
       for (Object o : caches) {
-         CacheSPI c = (CacheSPI) o;
+         Cache c = (Cache) o;
          if (c == null) {
             System.out.println("  ** Cache " + count + " is null!");
          } else {

Modified: core/branches/flat/src/test/java/org/horizon/BaseClusteredTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/BaseClusteredTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/BaseClusteredTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -113,7 +113,7 @@
 
       public ReplListener(Cache c) {
          this.c = c;
-         this.c.addInterceptor(new ReplListenerInterceptor(), 0);
+         this.c.getAdvancedCache().addInterceptor(new ReplListenerInterceptor(), 0);
       }
 
       /**

Modified: core/branches/flat/src/test/java/org/horizon/api/CacheAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/CacheAPITest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/api/CacheAPITest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,7 +1,6 @@
 package org.horizon.api;
 
 import org.horizon.Cache;
-import org.horizon.CacheSPI;
 import org.horizon.UnitTestCacheFactory;
 import org.horizon.config.Configuration;
 import org.horizon.config.ConfigurationException;
@@ -26,7 +25,7 @@
 
 @Test(groups = "functional", sequential = true)
 public abstract class CacheAPITest {
-   private ThreadLocal<CacheSPI<String, String>> cacheTL = new ThreadLocal<CacheSPI<String, String>>();
+   private ThreadLocal<Cache<String, String>> cacheTL = new ThreadLocal<Cache<String, String>>();
 
    @BeforeMethod(alwaysRun = true)
    public void setUp() throws Exception {
@@ -35,7 +34,7 @@
       c.setIsolationLevel(getIsolationLevel());
       c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
       UnitTestCacheFactory<String, String> cf = new UnitTestCacheFactory<String, String>();
-      CacheSPI<String, String> cache = (CacheSPI<String, String>) cf.createCache(c.clone());
+      Cache<String, String> cache = cf.createCache(c.clone());
       cacheTL.set(cache);
    }
 
@@ -43,7 +42,7 @@
 
    @AfterMethod(alwaysRun = true)
    public void tearDown() {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       TestingUtil.killCaches(cache);
       cacheTL.set(null);
    }
@@ -52,7 +51,7 @@
     * Tests that the configuration contains the values expected, as well as immutability of certain elements
     */
    public void testConfiguration() {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       Configuration c = cache.getConfiguration();
       assertEquals(Configuration.CacheMode.LOCAL, c.getCacheMode());
       assertEquals(DummyTransactionManagerLookup.class.getName(), c.getTransactionManagerLookupClass());
@@ -71,12 +70,12 @@
    }
 
    public void testGetMembersInLocalMode() {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       assert cache.getCacheManager().getAddress() == null : "Cache members should be null if running in LOCAL mode";
    }
 
    public void testConvenienceMethods() {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       String key = "key", value = "value";
       Map<String, String> data = new HashMap<String, String>();
       data.put(key, value);
@@ -100,7 +99,7 @@
     * Tests basic eviction
     */
    public void testEvict() {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       String key1 = "keyOne", key2 = "keyTwo", value = "value";
 
       cache.put(key1, value);
@@ -125,7 +124,7 @@
    }
 
    public void testStopClearsData() throws Exception {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       String key = "key", value = "value";
       cache.put(key, value);
       assert cache.get(key).equals(value);
@@ -139,7 +138,7 @@
    }
 
    public void testRollbackAfterPut() throws Exception {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       String key = "key", value = "value";
       cache.put(key, value);
       assert cache.get(key).equals(value);
@@ -155,7 +154,7 @@
    }
 
    public void testRollbackAfterOverwrite() throws Exception {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       String key = "key", value = "value";
       cache.put(key, value);
       assert cache.get(key).equals(value);
@@ -172,7 +171,7 @@
    }
 
    public void testRollbackAfterRemove() throws Exception {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       String key = "key", value = "value";
       cache.put(key, value);
       assert cache.get(key).equals(value);
@@ -188,7 +187,7 @@
    }
 
    public void testRollbackAfterClear() throws Exception {
-      CacheSPI<String, String> cache = cacheTL.get();
+      Cache<String, String> cache = cacheTL.get();
       String key = "key", value = "value";
       cache.put(key, value);
       assert cache.get(key).equals(value);
@@ -204,7 +203,7 @@
    }
 
    public void testConcurrentMapMethods() {
-      CacheSPI<String, String> c = cacheTL.get();
+      Cache<String, String> c = cacheTL.get();
 
       assert c.putIfAbsent("A", "B") == null;
       assert c.putIfAbsent("A", "C").equals("B");

Modified: core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,8 +1,9 @@
 package org.horizon.api;
 
+import org.horizon.AdvancedCache;
 import org.horizon.BaseClusteredTest;
-import org.horizon.Cache;
 import org.horizon.config.Configuration;
+import org.horizon.invocation.Options;
 import org.horizon.manager.CacheManager;
 import org.horizon.util.TestingUtil;
 import org.testng.annotations.BeforeMethod;
@@ -10,11 +11,11 @@
 
 @Test(groups = "functional", sequential = true)
 public class MixedModeTest extends BaseClusteredTest {
-   Cache replSyncCache1, replSyncCache2;
-   Cache replAsyncCache1, replAsyncCache2;
-   Cache invalAsyncCache1, invalAsyncCache2;
-   Cache invalSyncCache1, invalSyncCache2;
-   Cache localCache1, localCache2;
+   AdvancedCache replSyncCache1, replSyncCache2;
+   AdvancedCache replAsyncCache1, replAsyncCache2;
+   AdvancedCache invalAsyncCache1, invalAsyncCache2;
+   AdvancedCache invalSyncCache1, invalSyncCache2;
+   AdvancedCache localCache1, localCache2;
 
    @BeforeMethod
    public void setUp() {
@@ -42,16 +43,16 @@
       defineCacheOnAllManagers("invalAsync", invalAsync);
       defineCacheOnAllManagers("local", local);
 
-      replSyncCache1 = cm1.getCache("replSync");
-      replSyncCache2 = cm2.getCache("replSync");
-      replAsyncCache1 = cm1.getCache("replAsync");
-      replAsyncCache2 = cm2.getCache("replAsync");
-      invalSyncCache1 = cm1.getCache("invalSync");
-      invalSyncCache2 = cm2.getCache("invalSync");
-      invalAsyncCache1 = cm1.getCache("invalAsync");
-      invalAsyncCache2 = cm2.getCache("invalAsync");
-      localCache1 = cm1.getCache("local");
-      localCache2 = cm2.getCache("local");
+      replSyncCache1 = cm1.getCache("replSync").getAdvancedCache();
+      replSyncCache2 = cm2.getCache("replSync").getAdvancedCache();
+      replAsyncCache1 = cm1.getCache("replAsync").getAdvancedCache();
+      replAsyncCache2 = cm2.getCache("replAsync").getAdvancedCache();
+      invalSyncCache1 = cm1.getCache("invalSync").getAdvancedCache();
+      invalSyncCache2 = cm2.getCache("invalSync").getAdvancedCache();
+      invalAsyncCache1 = cm1.getCache("invalAsync").getAdvancedCache();
+      invalAsyncCache2 = cm2.getCache("invalAsync").getAdvancedCache();
+      localCache1 = cm1.getCache("local").getAdvancedCache();
+      localCache2 = cm2.getCache("local").getAdvancedCache();
 
       TestingUtil.blockUntilViewsReceived(60000, cm1, cm2);
    }
@@ -60,12 +61,10 @@
       ReplListener r1 = attachReplicationListener(replAsyncCache2);
       ReplListener r2 = attachReplicationListener(invalAsyncCache2);
 
-      invalSyncCache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      invalSyncCache2.put("k", "v");
+      invalSyncCache2.put("k", "v", Options.CACHE_MODE_LOCAL);
       assert invalSyncCache2.get("k").equals("v");
       assert invalSyncCache1.get("k") == null;
-      invalAsyncCache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      invalAsyncCache2.put("k", "v");
+      invalAsyncCache2.put("k", "v", Options.CACHE_MODE_LOCAL);
       assert invalAsyncCache2.get("k").equals("v");
       assert invalAsyncCache1.get("k") == null;
 

Modified: core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -8,6 +8,7 @@
 import org.horizon.commands.write.PutKeyValueCommand;
 import org.horizon.commands.write.RemoveCommand;
 import org.horizon.config.Configuration;
+import org.horizon.invocation.Options;
 import org.horizon.manager.CacheManager;
 import org.horizon.remoting.RPCManager;
 import org.horizon.remoting.RPCManagerImpl;
@@ -309,8 +310,7 @@
          if (transactional)
             tm1.begin();
 
-         cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-         cache1.putForExternalRead(key, value);
+         cache1.getAdvancedCache().putForExternalRead(key, value, Options.CACHE_MODE_LOCAL);
 
          if (transactional)
             tm1.commit();

Modified: core/branches/flat/src/test/java/org/horizon/api/tree/NodeLockSupport.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/NodeLockSupport.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/NodeLockSupport.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -24,11 +24,11 @@
 package org.horizon.api.tree;
 
 import org.horizon.Cache;
-import org.horizon.CacheSPI;
 import org.horizon.lock.LockManager;
 import org.horizon.tree.Fqn;
 import org.horizon.tree.TreeCache;
 import org.horizon.tree.TreeStructureSupport;
+import org.horizon.util.TestingUtil;
 
 import javax.transaction.TransactionManager;
 
@@ -49,31 +49,31 @@
 
    protected void checkLocks() {
       Cache<Object, Object> cache = cacheTL.get();
-
-      assert !TreeStructureSupport.isLocked(cache, A);
-      assert !TreeStructureSupport.isLocked(cache, Fqn.ROOT);
-      assert TreeStructureSupport.isLocked(cache, C);
-      assert TreeStructureSupport.isLocked(cache, A_B);
-      assert TreeStructureSupport.isLocked(cache, A_B_C);
+      LockManager lm = TestingUtil.extractLockManager(cache);
+      assert !TreeStructureSupport.isLocked(cache, lm, A);
+      assert !TreeStructureSupport.isLocked(cache, lm, Fqn.ROOT);
+      assert TreeStructureSupport.isLocked(cache, lm, C);
+      assert TreeStructureSupport.isLocked(cache, lm, A_B);
+      assert TreeStructureSupport.isLocked(cache, lm, A_B_C);
    }
 
    protected void checkLocksDeep() {
       Cache<Object, Object> cache = cacheTL.get();
+      LockManager lm = TestingUtil.extractLockManager(cache);
+      assert !TreeStructureSupport.isLocked(cache, lm, A);
+      assert !TreeStructureSupport.isLocked(cache, lm, Fqn.ROOT);
+      assert !TreeStructureSupport.isLocked(cache, lm, A_B_D);
 
-      assert !TreeStructureSupport.isLocked(cache, A);
-      assert !TreeStructureSupport.isLocked(cache, Fqn.ROOT);
-      assert !TreeStructureSupport.isLocked(cache, A_B_D);
-
-      assert TreeStructureSupport.isLocked(cache, C);
-      assert TreeStructureSupport.isLocked(cache, C_E);
-      assert TreeStructureSupport.isLocked(cache, A_B);
-      assert TreeStructureSupport.isLocked(cache, A_B_C);
-      assert TreeStructureSupport.isLocked(cache, A_B_C_E);
+      assert TreeStructureSupport.isLocked(cache, lm, C);
+      assert TreeStructureSupport.isLocked(cache, lm, C_E);
+      assert TreeStructureSupport.isLocked(cache, lm, A_B);
+      assert TreeStructureSupport.isLocked(cache, lm, A_B_C);
+      assert TreeStructureSupport.isLocked(cache, lm, A_B_C_E);
    }
 
    protected void assertNoLocks() {
       Cache<Object, Object> cache = cacheTL.get();
-      LockManager lm = ((CacheSPI) cache).getLockManager();
+      LockManager lm = TestingUtil.extractLockManager(cache);
       for (Object key : cache.keySet()) assert !lm.isLocked(key);
    }
 }

Modified: core/branches/flat/src/test/java/org/horizon/api/tree/NodeMoveAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/NodeMoveAPITest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/NodeMoveAPITest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,7 +1,6 @@
 package org.horizon.api.tree;
 
 import org.horizon.Cache;
-import org.horizon.CacheSPI;
 import org.horizon.UnitTestCacheFactory;
 import org.horizon.api.mvcc.LockAssert;
 import org.horizon.config.CacheLoaderConfig;
@@ -58,10 +57,10 @@
       Configuration c = new Configuration();
       c.setFetchInMemoryState(false);
       c.setInvocationBatchingEnabled(true);
-      CacheSPI<Object, Object> cache = (CacheSPI<Object, Object>) new UnitTestCacheFactory<Object, Object>().createCache(c);
+      Cache<Object, Object> cache = new UnitTestCacheFactory<Object, Object>().createCache(c);
 
       cacheTL.set(new TreeCacheImpl<Object, Object>(cache));
-      tmTL.set(cache.getTransactionManager());
+      tmTL.set(TestingUtil.getTransactionManager(cache));
    }
 
    @AfterMethod(alwaysRun = true)
@@ -554,20 +553,21 @@
    protected void checkLocks() {
       TreeCache<Object, Object> tree = cacheTL.get();
       Cache<Object, Object> cache = tree.getCache();
-
-      assert TreeStructureSupport.isLocked(cache, C);
-      assert TreeStructureSupport.isLocked(cache, A_B_C);
+      LockManager lm = TestingUtil.extractLockManager(cache);
+      assert TreeStructureSupport.isLocked(cache, lm, C);
+      assert TreeStructureSupport.isLocked(cache, lm, A_B_C);
    }
 
    protected void checkLocksDeep() {
       TreeCache<Object, Object> tree = cacheTL.get();
       Cache<Object, Object> cache = tree.getCache();
+      LockManager lm = TestingUtil.extractLockManager(cache);
 
       // /a/b, /c, /c/e, /a/b/c and /a/b/c/e should all be locked.
-      assert TreeStructureSupport.isLocked(cache, C);
-      assert TreeStructureSupport.isLocked(cache, C_E);
-      assert TreeStructureSupport.isLocked(cache, A_B_C);
-      assert TreeStructureSupport.isLocked(cache, A_B_C_E);
+      assert TreeStructureSupport.isLocked(cache, lm, C);
+      assert TreeStructureSupport.isLocked(cache, lm, C_E);
+      assert TreeStructureSupport.isLocked(cache, lm, A_B_C);
+      assert TreeStructureSupport.isLocked(cache, lm, A_B_C_E);
    }
 
    protected void assertNoLocks() {

Modified: core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -10,6 +10,7 @@
 import org.horizon.BaseClusteredTest;
 import org.horizon.Cache;
 import org.horizon.config.Configuration;
+import org.horizon.invocation.Options;
 import org.horizon.manager.CacheManager;
 import org.horizon.tree.Fqn;
 import org.horizon.tree.Node;
@@ -93,18 +94,14 @@
       Map<Object, Object> map = new HashMap<Object, Object>();
       map.put("1", "1");
       map.put("2", "2");
-      cache1.getCache().getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      cache1.getRoot().addChild(fqn).putAll(map);
-      cache1.getCache().getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      assertEquals("Value should be set", "1", cache1.get(fqn, "1"));
+      cache1.getRoot().addChild(fqn).putAll(map, Options.SKIP_LOCKING);
+      assertEquals("Value should be set", "1", cache1.get(fqn, "1", Options.SKIP_LOCKING));
 
       map = new HashMap<Object, Object>();
       map.put("3", "3");
       map.put("4", "4");
-      cache1.getCache().getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      cache1.getRoot().addChild(fqn1).putAll(map);
+      cache1.getRoot().addChild(fqn1).putAll(map, Options.SKIP_LOCKING);
 
-      cache1.getCache().getInvocationContext().getOptionOverrides().setSuppressLocking(true);
-      assertEquals("Value should be set", "2", cache1.get(fqn, "2"));
+      assertEquals("Value should be set", "2", cache1.get(fqn, "2", Options.SKIP_LOCKING));
    }
 }

Modified: core/branches/flat/src/test/java/org/horizon/api/tree/TreeCacheAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/TreeCacheAPITest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/TreeCacheAPITest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,7 +1,6 @@
 package org.horizon.api.tree;
 
 import org.horizon.Cache;
-import org.horizon.CacheSPI;
 import org.horizon.config.Configuration;
 import org.horizon.manager.DefaultCacheManager;
 import org.horizon.transaction.DummyTransactionManagerLookup;
@@ -41,7 +40,7 @@
       Cache flatcache = cm.getCache();
       cache = new TreeCacheImpl(flatcache);
 
-      tm = ((CacheSPI) cache.getCache()).getTransactionManager();
+      tm = TestingUtil.getTransactionManager(flatcache);
    }
 
    @AfterMethod(alwaysRun = true)
@@ -110,78 +109,6 @@
       assertEquals(false, cache.removeNode(fqn));
    }
 
-   /**
-    * Tests basic eviction
-    */
-   public void testEvict() {
-      Fqn one = Fqn.fromString("/one");
-      Fqn two = Fqn.fromString("/one/two");
-      String key = "key", value = "value";
-
-      cache.getRoot().addChild(one).put(key, value);
-      cache.getRoot().addChild(two).put(key, value);
-
-      assertTrue(cache.getRoot().hasChild(one));
-      assertFalse(cache.getRoot().getChild(one).getData().isEmpty());
-      assertTrue(cache.getRoot().hasChild(two));
-      assertFalse(cache.getRoot().getChild(two).getData().isEmpty());
-
-      // evict two
-      cache.evict(two, false);
-
-      assertTrue(cache.getRoot().hasChild(one));
-      assertTrue(cache.getRoot().getChild(one).getKeys().contains(key));
-      assertFalse(cache.getRoot().hasChild(two));
-
-      // now add 2 again...
-      cache.getRoot().addChild(two).put(key, value);
-
-      // now evict one, NOT recursive
-      cache.evict(one, false);
-
-      // one will NOT be removed, just emptied.
-      assertTrue(cache.getRoot().hasChild(one));
-      assertFalse(cache.getRoot().getChild(one).getKeys().contains(key));
-
-      // two will be unaffected
-      assertTrue(cache.getRoot().hasChild(two));
-      assertTrue(cache.getRoot().getChild(two).getKeys().contains(key));
-   }
-
-
-   /**
-    * Tests recursive eviction
-    */
-   public void testEvictRecursive() {
-      Fqn one = Fqn.fromString("/one");
-      Fqn two = Fqn.fromString("/one/two");
-      String key = "key", value = "value";
-
-      cache.getRoot().addChild(one).put(key, value);
-      cache.getRoot().addChild(two).put(key, value);
-
-      assertTrue(cache.getRoot().hasChild(one));
-      assertFalse(cache.getRoot().getChild(one).getData().isEmpty());
-      assertTrue(cache.getRoot().hasChild(two));
-      assertFalse(cache.getRoot().getChild(two).getData().isEmpty());
-
-      // evict two
-      cache.evict(two, true);
-
-      assertTrue(cache.getRoot().hasChild(one));
-      assertFalse(cache.getRoot().getChild(one).getData().isEmpty());
-      assertFalse(cache.getRoot().hasChild(two));
-
-      // now add 2 again...
-      cache.getRoot().addChild(two).put(key, value);
-
-      // now evict one, recursive
-      cache.evict(one, true);
-
-      assertFalse(cache.getRoot().hasChild(one));
-      assertFalse(cache.getRoot().hasChild(two));
-   }
-
    public void testStopClearsData() throws Exception {
       Fqn a = Fqn.fromString("/a");
       Fqn b = Fqn.fromString("/a/b");

Modified: core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,12 +1,14 @@
 package org.horizon.invalidation;
 
 import static org.easymock.EasyMock.*;
+import org.horizon.AdvancedCache;
 import org.horizon.BaseClusteredTest;
 import org.horizon.Cache;
 import org.horizon.commands.RPCCommand;
 import org.horizon.commands.write.ClearCommand;
 import org.horizon.commands.write.InvalidateCommand;
 import org.horizon.config.Configuration;
+import org.horizon.invocation.Options;
 import org.horizon.remoting.RPCManager;
 import org.horizon.remoting.RPCManagerImpl;
 import org.horizon.remoting.ResponseFilter;
@@ -27,7 +29,7 @@
 
 @Test(groups = "functional", sequential = true)
 public abstract class BaseInvalidationTest extends BaseClusteredTest {
-   protected Cache cache1, cache2;
+   protected AdvancedCache cache1, cache2;
    protected boolean isSync;
 
    @BeforeMethod
@@ -38,17 +40,15 @@
       c.setCacheMode(isSync ? Configuration.CacheMode.INVALIDATION_SYNC : Configuration.CacheMode.INVALIDATION_ASYNC);
       c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
       List<Cache> caches = createClusteredCaches(2, "invalidation", c);
-      cache1 = caches.get(0);
-      cache2 = caches.get(1);
+      cache1 = caches.get(0).getAdvancedCache();
+      cache2 = caches.get(1).getAdvancedCache();
       TestingUtil.blockUntilViewsReceived(10000, cache1, cache2);
    }
 
    public void testRemove() throws Exception {
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "value");
+      cache1.put("key", "value", Options.CACHE_MODE_LOCAL);
       assertEquals("value", cache1.get("key"));
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value");
+      cache2.put("key", "value", Options.CACHE_MODE_LOCAL);
       assertEquals("value", cache2.get("key"));
 
       ReplListener rl = attachReplicationListener(cache2);
@@ -193,8 +193,7 @@
    }
 
    public void testPutIfAbsent() {
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value");
+      cache2.put("key", "value", Options.CACHE_MODE_LOCAL);
       assert cache2.get("key").equals("value");
       assert cache1.get("key") == null;
 
@@ -206,8 +205,7 @@
       assert cache1.get("key").equals("value");
       assert cache2.get("key") == null;
 
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
 
       assert cache1.get("key").equals("value");
       assert cache2.get("key").equals("value2");
@@ -219,10 +217,8 @@
    }
 
    public void testRemoveIfPresent() {
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "value1");
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache1.put("key", "value1", Options.CACHE_MODE_LOCAL);
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key").equals("value1");
       assert cache2.get("key").equals("value2");
 
@@ -241,10 +237,8 @@
    }
 
    public void testClear() {
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "value1");
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache1.put("key", "value1", Options.CACHE_MODE_LOCAL);
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key").equals("value1");
       assert cache2.get("key").equals("value2");
 
@@ -258,8 +252,7 @@
    }
 
    public void testReplace() {
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key") == null;
       assert cache2.get("key").equals("value2");
 
@@ -268,8 +261,7 @@
       assert cache1.get("key") == null;
       assert cache2.get("key").equals("value2");
 
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "valueN");
+      cache1.put("key", "valueN", Options.CACHE_MODE_LOCAL);
 
       ReplListener r = attachReplicationListener(cache2);
       r.expect(InvalidateCommand.class);
@@ -281,8 +273,7 @@
    }
 
    public void testReplaceWithOldVal() {
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key") == null;
       assert cache2.get("key").equals("value2");
 
@@ -291,8 +282,7 @@
       assert cache1.get("key") == null;
       assert cache2.get("key").equals("value2");
 
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "valueN");
+      cache1.put("key", "valueN", Options.CACHE_MODE_LOCAL);
 
       cache1.replace("key", "valueOld", "value1"); // should do nothing since there is nothing to replace on cache1
 

Modified: core/branches/flat/src/test/java/org/horizon/notifications/cachelistener/CacheNotifierImplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/notifications/cachelistener/CacheNotifierImplTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/notifications/cachelistener/CacheNotifierImplTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -2,9 +2,11 @@
 
 import org.easymock.EasyMock;
 import static org.easymock.EasyMock.createNiceMock;
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
 import org.horizon.context.InvocationContext;
 import org.horizon.context.InvocationContextImpl;
+import org.horizon.factories.context.ContextFactory;
+import org.horizon.invocation.InvocationContextContainer;
 import org.horizon.notifications.cachelistener.event.CacheEntryEvent;
 import org.horizon.notifications.cachelistener.event.CacheEntryModifiedEvent;
 import org.horizon.notifications.cachelistener.event.CacheEntryRemovedEvent;
@@ -19,17 +21,18 @@
 @Test(groups = "unit", sequential = true)
 public class CacheNotifierImplTest {
    CacheNotifierImpl n;
-   CacheSPI mockCache;
+   Cache mockCache;
    CacheListener cl;
    InvocationContext ctx;
 
    @BeforeMethod
    public void setUp() {
       n = new CacheNotifierImpl();
-      mockCache = createNiceMock(CacheSPI.class);
-      EasyMock.expect(mockCache.getInvocationContext()).andReturn(new InvocationContextImpl()).anyTimes();
+      mockCache = createNiceMock(Cache.class);
       EasyMock.replay(mockCache);
-      n.injectDependencies(mockCache);
+      InvocationContextContainer icc = new InvocationContextContainer();
+      icc.injectContextFactory(new ContextFactory());
+      n.injectDependencies(icc, mockCache);
       cl = new CacheListener();
       n.start();
       n.addListener(cl);

Modified: core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -1,5 +1,6 @@
 package org.horizon.replication;
 
+import org.horizon.AdvancedCache;
 import org.horizon.BaseClusteredTest;
 import org.horizon.Cache;
 import org.horizon.commands.write.ClearCommand;
@@ -8,6 +9,7 @@
 import org.horizon.commands.write.RemoveCommand;
 import org.horizon.commands.write.ReplaceCommand;
 import org.horizon.config.Configuration;
+import org.horizon.invocation.Options;
 import org.horizon.transaction.DummyTransactionManagerLookup;
 import org.horizon.util.TestingUtil;
 import org.testng.annotations.BeforeMethod;
@@ -20,7 +22,7 @@
 @Test(groups = "functional", sequential = true)
 public abstract class BaseReplicatedAPITest extends BaseClusteredTest {
 
-   Cache cache1, cache2;
+   AdvancedCache cache1, cache2;
    protected boolean isSync;
 
    @BeforeMethod
@@ -31,8 +33,8 @@
       c.setCacheMode(isSync ? Configuration.CacheMode.REPL_SYNC : Configuration.CacheMode.REPL_ASYNC);
       c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
       List<Cache> caches = createClusteredCaches(2, "replication", c);
-      cache1 = caches.get(0);
-      cache2 = caches.get(1);
+      cache1 = caches.get(0).getAdvancedCache();
+      cache2 = caches.get(1).getAdvancedCache();
       TestingUtil.blockUntilViewsReceived(10000, cache1, cache2);
    }
 
@@ -66,8 +68,7 @@
    }
 
    public void remove() {
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value");
+      cache2.put("key", "value", Options.CACHE_MODE_LOCAL);
       assert cache2.get("key").equals("value");
       assert cache1.get("key") == null;
 
@@ -79,10 +80,8 @@
       assert cache1.get("key") == null;
       assert cache2.get("key") == null;
 
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "value");
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value");
+      cache1.put("key", "value", Options.CACHE_MODE_LOCAL);
+      cache2.put("key", "value", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key").equals("value");
       assert cache2.get("key").equals("value");
 
@@ -95,8 +94,7 @@
    }
 
    public void testPutIfAbsent() {
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "valueOld");
+      cache2.put("key", "valueOld", Options.CACHE_MODE_LOCAL);
       assert cache2.get("key").equals("valueOld");
       assert cache1.get("key") == null;
 
@@ -108,8 +106,7 @@
       assert cache1.get("key").equals("value");
       assert cache2.get("key").equals("value");
 
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
 
       assert cache1.get("key").equals("value");
       assert cache2.get("key").equals("value2");
@@ -121,10 +118,8 @@
    }
 
    public void testRemoveIfPresent() {
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "value1");
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache1.put("key", "value1", Options.CACHE_MODE_LOCAL);
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key").equals("value1");
       assert cache2.get("key").equals("value2");
 
@@ -143,10 +138,8 @@
    }
 
    public void testClear() {
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "value1");
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache1.put("key", "value1", Options.CACHE_MODE_LOCAL);
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key").equals("value1");
       assert cache2.get("key").equals("value2");
 
@@ -160,8 +153,7 @@
    }
 
    public void testReplace() {
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key") == null;
       assert cache2.get("key").equals("value2");
 
@@ -170,8 +162,7 @@
       assert cache1.get("key") == null;
       assert cache2.get("key").equals("value2");
 
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "valueN");
+      cache1.put("key", "valueN", Options.CACHE_MODE_LOCAL);
 
       BaseClusteredTest.ReplListener r = attachReplicationListener(cache2);
       r.expect(ReplaceCommand.class);
@@ -183,8 +174,7 @@
    }
 
    public void testReplaceWithOldVal() {
-      cache2.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache2.put("key", "value2");
+      cache2.put("key", "value2", Options.CACHE_MODE_LOCAL);
       assert cache1.get("key") == null;
       assert cache2.get("key").equals("value2");
 
@@ -193,8 +183,7 @@
       assert cache1.get("key") == null;
       assert cache2.get("key").equals("value2");
 
-      cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-      cache1.put("key", "valueN");
+      cache1.put("key", "valueN", Options.CACHE_MODE_LOCAL);
 
       cache1.replace("key", "valueOld", "value1"); // should do nothing since there is nothing to replace on cache1
 

Modified: core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -7,6 +7,7 @@
  */
 package org.horizon.replication;
 
+import org.horizon.AdvancedCache;
 import org.horizon.BaseClusteredTest;
 import org.horizon.Cache;
 import org.horizon.commands.VisitableCommand;
@@ -32,7 +33,7 @@
 
 @Test(groups = "functional", sequential = true)
 public class ReplicationExceptionTest extends BaseClusteredTest {
-   private Cache cache1, cache2;
+   private AdvancedCache cache1, cache2;
 
    @BeforeMethod
    public void setUp() {
@@ -46,8 +47,8 @@
 
       List<Cache> caches = createClusteredCaches(2, "replicatinExceptionTest", configuration);
 
-      cache1 = caches.get(0);
-      cache2 = caches.get(1);
+      cache1 = caches.get(0).getAdvancedCache();
+      cache2 = caches.get(1).getAdvancedCache();
    }
 
    private TransactionManager beginTransaction() throws SystemException, NotSupportedException {

Modified: core/branches/flat/src/test/java/org/horizon/tx/LocalModeTxTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/tx/LocalModeTxTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/tx/LocalModeTxTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -21,7 +21,7 @@
  */
 package org.horizon.tx;
 
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
 import org.horizon.UnitTestCacheManager;
 import org.horizon.config.Configuration;
 import org.horizon.transaction.DummyTransactionManagerLookup;
@@ -33,18 +33,18 @@
 
 @Test(groups = "functional")
 public class LocalModeTxTest {
-   private CacheSPI<String, String> createCache() {
+   private Cache<String, String> createCache() {
       Configuration cfg = new Configuration();
       cfg.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
       UnitTestCacheManager cm = new UnitTestCacheManager(cfg);
-      return (CacheSPI<String, String>) cm.createCache("test");
+      return cm.createCache("test");
    }
 
    public void testTxCommit1() throws Exception {
-      CacheSPI c = null;
+      Cache c = null;
       try {
          c = createCache();
-         TransactionManager tm = c.getTransactionManager();
+         TransactionManager tm = TestingUtil.getTransactionManager(c);
          tm.begin();
          c.put("key", "value");
          Transaction t = tm.suspend();
@@ -59,10 +59,10 @@
    }
 
    public void testTxCommit2() throws Exception {
-      CacheSPI c = null;
+      Cache c = null;
       try {
          c = createCache();
-         TransactionManager tm = c.getTransactionManager();
+         TransactionManager tm = TestingUtil.getTransactionManager(c);
          c.put("key", "old");
          tm.begin();
          assert c.get("key").equals("old");

Modified: core/branches/flat/src/test/java/org/horizon/tx/MarkAsRollbackTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/tx/MarkAsRollbackTest.java	2009-02-09 18:29:53 UTC (rev 7668)
+++ core/branches/flat/src/test/java/org/horizon/tx/MarkAsRollbackTest.java	2009-02-09 18:30:59 UTC (rev 7669)
@@ -2,7 +2,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
 import org.horizon.UnitTestCacheFactory;
 import org.horizon.config.Configuration;
 import org.horizon.transaction.DummyTransactionManagerLookup;
@@ -19,9 +19,9 @@
    public void testMarkAsRollbackAfterMods() throws Exception {
       Configuration c = new Configuration();
       c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
-      CacheSPI<String, String> cache = (CacheSPI<String, String>) new UnitTestCacheFactory<String, String>().createCache(c);
+      Cache<String, String> cache = new UnitTestCacheFactory<String, String>().createCache(c);
       try {
-         TransactionManager tm = cache.getTransactionManager();
+         TransactionManager tm = TestingUtil.getTransactionManager(cache);
          assert tm != null;
          tm.begin();
          cache.put("k", "v");
@@ -46,9 +46,9 @@
    public void testMarkAsRollbackBeforeMods() throws Exception {
       Configuration c = new Configuration();
       c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
-      CacheSPI<String, String> cache = (CacheSPI<String, String>) new UnitTestCacheFactory<String, String>().createCache(c);
+      Cache<String, String> cache = new UnitTestCacheFactory<String, String>().createCache(c);
       try {
-         TransactionManager tm = cache.getTransactionManager();
+         TransactionManager tm = TestingUtil.getTransactionManager(cache);
          assert tm != null;
          tm.begin();
          tm.setRollbackOnly();




More information about the jbosscache-commits mailing list