[infinispan-commits] Infinispan SVN: r619 - in trunk: core/src/main/java/org/infinispan/eviction and 12 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Tue Jul 28 10:20:56 EDT 2009


Author: vblagojevic at jboss.com
Date: 2009-07-28 10:20:55 -0400 (Tue, 28 Jul 2009)
New Revision: 619

Added:
   trunk/core/src/main/java/org/infinispan/config/InfinispanConfiguration.java
   trunk/core/src/main/java/org/infinispan/config/TypedPropertiesAdapter.java
   trunk/core/src/main/java/org/infinispan/loaders/decorators/package-info.java
   trunk/core/src/main/java/org/infinispan/util/concurrent/package-info.java
   trunk/tools/src/main/java/org/infinispan/tools/schema/JaxbSchemaGenerator.java
Modified:
   trunk/core/src/main/java/org/infinispan/config/AbstractConfigurationBean.java
   trunk/core/src/main/java/org/infinispan/config/AbstractNamedCacheConfigurationBean.java
   trunk/core/src/main/java/org/infinispan/config/CacheLoaderManagerConfig.java
   trunk/core/src/main/java/org/infinispan/config/Configuration.java
   trunk/core/src/main/java/org/infinispan/config/CustomInterceptorConfig.java
   trunk/core/src/main/java/org/infinispan/config/GlobalConfiguration.java
   trunk/core/src/main/java/org/infinispan/config/PluggableConfigurationComponent.java
   trunk/core/src/main/java/org/infinispan/config/package-info.java
   trunk/core/src/main/java/org/infinispan/eviction/package-info.java
   trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java
   trunk/core/src/main/java/org/infinispan/loaders/AbstractCacheLoaderConfig.java
   trunk/core/src/main/java/org/infinispan/loaders/AbstractCacheStoreConfig.java
   trunk/core/src/main/java/org/infinispan/loaders/CacheLoaderConfig.java
   trunk/core/src/main/java/org/infinispan/loaders/decorators/AsyncStoreConfig.java
   trunk/core/src/main/java/org/infinispan/loaders/decorators/SingletonStoreConfig.java
   trunk/core/src/main/java/org/infinispan/loaders/package-info.java
   trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java
   trunk/core/src/main/java/org/infinispan/util/ReflectionUtil.java
   trunk/core/src/main/java/org/infinispan/util/TypedProperties.java
   trunk/core/src/main/resources/config-samples/all.xml
   trunk/core/src/test/java/org/infinispan/config/parsing/EHCache2InfinispanTransformerTest.java
   trunk/core/src/test/java/org/infinispan/config/parsing/Jbc2InfinispanTransformerTest.java
   trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java
   trunk/core/src/test/java/org/infinispan/loaders/ConcurrentLoadAndEvictTest.java
   trunk/core/src/test/resources/configs/named-cache-test.xml
   trunk/tools/pom.xml
Log:
[ISPN-97] - Improve configuration processing and maintenance
jaxb based configuration processing

Modified: trunk/core/src/main/java/org/infinispan/config/AbstractConfigurationBean.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/AbstractConfigurationBean.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/config/AbstractConfigurationBean.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -21,20 +21,31 @@
  */
 package org.infinispan.config;
 
+import org.infinispan.CacheException;
 import org.infinispan.factories.scopes.Scope;
 import org.infinispan.factories.scopes.Scopes;
+import org.infinispan.util.BeanUtils;
+import org.infinispan.util.ReflectionUtil;
 import org.infinispan.util.TypedProperties;
+import org.infinispan.util.Util;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Properties;
 
+import javax.xml.bind.annotation.XmlElement;
+
 /**
  * Base superclass of Cache configuration classes that expose some properties that can be changed after the cache is
  * started.
@@ -161,6 +172,77 @@
       // now mark this as overridden
       overriddenConfigurationElements.add(fieldName);
    }
+   
+   public void applyOverrides(AbstractConfigurationBean overrides) {
+      //does this component have overridden fields?
+      for (String overridenField : overrides.overriddenConfigurationElements) {
+         try {                     
+            ReflectionUtil.setValue(this, overridenField, ReflectionUtil.getValue(overrides,overridenField));                 
+         } catch (Exception e1) {
+            throw new CacheException("Could not apply value for field " + overridenField
+                     + " from instance " + overrides + " on instance " + this, e1);
+         }
+      }
+      
+      // then recurse into field of this component...
+      List<Field> fields = ReflectionUtil.getFields(overrides.getClass(),AbstractConfigurationBean.class);
+      for (Field field : fields) {
+         if (AbstractConfigurationBean.class.isAssignableFrom(field.getType())) {
+            AbstractConfigurationBean fieldValueOverrides = null;
+            AbstractConfigurationBean fieldValueThis = null;
+            try {
+               field.setAccessible(true);
+               fieldValueOverrides = (AbstractConfigurationBean) field.get(overrides);
+               fieldValueThis = (AbstractConfigurationBean) field.get(this);
+               if(fieldValueOverrides != null && fieldValueThis!=null){
+                  fieldValueThis.applyOverrides(fieldValueOverrides);
+               }
+            } catch (Exception e) {
+               log.warn("Could not apply override for field " + field + " in class " +overrides,e);
+            }
+         }
+      }
+      
+      //and don't forget to recurse into collections of components...
+      fields = ReflectionUtil.getFields(overrides.getClass(), Collection.class);
+      for (Field field : fields) {
+         Type genericType = field.getGenericType();
+         if (genericType instanceof ParameterizedType) {
+            ParameterizedType aType = (ParameterizedType) genericType;
+            Type[] fieldArgTypes = aType.getActualTypeArguments();
+            for (Type fieldArgType : fieldArgTypes) {
+               Class<?> fieldArgClass = (Class<?>) fieldArgType;
+               if (!(fieldArgClass.isPrimitive() || fieldArgClass.equals(String.class))) {
+                  try {
+                     field.setAccessible(true);
+                     Collection<Object> c = (Collection<Object>) field.get(this);
+                     Collection<Object> c2 = (Collection<Object>) field.get(overrides);
+                     if (c.isEmpty() && !c2.isEmpty()) {
+                        c.addAll(c2);
+                     } else if (!c.isEmpty() && !c2.isEmpty()) {
+                        Iterator<?> i = c.iterator();
+                        Iterator<?> i2 = c2.iterator();
+                        for (; i.hasNext() && i2.hasNext();) {
+                           Object nextThis = i.next();
+                           Object nextOverrides = i2.next();
+                           if (AbstractConfigurationBean.class.isAssignableFrom(nextThis.getClass())
+                                    && AbstractConfigurationBean.class.isAssignableFrom(nextOverrides.getClass())) {
+                              ((AbstractConfigurationBean) nextThis).applyOverrides((AbstractConfigurationBean) nextOverrides);
+                           }
+                        }
+                        while (i2.hasNext()) {
+                           c.add(i2.next());
+                        }
+                     }
+                  } catch (Exception e) {
+                     log.warn("Could not apply override for field " + field + " in class " +overrides.getClass(),e);
+                  }
+               }
+            }
+         }
+      }
+   }
+ 
 
 //   public void setCache(CacheSPI cache) {
 //      this.cache = cache;

Modified: trunk/core/src/main/java/org/infinispan/config/AbstractNamedCacheConfigurationBean.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/AbstractNamedCacheConfigurationBean.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/config/AbstractNamedCacheConfigurationBean.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,10 +1,18 @@
 package org.infinispan.config;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
 import org.infinispan.factories.ComponentRegistry;
 import org.infinispan.factories.annotations.Inject;
 import org.infinispan.factories.scopes.Scope;
 import org.infinispan.factories.scopes.Scopes;
 import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.util.ReflectionUtil;
 
 /**
  * Adds named cache specific features to the {@link org.infinispan.config.AbstractConfigurationBean}.
@@ -16,10 +24,54 @@
 public abstract class AbstractNamedCacheConfigurationBean extends AbstractConfigurationBean {
 
    protected ComponentRegistry cr;
-
+   
    @Inject
-   private void inject(ComponentRegistry cr) {
+   public void inject(ComponentRegistry cr) {
       this.cr = cr;
+      
+      // then recurse into field of this component...
+      List<Field> fields = ReflectionUtil.getFields(this.getClass(),AbstractNamedCacheConfigurationBean.class);
+      for (Field field : fields) {         
+         AbstractNamedCacheConfigurationBean fieldValueThis = null;
+            try {
+               field.setAccessible(true);               
+               fieldValueThis = (AbstractNamedCacheConfigurationBean) field.get(this);
+               if(fieldValueThis!=null){
+                  fieldValueThis.inject(cr);
+               }
+            } catch (Exception e) {
+               log.warn("Could not inject for field " + field + " in class " +fieldValueThis,e);
+            }         
+      }
+      
+      //and don't forget to recurse into collections of components...
+      fields = ReflectionUtil.getFields(this.getClass(), Collection.class);
+      for (Field field : fields) {
+         Type genericType = field.getGenericType();
+         if (genericType instanceof ParameterizedType) {
+            ParameterizedType aType = (ParameterizedType) genericType;
+            Type[] fieldArgTypes = aType.getActualTypeArguments();
+            for (Type fieldArgType : fieldArgTypes) {
+               Class<?> fieldArgClass = (Class<?>) fieldArgType;
+               if (!(fieldArgClass.isPrimitive() || fieldArgClass.equals(String.class))) {
+                  try {
+                     field.setAccessible(true);
+                     Collection<Object> c = (Collection<Object>) field.get(this);
+                     for (Object nextThis : c) {
+                        if (AbstractNamedCacheConfigurationBean.class.isAssignableFrom(nextThis.getClass())) {
+                           ((AbstractNamedCacheConfigurationBean) nextThis).inject(cr);
+                        } else {
+                           //collection does not contain AbstractNamedCacheConfigurationBean, skip altogether
+                           break;
+                        }
+                     }
+                  } catch (Exception e) {
+                     log.warn("Could not inject for field " + field + " in class " +field,e);
+                  }
+               }
+            }
+         }
+      }
    }
 
    protected boolean hasComponentStarted() {

Modified: trunk/core/src/main/java/org/infinispan/config/CacheLoaderManagerConfig.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/CacheLoaderManagerConfig.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/config/CacheLoaderManagerConfig.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -21,14 +21,19 @@
  */
 package org.infinispan.config;
 
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+
 import org.infinispan.config.parsing.CacheLoaderManagerConfigReader;
 import org.infinispan.loaders.CacheLoaderConfig;
 import org.infinispan.loaders.CacheStoreConfig;
 import org.infinispan.util.Util;
 
-import java.util.LinkedList;
-import java.util.List;
-
 /**
  * Holds the configuration of the cache loader chain.  ALL cache loaders should be defined using this class, adding
  * individual cache loaders to the chain by calling {@link CacheLoaderManagerConfig#addCacheLoaderConfig}
@@ -39,14 +44,22 @@
  * @since 4.0
  */
 @ConfigurationElement(name="loaders",parent="default",customReader=CacheLoaderManagerConfigReader.class)
+ at XmlAccessorType(XmlAccessType.FIELD)
 public class CacheLoaderManagerConfig extends AbstractNamedCacheConfigurationBean {
    private static final long serialVersionUID = 2210349340378984424L;
 
-   private boolean passivation;
-   private boolean preload;
+   @XmlAttribute
+   private Boolean passivation = false;
+   
+   @XmlAttribute
+   private Boolean preload = false;
+   
+   @XmlAttribute
+   private Boolean shared = false;
+  
+   @XmlElement(name="loader")
    private List<CacheLoaderConfig> cacheLoaderConfigs = new LinkedList<CacheLoaderConfig>();
 
-   private boolean shared;
 
 
    @ConfigurationAttribute(name = "preload", 

Modified: trunk/core/src/main/java/org/infinispan/config/Configuration.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/Configuration.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/config/Configuration.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -21,19 +21,40 @@
  */
 package org.infinispan.config;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
 import org.infinispan.config.parsing.ClusteringConfigReader;
 import org.infinispan.config.parsing.CustomInterceptorConfigReader;
 import org.infinispan.distribution.DefaultConsistentHash;
 import org.infinispan.eviction.EvictionStrategy;
+import org.infinispan.factories.ComponentRegistry;
 import org.infinispan.factories.annotations.Inject;
 import org.infinispan.factories.annotations.NonVolatile;
 import org.infinispan.factories.annotations.Start;
+import org.infinispan.transaction.lookup.GenericTransactionManagerLookup;
 import org.infinispan.util.ReflectionUtil;
 import org.infinispan.util.concurrent.IsolationLevel;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Encapsulates the configuration of a Cache.
@@ -65,83 +86,20 @@
          @ConfigurationElement(name = "customInterceptors", parent = "default",
                   customReader=CustomInterceptorConfigReader.class)         
 })
-public class Configuration extends AbstractNamedCacheConfigurationBean {
+ at XmlAccessorType(XmlAccessType.FIELD)
+ at XmlType(propOrder={})
+public class Configuration extends AbstractNamedCacheConfigurationBean {  
+
    private static final long serialVersionUID = 5553791890144997466L;
 
-   private boolean enableDeadlockDetection = false;
-
-   private long deadlockDetectionSpinDuration = 100;
-
    // reference to a global configuration
+   @XmlTransient
    private GlobalConfiguration globalConfiguration;
+   
+   @XmlAttribute
+   private String name;
 
-   public GlobalConfiguration getGlobalConfiguration() {
-      return globalConfiguration;
-   }
 
-   @Inject
-   private void injectGlobalConfiguration(GlobalConfiguration globalConfiguration) {
-      this.globalConfiguration = globalConfiguration;
-   }
-
-   public boolean isStateTransferEnabled() {
-      return fetchInMemoryState || (cacheLoaderManagerConfig != null && cacheLoaderManagerConfig.isFetchPersistentState());
-   }
-
-
-   public long getDeadlockDetectionSpinDuration() {
-      return deadlockDetectionSpinDuration;
-   }
-
-   @ConfigurationAttribute(name = "spinDuration",  containingElement = "deadlockDetection")
-   public void setDeadlockDetectionSpinDuration(long eagerDeadlockSpinDuration) {
-      testImmutability("eagerDeadlockSpinDuration");
-      this.deadlockDetectionSpinDuration = eagerDeadlockSpinDuration;
-   }
-
-
-   public boolean isEnableDeadlockDetection() {
-      return enableDeadlockDetection;
-   }
-
-   @ConfigurationAttribute(name = "enabled",  containingElement = "deadlockDetection")
-   public void setEnableDeadlockDetection(boolean useEagerDeadlockDetection) {
-      testImmutability("enableDeadlockDetection");
-      this.enableDeadlockDetection = useEagerDeadlockDetection;
-   }
-
-   public void setUseLockStriping(boolean useLockStriping) {
-      testImmutability("useLockStriping");
-      this.useLockStriping = useLockStriping;
-   }
-
-   public boolean isUseLockStriping() {
-      return useLockStriping;
-   }
-
-   public boolean isUnsafeUnreliableReturnValues() {
-      return unsafeUnreliableReturnValues;
-   }
-
-   @ConfigurationAttribute(name = "unreliableReturnValues", 
-            containingElement = "unsafe")    
-   public void setUnsafeUnreliableReturnValues(boolean unsafeUnreliableReturnValues) {
-      testImmutability("unsafeUnreliableReturnValues");
-      this.unsafeUnreliableReturnValues = unsafeUnreliableReturnValues;
-   }
-
-   @ConfigurationAttribute(name = "rehashRpcTimeout", 
-            containingElement = "hash")    
-   public void setRehashRpcTimeout(long rehashRpcTimeout) {
-      testImmutability("rehashRpcTimeout");
-      this.rehashRpcTimeout = rehashRpcTimeout;
-   }
-
-   public long getRehashRpcTimeout() {
-      return rehashRpcTimeout;
-   }
-
-
    /**
     * Cache replication mode.
     */
@@ -234,60 +192,55 @@
    // ------------------------------------------------------------------------------------------------------------
    //   CONFIGURATION OPTIONS
    // ------------------------------------------------------------------------------------------------------------
+   
+   @XmlElement
+   private LockingType locking = new LockingType();
+   
+   @XmlElement
+   private CacheLoaderManagerConfig loaders = new CacheLoaderManagerConfig();
+   
+   @XmlElement
+   private TransactionType transaction = new TransactionType(null);
 
-   private boolean useReplQueue = false;
-   private int replQueueMaxElements = 1000;
-   private long replQueueInterval = 5000;
-   private boolean exposeJmxStatistics = false;
-   @Dynamic
-   private boolean fetchInMemoryState = false;
-   @Dynamic
-   private long lockAcquisitionTimeout = 10000;
-   @Dynamic
-   private long syncReplTimeout = 15000;
-   private CacheMode cacheMode = CacheMode.LOCAL;
-   @Dynamic
-   private long stateRetrievalTimeout = 10000;
-   private IsolationLevel isolationLevel = IsolationLevel.READ_COMMITTED;
-   private String transactionManagerLookupClass = null;
-   private CacheLoaderManagerConfig cacheLoaderManagerConfig = null;
-   @Dynamic
-   private boolean syncCommitPhase = false;
-   @Dynamic
-   private boolean syncRollbackPhase = false;
-   @Dynamic
-   private boolean useEagerLocking = false;
-   private boolean useLazyDeserialization = false;
-   private List<CustomInterceptorConfig> customInterceptors = Collections.emptyList();
-   private boolean writeSkewCheck = false;
-   private int concurrencyLevel = 500;
-   private boolean invocationBatchingEnabled;
-   private long evictionWakeUpInterval = 5000;
-   private EvictionStrategy evictionStrategy = EvictionStrategy.NONE;
-   private int evictionMaxEntries = -1;
-   private long expirationLifespan = -1;
-   private long expirationMaxIdle = -1;
-   private boolean l1CacheEnabled = true;
-   private long l1Lifespan = 600000;
-   private boolean l1OnRehash = true;
-   private String consistentHashClass = DefaultConsistentHash.class.getName();
-   private int numOwners = 2;
-   private long rehashWaitTime = 60000;
-   private boolean useLockStriping = true;
-   private boolean unsafeUnreliableReturnValues = false;
-   private boolean useAsyncMarshalling = true;
-   private long rehashRpcTimeout = 60 * 1000 * 10; // 10 minutes
+   @XmlElement
+   private CustomInterceptorsType customInterceptors = new CustomInterceptorsType();
 
+   @XmlElement
+   private EvictionType eviction = new EvictionType();
+
+   @XmlElement
+   private ExpirationType expiration = new ExpirationType();
+
+   @XmlElement
+   private UnsafeType unsafe = new UnsafeType();
+
+   @XmlElement
+   private ClusteringType clustering = new ClusteringType();
+   
+   @XmlElement
+   private BooleanAttributeType jmxStatistics = new BooleanAttributeType();
+   
+   @XmlElement
+   private BooleanAttributeType lazyDeserialization = new BooleanAttributeType();
+   
+   @XmlElement
+   private BooleanAttributeType invocationBatching = new BooleanAttributeType();
+   
+   @XmlElement
+   private DeadlockDetectionType deadlockDetection = new DeadlockDetectionType();
+   
+
+   @SuppressWarnings("unused")
    @Start(priority = 1)
    private void correctIsolationLevels() {
       // ensure the correct isolation level upgrades and/or downgrades are performed.
-      switch (isolationLevel) {
+      switch (locking.isolationLevel) {
          case NONE:
          case READ_UNCOMMITTED:
-            isolationLevel = IsolationLevel.READ_COMMITTED;
+            locking.isolationLevel = IsolationLevel.READ_COMMITTED;
             break;
          case SERIALIZABLE:
-            isolationLevel = IsolationLevel.REPEATABLE_READ;
+            locking.isolationLevel = IsolationLevel.REPEATABLE_READ;
             break;
       }
    }
@@ -296,42 +249,105 @@
    //   SETTERS - MAKE SURE ALL SETTERS PERFORM testImmutability()!!!
    // ------------------------------------------------------------------------------------------------------------
 
+   public GlobalConfiguration getGlobalConfiguration() {
+      return globalConfiguration;
+   }
+
+   public String getName() {
+      return name;
+   }
+
+   @SuppressWarnings("unused")
+   @Inject
+   private void injectGlobalConfiguration(GlobalConfiguration globalConfiguration) {
+      this.globalConfiguration = globalConfiguration;
+   }
+   
+   
+
+   public boolean isStateTransferEnabled() {
+      return clustering.stateRetrieval.fetchInMemoryState || (loaders != null && loaders.isFetchPersistentState());
+   }
+
+
+   public long getDeadlockDetectionSpinDuration() {
+      return deadlockDetection.spinDuration;
+   }
+
+   @ConfigurationAttribute(name = "spinDuration",  containingElement = "deadlockDetection")
+   public void setDeadlockDetectionSpinDuration(long eagerDeadlockSpinDuration) {
+      this.deadlockDetection.setSpinDuration(eagerDeadlockSpinDuration);
+   }
+
+
+   public boolean isEnableDeadlockDetection() {
+      return deadlockDetection.enabled;
+   }
+
+   @ConfigurationAttribute(name = "enabled",  containingElement = "deadlockDetection")
+   public void setEnableDeadlockDetection(boolean useEagerDeadlockDetection) {
+      this.deadlockDetection.setEnabled(useEagerDeadlockDetection);
+   }
+
+   public void setUseLockStriping(boolean useLockStriping) {
+      locking.setUseLockStriping(useLockStriping);
+   }
+
+   public boolean isUseLockStriping() {
+      return locking.useLockStriping;
+   }
+
+   public boolean isUnsafeUnreliableReturnValues() {
+      return unsafe.unreliableReturnValues;
+   }
+
+   @ConfigurationAttribute(name = "unreliableReturnValues", 
+            containingElement = "unsafe")    
+   public void setUnsafeUnreliableReturnValues(boolean unsafeUnreliableReturnValues) {
+      this.unsafe.setUnreliableReturnValues(unsafeUnreliableReturnValues);
+   }
+
+   @ConfigurationAttribute(name = "rehashRpcTimeout", 
+            containingElement = "hash")    
+   public void setRehashRpcTimeout(long rehashRpcTimeout) {
+      this.clustering.hash.setRehashRpcTimeout(rehashRpcTimeout);
+   }
+
+   public long getRehashRpcTimeout() {
+      return clustering.hash.rehashRpcTimeout;
+   }
    public boolean isWriteSkewCheck() {
-      return writeSkewCheck;
+      return locking.writeSkewCheck;
    }
 
 
    @ConfigurationAttribute(name = "writeSkewCheck", 
             containingElement = "locking")    
    public void setWriteSkewCheck(boolean writeSkewCheck) {
-      testImmutability("writeSkewCheck");
-      this.writeSkewCheck = writeSkewCheck;
+      locking.setWriteSkewCheck(writeSkewCheck);
    }
 
    public int getConcurrencyLevel() {
-      return concurrencyLevel;
+      return locking.concurrencyLevel;
    }
 
 
    @ConfigurationAttribute(name = "concurrencyLevel", 
             containingElement = "locking")    
    public void setConcurrencyLevel(int concurrencyLevel) {
-      testImmutability("concurrencyLevel");
-      this.concurrencyLevel = concurrencyLevel;
+      locking.setConcurrencyLevel(concurrencyLevel);
    }
 
    @ConfigurationAttribute(name = "replQueueMaxElements", 
             containingElement = "async")
    public void setReplQueueMaxElements(int replQueueMaxElements) {
-      testImmutability("replQueueMaxElements");
-      this.replQueueMaxElements = replQueueMaxElements;
+      this.clustering.async.setReplQueueMaxElements(replQueueMaxElements);
    }
 
    @ConfigurationAttribute(name = "replQueueInterval", 
             containingElement = "async")
    public void setReplQueueInterval(long replQueueInterval) {
-      testImmutability("replQueueInterval");
-      this.replQueueInterval = replQueueInterval;
+      this.clustering.async.setReplQueueInterval(replQueueInterval);
    }
 
    public void setReplQueueInterval(long replQueueInterval, TimeUnit timeUnit) {
@@ -341,8 +357,7 @@
    @ConfigurationAttribute(name = "enabled", 
             containingElement = "jmxStatistics")   
    public void setExposeJmxStatistics(boolean useMbean) {
-      testImmutability("exposeJmxStatistics");
-      this.exposeJmxStatistics = useMbean;
+      jmxStatistics.setEnabled(useMbean);
    }
 
    /**
@@ -357,22 +372,19 @@
    @ConfigurationAttribute(name = "enabled", 
             containingElement = "invocationBatching") 
    public void setInvocationBatchingEnabled(boolean enabled) {
-      testImmutability("invocationBatchingEnabled");
-      this.invocationBatchingEnabled = enabled;
+      invocationBatching.setEnabled(enabled);
    }
 
    @ConfigurationAttribute(name = "fetchInMemoryState", 
             containingElement = "stateRetrieval")
    public void setFetchInMemoryState(boolean fetchInMemoryState) {
-      testImmutability("fetchInMemoryState");
-      this.fetchInMemoryState = fetchInMemoryState;
+      this.clustering.stateRetrieval.setFetchInMemoryState(fetchInMemoryState);
    }
 
    @ConfigurationAttribute(name = "lockAcquisitionTimeout", 
             containingElement = "locking")    
    public void setLockAcquisitionTimeout(long lockAcquisitionTimeout) {
-      testImmutability("lockAcquisitionTimeout");
-      this.lockAcquisitionTimeout = lockAcquisitionTimeout;
+      locking.setLockAcquisitionTimeout(lockAcquisitionTimeout);
    }
 
    public void setLockAcquisitionTimeout(long lockAcquisitionTimeout, TimeUnit timeUnit) {
@@ -382,8 +394,7 @@
    @ConfigurationAttribute(name = "replTimeout", 
             containingElement = "sync")    
    public void setSyncReplTimeout(long syncReplTimeout) {
-      testImmutability("syncReplTimeout");
-      this.syncReplTimeout = syncReplTimeout;
+      this.clustering.sync.setReplTimeout(syncReplTimeout);
    }
 
    public void setSyncReplTimeout(long syncReplTimeout, TimeUnit timeUnit) {
@@ -391,24 +402,22 @@
    }
 
    public void setCacheMode(CacheMode cacheModeInt) {
-      testImmutability("cacheMode");
-      this.cacheMode = cacheModeInt;
+      clustering.setMode(cacheModeInt);
    }
 
    @ConfigurationAttribute(name = "mode", 
             containingElement = "clustering", allowedValues={"LOCAL","REPL","INVALIDATION","DIST"})
    public void setCacheMode(String cacheMode) {
-      testImmutability("cacheMode");
       if (cacheMode == null) throw new ConfigurationException("Cache mode cannot be null", "CacheMode");
-      this.cacheMode = CacheMode.valueOf(uc(cacheMode));
-      if (this.cacheMode == null) {
+      clustering.setMode(CacheMode.valueOf(uc(cacheMode)));
+      if (clustering.mode == null) {
          log.warn("Unknown cache mode '" + cacheMode + "', using defaults.");
-         this.cacheMode = CacheMode.LOCAL;
+         clustering.setMode(CacheMode.LOCAL);
       }
    }
 
    public String getCacheModeString() {
-      return cacheMode == null ? null : cacheMode.toString();
+      return clustering.mode == null ? null : clustering.mode.toString();
    }
 
    public void setCacheModeString(String cacheMode) {
@@ -416,67 +425,61 @@
    }
 
    public long getEvictionWakeUpInterval() {
-      return evictionWakeUpInterval;
+      return eviction.wakeUpInterval;
    }
 
    @ConfigurationAttribute(name = "wakeUpInterval", 
             containingElement = "eviction")
    public void setEvictionWakeUpInterval(long evictionWakeUpInterval) {
-      testImmutability("evictionWakeUpInterval");
-      this.evictionWakeUpInterval = evictionWakeUpInterval;
+      this.eviction.setWakeUpInterval(evictionWakeUpInterval);
    }
 
    public EvictionStrategy getEvictionStrategy() {
-      return evictionStrategy;
+      return eviction.strategy;
    }
 
    public void setEvictionStrategy(EvictionStrategy evictionStrategy) {
-      testImmutability("evictionStrategy");
-      this.evictionStrategy = evictionStrategy;
+      this.eviction.setStrategy(evictionStrategy);
    }
    
    @ConfigurationAttribute(name = "strategy", 
             containingElement = "eviction",allowedValues={"NONE", "FIFO", "LRU"})
    public void setEvictionStrategy(String eStrategy){
-      testImmutability("evictionStrategy");
-      this.evictionStrategy = EvictionStrategy.valueOf(uc(eStrategy));
-      if (this.evictionStrategy == null) {
+      this.eviction.strategy = EvictionStrategy.valueOf(uc(eStrategy));
+      if (this.eviction.strategy == null) {
          log.warn("Unknown evictionStrategy  '" + eStrategy + "', using defaults.");
-         this.evictionStrategy = EvictionStrategy.NONE;
+         this.eviction.setStrategy(EvictionStrategy.NONE);
       }
    }
 
    public int getEvictionMaxEntries() {
-      return evictionMaxEntries;
+      return eviction.maxEntries;
    }
 
    @ConfigurationAttribute(name = "maxEntries", 
             containingElement = "eviction")
    public void setEvictionMaxEntries(int evictionMaxEntries) {
-      testImmutability("evictionMaxEntries");
-      this.evictionMaxEntries = evictionMaxEntries;
+      this.eviction.setMaxEntries(evictionMaxEntries);
    }
 
    public long getExpirationLifespan() {
-      return expirationLifespan;
+      return expiration.lifespan;
    }
 
    @ConfigurationAttribute(name = "lifespan", 
             containingElement = "expiration")
    public void setExpirationLifespan(long expirationLifespan) {
-      testImmutability("expirationLifespan");
-      this.expirationLifespan = expirationLifespan;
+      this.expiration.setLifespan(expirationLifespan);
    }
 
    public long getExpirationMaxIdle() {
-      return expirationMaxIdle;
+      return expiration.maxIdle;
    }
 
    @ConfigurationAttribute(name = "maxIdle", 
             containingElement = "expiration")
    public void setExpirationMaxIdle(long expirationMaxIdle) {
-      testImmutability("expirationMaxIdle");
-      this.expirationMaxIdle = expirationMaxIdle;
+      this.expiration.setMaxIdle(expirationMaxIdle);
    }
 
    @ConfigurationAttribute(name = "transactionManagerLookupClass", 
@@ -484,53 +487,45 @@
             description = "",
              defaultValue="org.infinispan.transaction.lookup.GenericTransactionManagerLookup")
    public void setTransactionManagerLookupClass(String transactionManagerLookupClass) {
-      testImmutability("transactionManagerLookupClass");
-      this.transactionManagerLookupClass = transactionManagerLookupClass;
+      this.transaction.setTransactionManagerLookupClass(transactionManagerLookupClass);
    }
 
    public void setCacheLoaderManagerConfig(CacheLoaderManagerConfig cacheLoaderManagerConfig) {
-      testImmutability("cacheLoaderManagerConfig");
-      this.cacheLoaderManagerConfig = cacheLoaderManagerConfig;
+      this.loaders = cacheLoaderManagerConfig;
    }
 
    @ConfigurationAttribute(name = "syncCommitPhase", 
             containingElement = "transaction")
    public void setSyncCommitPhase(boolean syncCommitPhase) {
-      testImmutability("syncCommitPhase");
-      this.syncCommitPhase = syncCommitPhase;
+      this.transaction.setSyncCommitPhase(syncCommitPhase);
    }
 
    @ConfigurationAttribute(name = "syncRollbackPhase", 
             containingElement = "transaction")
    public void setSyncRollbackPhase(boolean syncRollbackPhase) {
-      testImmutability("syncRollbackPhase");
-      this.syncRollbackPhase = syncRollbackPhase;
+      this.transaction.setSyncRollbackPhase(syncRollbackPhase);
    }
    
    @ConfigurationAttribute(name = "useEagerLocking", 
             containingElement = "transaction")           
    public void setUseEagerLocking(boolean useEagerLocking) {
-      testImmutability("useEagerLocking");
-      this.useEagerLocking = useEagerLocking;
+      this.transaction.setUseEagerLocking(useEagerLocking);
    }
 
    @ConfigurationAttribute(name = "useReplQueue", 
             containingElement = "async")
    public void setUseReplQueue(boolean useReplQueue) {
-      testImmutability("useReplQueue");
-      this.useReplQueue = useReplQueue;
+      this.clustering.async.setUseReplQueue(useReplQueue);
    }
 
    public void setIsolationLevel(IsolationLevel isolationLevel) {
-      testImmutability("isolationLevel");
-      this.isolationLevel = isolationLevel;
+      locking.setIsolationLevel(isolationLevel);
    }
 
    @ConfigurationAttribute(name = "timeout", 
             containingElement = "stateRetrieval")
    public void setStateRetrievalTimeout(long stateRetrievalTimeout) {
-      testImmutability("stateRetrievalTimeout");
-      this.stateRetrievalTimeout = stateRetrievalTimeout;
+      this.clustering.stateRetrieval.setTimeout(stateRetrievalTimeout);
    }
 
    public void setStateRetrievalTimeout(long stateRetrievalTimeout, TimeUnit timeUnit) {
@@ -541,70 +536,61 @@
             containingElement = "locking",
             allowedValues={"NONE","SERIALIZABLE","REPEATABLE_READ","READ_COMMITTED","READ_UNCOMMITTED"})    
    public void setIsolationLevel(String isolationLevel) {
-      testImmutability("isolationLevel");
       if (isolationLevel == null) throw new ConfigurationException("Isolation level cannot be null", "IsolationLevel");
-      this.isolationLevel = IsolationLevel.valueOf(uc(isolationLevel));
-      if (this.isolationLevel == null) {
+      locking.setIsolationLevel(IsolationLevel.valueOf(uc(isolationLevel)));
+      if (locking.isolationLevel == null) {
          log.warn("Unknown isolation level '" + isolationLevel + "', using defaults.");
-         this.isolationLevel = IsolationLevel.REPEATABLE_READ;
+         locking.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
       }
    }
 
    @ConfigurationAttribute(name = "enabled", 
             containingElement = "lazyDeserialization") 
    public void setUseLazyDeserialization(boolean useLazyDeserialization) {
-      testImmutability("useLazyDeserialization");
-      this.useLazyDeserialization = useLazyDeserialization;
+      lazyDeserialization.setEnabled(useLazyDeserialization);
    }
 
    @ConfigurationAttribute(name = "enabled", 
             containingElement = "l1")   
    public void setL1CacheEnabled(boolean l1CacheEnabled) {
-      testImmutability("l1CacheEnabled");
-      this.l1CacheEnabled = l1CacheEnabled;
+      this.clustering.l1.setEnabled(l1CacheEnabled);
    }
 
 
    @ConfigurationAttribute(name = "lifespan", 
             containingElement = "l1")   
    public void setL1Lifespan(long l1Lifespan) {
-      testImmutability("l1Lifespan");
-      this.l1Lifespan = l1Lifespan;
+      this.clustering.l1.setLifespan(l1Lifespan);
    }
 
    @ConfigurationAttribute(name = "onRehash", 
             containingElement = "l1")   
    public void setL1OnRehash(boolean l1OnRehash) {
-      testImmutability("l1OnRehash");
-      this.l1OnRehash = l1OnRehash;
+      this.clustering.l1.setOnRehash(l1OnRehash);
    }
 
    @ConfigurationAttribute(name = "consistentHashClass", 
             containingElement = "hash")   
    public void setConsistentHashClass(String consistentHashClass) {
-      testImmutability("consistentHashClass");
-      this.consistentHashClass = consistentHashClass;
+      this.clustering.hash.setConsistentHashClass(consistentHashClass);
    }
    
    @ConfigurationAttribute(name = "numOwners", 
             containingElement = "hash")    
    public void setNumOwners(int numOwners) {
-      testImmutability("numOwners");
-      this.numOwners = numOwners;
+      this.clustering.hash.setNumOwners(numOwners);
    }
 
    @ConfigurationAttribute(name = "rehashWait", 
             containingElement = "hash")    
    public void setRehashWaitTime(long rehashWaitTime) {
-      testImmutability("rehashWaitTime");
-      this.rehashWaitTime = rehashWaitTime;
+      this.clustering.hash.setRehashWait(rehashWaitTime);
    }
 
    @ConfigurationAttribute(name = "asyncMarshalling", 
             containingElement = "async")
    public void setUseAsyncMarshalling(boolean useAsyncMarshalling) {
-      testImmutability("useAsyncMarshalling");
-      this.useAsyncMarshalling = useAsyncMarshalling;
+      this.clustering.async.setAsyncMarshalling(useAsyncMarshalling);
    }
 
    // ------------------------------------------------------------------------------------------------------------
@@ -612,23 +598,23 @@
    // ------------------------------------------------------------------------------------------------------------
 
    public boolean isUseAsyncMarshalling() {
-      return useAsyncMarshalling;
+      return clustering.async.asyncMarshalling;
    }
 
    public boolean isUseReplQueue() {
-      return useReplQueue;
+      return clustering.async.useReplQueue;
    }
 
    public int getReplQueueMaxElements() {
-      return replQueueMaxElements;
+      return clustering.async.replQueueMaxElements;
    }
 
    public long getReplQueueInterval() {
-      return replQueueInterval;
+      return clustering.async.replQueueInterval;
    }
 
    public boolean isExposeJmxStatistics() {
-      return exposeJmxStatistics;
+      return jmxStatistics.enabled;
    }
 
    /**
@@ -636,79 +622,79 @@
     * @since 4.0
     */
    public boolean isInvocationBatchingEnabled() {
-      return invocationBatchingEnabled;
+      return invocationBatching.enabled ;
    }
 
    public boolean isFetchInMemoryState() {
-      return fetchInMemoryState;
+      return clustering.stateRetrieval.fetchInMemoryState;
    }
 
    public long getLockAcquisitionTimeout() {
-      return lockAcquisitionTimeout;
+      return locking.lockAcquisitionTimeout;
    }
 
    public long getSyncReplTimeout() {
-      return syncReplTimeout;
+      return clustering.sync.replTimeout;
    }
 
    public CacheMode getCacheMode() {
-      return cacheMode;
+      return clustering.mode;
    }
 
    public IsolationLevel getIsolationLevel() {
-      return isolationLevel;
+      return locking.isolationLevel;
    }
 
    public String getTransactionManagerLookupClass() {
-      return transactionManagerLookupClass;
+      return transaction.transactionManagerLookupClass;
    }
 
    public CacheLoaderManagerConfig getCacheLoaderManagerConfig() {
-      return cacheLoaderManagerConfig;
+      return loaders;
    }
 
    public boolean isSyncCommitPhase() {
-      return syncCommitPhase;
+      return transaction.syncCommitPhase;
    }
 
    public boolean isSyncRollbackPhase() {
-      return syncRollbackPhase;
+      return transaction.syncRollbackPhase;
    }
    
    public boolean isUseEagerLocking() {
-      return useEagerLocking;
+      return transaction.useEagerLocking;
    }
 
    public long getStateRetrievalTimeout() {
-      return stateRetrievalTimeout;
+      return clustering.stateRetrieval.timeout;
    }
 
    public boolean isUseLazyDeserialization() {
-      return useLazyDeserialization;
+      return lazyDeserialization.enabled;
    }
 
    public boolean isL1CacheEnabled() {
-      return l1CacheEnabled;
+      return clustering.l1.enabled;
    }
 
    public long getL1Lifespan() {
-      return l1Lifespan;
+      return clustering.l1.lifespan;
    }
 
    public boolean isL1OnRehash() {
-      return l1OnRehash;
+      return clustering.l1.onRehash;
    }
 
    public String getConsistentHashClass() {
-      return consistentHashClass;
+      return clustering.hash.consistentHashClass;
    }
 
    public int getNumOwners() {
-      return numOwners;
+      return clustering.hash.numOwners;
    }
 
    public long getRehashWaitTime() {
-      return rehashWaitTime;
+      return clustering.hash.rehashWait;
    }
 
    // ------------------------------------------------------------------------------------------------------------
@@ -726,46 +712,46 @@
 
       Configuration that = (Configuration) o;
 
-      if (concurrencyLevel != that.concurrencyLevel) return false;
-      if (evictionMaxEntries != that.evictionMaxEntries) return false;
-      if (evictionWakeUpInterval != that.evictionWakeUpInterval) return false;
-      if (expirationLifespan != that.expirationLifespan) return false;
-      if (expirationMaxIdle != that.expirationMaxIdle) return false;
-      if (exposeJmxStatistics != that.exposeJmxStatistics) return false;
-      if (fetchInMemoryState != that.fetchInMemoryState) return false;
-      if (invocationBatchingEnabled != that.invocationBatchingEnabled) return false;
-      if (l1CacheEnabled != that.l1CacheEnabled) return false;
-      if (l1Lifespan != that.l1Lifespan) return false;
-      if (rehashWaitTime != that.rehashWaitTime) return false;
-      if (l1OnRehash != that.l1OnRehash) return false;
-      if (lockAcquisitionTimeout != that.lockAcquisitionTimeout) return false;
-      if (numOwners != that.numOwners) return false;
-      if (replQueueInterval != that.replQueueInterval) return false;
-      if (replQueueMaxElements != that.replQueueMaxElements) return false;
-      if (stateRetrievalTimeout != that.stateRetrievalTimeout) return false;
-      if (syncCommitPhase != that.syncCommitPhase) return false;
-      if (syncReplTimeout != that.syncReplTimeout) return false;
-      if (rehashRpcTimeout != that.rehashRpcTimeout) return false;
-      if (syncRollbackPhase != that.syncRollbackPhase) return false;
-      if (useEagerLocking != that.useEagerLocking) return false;
-      if (useLazyDeserialization != that.useLazyDeserialization) return false;
-      if (useLockStriping != that.useLockStriping) return false;
-      if (useReplQueue != that.useReplQueue) return false;
-      if (writeSkewCheck != that.writeSkewCheck) return false;
-      if (cacheLoaderManagerConfig != null ? !cacheLoaderManagerConfig.equals(that.cacheLoaderManagerConfig) : that.cacheLoaderManagerConfig != null)
+      if (locking.concurrencyLevel != that.locking.concurrencyLevel) return false;
+      if (eviction.maxEntries != that.eviction.maxEntries) return false;
+      if (eviction.wakeUpInterval != that.eviction.wakeUpInterval) return false;
+      if (expiration.lifespan != that.expiration.lifespan) return false;
+      if (expiration.maxIdle != that.expiration.maxIdle) return false;
+      if (jmxStatistics.enabled != that.jmxStatistics.enabled) return false;
+      if (clustering.stateRetrieval.fetchInMemoryState != that.clustering.stateRetrieval.fetchInMemoryState) return false;
+      if (invocationBatching.enabled  != that.invocationBatching.enabled ) return false;
+      if (clustering.l1.enabled != that.clustering.l1.enabled) return false;
+      if (clustering.l1.lifespan != that.clustering.l1.lifespan) return false;
+      if (clustering.hash.rehashWait != that.clustering.hash.rehashWait) return false;
+      if (clustering.l1.onRehash != that.clustering.l1.onRehash) return false;
+      if (locking.lockAcquisitionTimeout != that.locking.lockAcquisitionTimeout) return false;
+      if (clustering.hash.numOwners != that.clustering.hash.numOwners) return false;
+      if (clustering.async.replQueueInterval != that.clustering.async.replQueueInterval) return false;
+      if (clustering.async.replQueueMaxElements != that.clustering.async.replQueueMaxElements) return false;
+      if (clustering.stateRetrieval.timeout != that.clustering.stateRetrieval.timeout) return false;
+      if (transaction.syncCommitPhase != that.transaction.syncCommitPhase) return false;
+      if (clustering.sync.replTimeout != that.clustering.sync.replTimeout) return false;
+      if (clustering.hash.rehashRpcTimeout != that.clustering.hash.rehashRpcTimeout) return false;
+      if (transaction.syncRollbackPhase != that.transaction.syncRollbackPhase) return false;
+      if (transaction.useEagerLocking != that.transaction.useEagerLocking) return false;
+      if (lazyDeserialization.enabled != that.lazyDeserialization.enabled) return false;
+      if (locking.useLockStriping != that.locking.useLockStriping) return false;
+      if (clustering.async.useReplQueue != that.clustering.async.useReplQueue) return false;
+      if (locking.writeSkewCheck != that.locking.writeSkewCheck) return false;
+      if (loaders != null ? !loaders.equals(that.loaders) : that.loaders != null)
          return false;
-      if (cacheMode != that.cacheMode) return false;
-      if (consistentHashClass != null ? !consistentHashClass.equals(that.consistentHashClass) : that.consistentHashClass != null)
+      if (clustering.mode != that.clustering.mode) return false;
+      if (clustering.hash.consistentHashClass != null ? !clustering.hash.consistentHashClass.equals(that.clustering.hash.consistentHashClass) : that.clustering.hash.consistentHashClass != null)
          return false;
-      if (customInterceptors != null ? !customInterceptors.equals(that.customInterceptors) : that.customInterceptors != null)
+      if (customInterceptors.customInterceptors != null ? !customInterceptors.customInterceptors.equals(that.customInterceptors.customInterceptors) : that.customInterceptors.customInterceptors != null)
          return false;
-      if (evictionStrategy != that.evictionStrategy) return false;
+      if (eviction.strategy != that.eviction.strategy) return false;
       if (globalConfiguration != null ? !globalConfiguration.equals(that.globalConfiguration) : that.globalConfiguration != null)
          return false;
-      if (isolationLevel != that.isolationLevel) return false;
-      if (transactionManagerLookupClass != null ? !transactionManagerLookupClass.equals(that.transactionManagerLookupClass) : that.transactionManagerLookupClass != null)
+      if (locking.isolationLevel != that.locking.isolationLevel) return false;
+      if (transaction.transactionManagerLookupClass != null ? !transaction.transactionManagerLookupClass.equals(that.transaction.transactionManagerLookupClass) : that.transaction.transactionManagerLookupClass != null)
          return false;
-      if (useAsyncMarshalling != that.useAsyncMarshalling) return false;
+      if (clustering.async.asyncMarshalling != that.clustering.async.asyncMarshalling) return false;
 
       return true;
    }
@@ -773,55 +759,68 @@
    @Override
    public int hashCode() {
       int result = globalConfiguration != null ? globalConfiguration.hashCode() : 0;
-      result = 31 * result + (useLockStriping ? 1 : 0);
-      result = 31 * result + (useReplQueue ? 1 : 0);
-      result = 31 * result + replQueueMaxElements;
-      result = 31 * result + (int) (replQueueInterval ^ (replQueueInterval >>> 32));
-      result = 31 * result + (exposeJmxStatistics ? 1 : 0);
-      result = 31 * result + (fetchInMemoryState ? 1 : 0);
-      result = 31 * result + (int) (lockAcquisitionTimeout ^ (lockAcquisitionTimeout >>> 32));
-      result = 31 * result + (int) (syncReplTimeout ^ (syncReplTimeout >>> 32));
-      result = 31 * result + (cacheMode != null ? cacheMode.hashCode() : 0);
-      result = 31 * result + (int) (stateRetrievalTimeout ^ (stateRetrievalTimeout >>> 32));
-      result = 31 * result + (isolationLevel != null ? isolationLevel.hashCode() : 0);
-      result = 31 * result + (transactionManagerLookupClass != null ? transactionManagerLookupClass.hashCode() : 0);
-      result = 31 * result + (cacheLoaderManagerConfig != null ? cacheLoaderManagerConfig.hashCode() : 0);
-      result = 31 * result + (syncCommitPhase ? 1 : 0);
-      result = 31 * result + (syncRollbackPhase ? 1 : 0);
-      result = 31 * result + (useEagerLocking ? 1 : 0);
-      result = 31 * result + (useLazyDeserialization ? 1 : 0);
-      result = 31 * result + (customInterceptors != null ? customInterceptors.hashCode() : 0);
-      result = 31 * result + (writeSkewCheck ? 1 : 0);
-      result = 31 * result + concurrencyLevel;
-      result = 31 * result + (invocationBatchingEnabled ? 1 : 0);
-      result = 31 * result + (int) (evictionWakeUpInterval ^ (evictionWakeUpInterval >>> 32));
-      result = 31 * result + (evictionStrategy != null ? evictionStrategy.hashCode() : 0);
-      result = 31 * result + evictionMaxEntries;
-      result = 31 * result + (int) (expirationLifespan ^ (expirationLifespan >>> 32));
-      result = 31 * result + (int) (expirationMaxIdle ^ (expirationMaxIdle >>> 32));
-      result = 31 * result + (l1CacheEnabled ? 1 : 0);
-      result = 31 * result + (int) (l1Lifespan ^ (l1Lifespan >>> 32));
-      result = 31 * result + (int) (rehashWaitTime ^ (rehashWaitTime >>> 32));
-      result = 31 * result + (int) (rehashRpcTimeout ^ (rehashRpcTimeout >>> 32));
-      result = 31 * result + (l1OnRehash ? 1 : 0);
-      result = 31 * result + (consistentHashClass != null ? consistentHashClass.hashCode() : 0);
-      result = 31 * result + numOwners;
-      result = 31 * result + (useAsyncMarshalling ? 1 : 0);
+      result = 31 * result + (locking.useLockStriping ? 1 : 0);
+      result = 31 * result + (clustering.async.useReplQueue ? 1 : 0);
+      result = 31 * result + clustering.async.replQueueMaxElements;
+      result = 31 * result + (int) (clustering.async.replQueueInterval ^ (clustering.async.replQueueInterval >>> 32));
+      result = 31 * result + (jmxStatistics.enabled ? 1 : 0);
+      result = 31 * result + (clustering.stateRetrieval.fetchInMemoryState ? 1 : 0);
+      result = 31 * result + (int) (locking.lockAcquisitionTimeout ^ (locking.lockAcquisitionTimeout >>> 32));
+      result = 31 * result + (int) (clustering.sync.replTimeout ^ (clustering.sync.replTimeout >>> 32));
+      result = 31 * result + (clustering.mode != null ? clustering.mode.hashCode() : 0);
+      result = 31 * result + (int) (clustering.stateRetrieval.timeout ^ (clustering.stateRetrieval.timeout >>> 32));
+      result = 31 * result + (locking.isolationLevel != null ? locking.isolationLevel.hashCode() : 0);
+      result = 31 * result + (transaction.transactionManagerLookupClass != null ? transaction.transactionManagerLookupClass.hashCode() : 0);
+      result = 31 * result + (loaders != null ? loaders.hashCode() : 0);
+      result = 31 * result + (transaction.syncCommitPhase ? 1 : 0);
+      result = 31 * result + (transaction.syncRollbackPhase ? 1 : 0);
+      result = 31 * result + (transaction.useEagerLocking ? 1 : 0);
+      result = 31 * result + (lazyDeserialization.enabled ? 1 : 0);
+      result = 31 * result + (customInterceptors.customInterceptors != null ? customInterceptors.customInterceptors.hashCode() : 0);
+      result = 31 * result + (locking.writeSkewCheck ? 1 : 0);
+      result = 31 * result + locking.concurrencyLevel;
+      result = 31 * result + (invocationBatching.enabled  ? 1 : 0);
+      result = 31 * result + (int) (eviction.wakeUpInterval ^ (eviction.wakeUpInterval >>> 32));
+      result = 31 * result + (eviction.strategy != null ? eviction.strategy.hashCode() : 0);
+      result = 31 * result + eviction.maxEntries;
+      result = 31 * result + (int) (expiration.lifespan ^ (expiration.lifespan >>> 32));
+      result = 31 * result + (int) (expiration.maxIdle ^ (expiration.maxIdle >>> 32));
+      result = 31 * result + (clustering.l1.enabled ? 1 : 0);
+      result = 31 * result + (int) (clustering.l1.lifespan ^ (clustering.l1.lifespan >>> 32));
+      result = 31 * result + (int) (clustering.hash.rehashWait ^ (clustering.hash.rehashWait >>> 32));
+      result = 31 * result + (int) (clustering.hash.rehashRpcTimeout ^ (clustering.hash.rehashRpcTimeout >>> 32));
+      result = 31 * result + (clustering.l1.onRehash ? 1 : 0);
+      result = 31 * result + (clustering.hash.consistentHashClass != null ? clustering.hash.consistentHashClass.hashCode() : 0);
+      result = 31 * result + clustering.hash.numOwners;
+      result = 31 * result + (clustering.async.asyncMarshalling ? 1 : 0);
       return result;
    }
 
    @Override
    public Configuration clone() {
+      
+      Configuration obj = null;
       try {
-         Configuration c = (Configuration) super.clone();
-         if (cacheLoaderManagerConfig != null) {
-            c.setCacheLoaderManagerConfig(cacheLoaderManagerConfig.clone());
-         }
-         return c;
+          // Write the object out to a byte array
+          ByteArrayOutputStream bos = new ByteArrayOutputStream();
+          ObjectOutputStream out = new ObjectOutputStream(bos);
+          out.writeObject(this);
+          out.flush();
+          out.close();
+
+          // Make an input stream from the byte array and read
+          // a copy of the object back in.
+          ObjectInputStream in = new ObjectInputStream(
+              new ByteArrayInputStream(bos.toByteArray()));
+          obj= (Configuration) in.readObject();
       }
-      catch (CloneNotSupportedException e) {
-         throw new RuntimeException(e);
+      catch(IOException e) {
+          e.printStackTrace();
       }
+      catch(ClassNotFoundException cnfe) {
+          cnfe.printStackTrace();
+      }
+      return obj;
    }
 
    public boolean isUsingCacheLoaders() {
@@ -836,7 +835,7 @@
     */
    @SuppressWarnings("unchecked")
    public List<CustomInterceptorConfig> getCustomInterceptors() {
-      return customInterceptors == null ? Collections.EMPTY_LIST : customInterceptors;
+      return customInterceptors.customInterceptors == null ? Collections.EMPTY_LIST : customInterceptors.customInterceptors;
    }
 
    /**
@@ -844,23 +843,411 @@
     */
    public void setCustomInterceptors(List<CustomInterceptorConfig> customInterceptors) {
       testImmutability("customInterceptors");
-      this.customInterceptors = customInterceptors;
-   }
+      this.customInterceptors.customInterceptors = customInterceptors;
+   }  
 
-   public void applyOverrides(Configuration overrides) {
-      // loop through all overridden elements in the incoming configuration and apply
-      for (String overriddenField : overrides.overriddenConfigurationElements) {
-         ReflectionUtil.setValue(this, overriddenField, ReflectionUtil.getValue(overrides, overriddenField));
-      }
-   }
-
    public void assertValid() throws ConfigurationException {
       // certain combinations are illegal, such as state transfer + DIST
-      if (cacheMode.isDistributed() && fetchInMemoryState)
+      if (clustering.mode.isDistributed() && clustering.stateRetrieval.fetchInMemoryState)
          throw new ConfigurationException("Cache cannot use DISTRIBUTION mode and have fetchInMemoryState set to true");
    }
 
    public boolean isOnePhaseCommit() {
       return !getCacheMode().isSynchronous();
    }
-}
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class TransactionType extends AbstractNamedCacheConfigurationBean{
+           
+      /** The serialVersionUID */
+      private static final long serialVersionUID = -3867090839830874603L;
+
+      private String transactionManagerLookupClass;
+      
+      @Dynamic
+      private Boolean syncCommitPhase = false;
+      
+      @Dynamic
+      private Boolean syncRollbackPhase = false;
+      
+      @Dynamic
+      private Boolean useEagerLocking = false;
+      
+      public TransactionType(String transactionManagerLookupClass) {
+         this.transactionManagerLookupClass = transactionManagerLookupClass;
+      }
+      
+      public TransactionType() {
+         this.transactionManagerLookupClass = GenericTransactionManagerLookup.class.getName();
+      }
+
+      @XmlAttribute
+      public void setTransactionManagerLookupClass(String transactionManagerLookupClass) {
+         testImmutability("transactionManagerLookupClass");
+         this.transactionManagerLookupClass = transactionManagerLookupClass;         
+      }
+
+      @XmlAttribute
+      public void setSyncCommitPhase(Boolean syncCommitPhase) {
+         testImmutability("syncCommitPhase");
+         this.syncCommitPhase = syncCommitPhase;
+      }
+
+      @XmlAttribute
+      public void setSyncRollbackPhase(Boolean syncRollbackPhase) {
+         testImmutability("syncRollbackPhase");
+         this.syncRollbackPhase = syncRollbackPhase;
+      }
+
+      @XmlAttribute
+      public void setUseEagerLocking(Boolean useEagerLocking) {
+         testImmutability("useEagerLocking");
+         this.useEagerLocking = useEagerLocking;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class LockingType  extends AbstractNamedCacheConfigurationBean{      
+      
+
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 8142143187082119506L;
+
+      @Dynamic
+      private Long lockAcquisitionTimeout = 10000L;
+      
+      private IsolationLevel isolationLevel = IsolationLevel.READ_COMMITTED;
+      
+      private Boolean writeSkewCheck = false;
+    
+      private Boolean useLockStriping = true;
+      
+      private Integer concurrencyLevel = 500;   
+      
+      @XmlAttribute
+      public void setLockAcquisitionTimeout(Long lockAcquisitionTimeout) {
+         testImmutability("lockAcquisitionTimeout");
+         this.lockAcquisitionTimeout = lockAcquisitionTimeout;
+      }
+
+      @XmlAttribute
+      public void setIsolationLevel(IsolationLevel isolationLevel) {
+         testImmutability("isolationLevel");
+         this.isolationLevel = isolationLevel;
+      }
+
+      @XmlAttribute
+      public void setWriteSkewCheck(Boolean writeSkewCheck) {
+         testImmutability("writeSkewCheck");
+         this.writeSkewCheck = writeSkewCheck;
+      }
+
+      @XmlAttribute
+      public void setUseLockStriping(Boolean useLockStriping) {
+         testImmutability("useLockStriping");
+         this.useLockStriping = useLockStriping;
+      }
+
+      @XmlAttribute
+      public void setConcurrencyLevel(Integer concurrencyLevel) {
+         testImmutability("concurrencyLevel");
+         this.concurrencyLevel = concurrencyLevel;
+      }
+   } 
+   
+   @XmlAccessorType(XmlAccessType.FIELD)
+   @XmlType(propOrder={})
+   private static class ClusteringType extends AbstractNamedCacheConfigurationBean {
+      
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 4048135465543498430L;
+
+      @XmlTransient
+      private CacheMode mode = CacheMode.LOCAL;
+      
+      @XmlElement
+      private SyncType sync = new SyncType();
+      
+      @XmlElement
+      private StateRetrievalType stateRetrieval = new StateRetrievalType();
+      
+      @XmlElement
+      private L1Type l1 = new L1Type();
+      
+      @XmlElement
+      private AsyncType async = new AsyncType();
+      
+      @XmlElement
+      private HashType hash = new HashType();
+
+      @XmlAttribute
+      public void setMode(CacheMode mode) {
+         testImmutability("mode");
+         this.mode = mode;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class AsyncType extends AbstractNamedCacheConfigurationBean {
+
+      /** The serialVersionUID */
+      private static final long serialVersionUID = -7726319188826197399L;
+
+      private Boolean useReplQueue=false;
+      
+      private Integer replQueueMaxElements=1000;
+      
+      private Long replQueueInterval=5000L;
+      
+      private Boolean asyncMarshalling=true;
+      
+      @XmlAttribute
+      public void setUseReplQueue(Boolean useReplQueue) {
+         testImmutability("useReplQueue");
+         this.useReplQueue = useReplQueue;
+      }
+
+      @XmlAttribute
+      public void setReplQueueMaxElements(Integer replQueueMaxElements) {
+         testImmutability("replQueueMaxElements");
+         this.replQueueMaxElements = replQueueMaxElements;
+      }
+
+      @XmlAttribute
+      public void setReplQueueInterval(Long replQueueInterval) {
+         testImmutability("replQueueInterval");
+         this.replQueueInterval = replQueueInterval;
+      }
+
+      @XmlAttribute
+      public void setAsyncMarshalling(Boolean asyncMarshalling) {
+         testImmutability("asyncMarshalling");
+         this.asyncMarshalling = asyncMarshalling;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class ExpirationType extends AbstractNamedCacheConfigurationBean{
+
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 5757161438110848530L;
+
+      private Long lifespan=-1L;
+      
+      private Long maxIdle=-1L;
+      
+      @XmlAttribute
+      public void setLifespan(Long lifespan) {
+         testImmutability("lifespan");
+         this.lifespan = lifespan;
+      }
+
+      @XmlAttribute
+      public void setMaxIdle(Long maxIdle) {
+         testImmutability("maxIdle");
+         this.maxIdle = maxIdle;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class EvictionType extends AbstractNamedCacheConfigurationBean {
+
+      /** The serialVersionUID */
+      private static final long serialVersionUID = -1248563712058858791L;
+
+      private Long wakeUpInterval=5000L;
+    
+      private EvictionStrategy strategy=EvictionStrategy.NONE;
+      
+      private Integer maxEntries=-1;      
+      
+      @XmlAttribute
+      public void setWakeUpInterval(Long wakeUpInterval) {
+         testImmutability("wakeUpInterval");
+         this.wakeUpInterval = wakeUpInterval;
+      }
+
+      @XmlAttribute
+      public void setStrategy(EvictionStrategy strategy) {
+         testImmutability("strategy");
+         this.strategy = strategy;
+      }
+
+      @XmlAttribute
+      public void setMaxEntries(Integer maxEntries) {
+         testImmutability("maxEntries");
+         this.maxEntries = maxEntries;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class StateRetrievalType extends AbstractNamedCacheConfigurationBean {
+
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 3709234918426217096L;
+
+      @Dynamic
+      private Boolean fetchInMemoryState = false;
+      
+      @Dynamic      
+      private Long timeout=10000L;     
+      
+      @XmlAttribute
+      public void setFetchInMemoryState(Boolean fetchInMemoryState) {
+         testImmutability("fetchInMemoryState");
+         this.fetchInMemoryState = fetchInMemoryState;
+      }
+
+      @XmlAttribute
+      public void setTimeout(Long timeout) {
+         testImmutability("timeout");
+         this.timeout = timeout;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class SyncType  extends AbstractNamedCacheConfigurationBean {
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 8419216253674289524L;
+      
+      @Dynamic
+      private Long replTimeout=15000L;
+      
+      @XmlAttribute
+      public void setReplTimeout(Long replTimeout) {
+         testImmutability("replTimeout");
+         this.replTimeout = replTimeout;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class HashType extends AbstractNamedCacheConfigurationBean {
+
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 752218766840948822L;
+
+      private String consistentHashClass=DefaultConsistentHash.class.getName();
+      
+      private Integer numOwners=2;
+      
+      private Long rehashWait=60000L;
+      
+      private Long rehashRpcTimeout=60 * 1000 * 10L;     
+      
+      @XmlAttribute(name="class")
+      public void setConsistentHashClass(String consistentHashClass) {
+         testImmutability("class");
+         this.consistentHashClass = consistentHashClass;
+      }
+
+      @XmlAttribute
+      public void setNumOwners(Integer numOwners) {
+         testImmutability("numOwners");
+         this.numOwners = numOwners;
+      }
+
+      @XmlAttribute
+      public void setRehashWait(Long rehashWaitTime) {
+         testImmutability("rehashWait");
+         this.rehashWait = rehashWaitTime;
+      }
+
+      @XmlAttribute
+      public void setRehashRpcTimeout(Long rehashRpcTimeout) {
+         testImmutability("rehashRpcTimeout");
+         this.rehashRpcTimeout = rehashRpcTimeout;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class L1Type extends AbstractNamedCacheConfigurationBean {
+      
+      /** The serialVersionUID */
+      private static final long serialVersionUID = -4703587764861110638L;
+
+      private Boolean enabled=true;
+
+      private Long lifespan=600000L;
+      
+      private Boolean onRehash=true;
+      
+      @XmlAttribute
+      public void setEnabled(Boolean enabled) {
+         testImmutability("enabled");
+         this.enabled = enabled;
+      }
+      
+      @XmlAttribute
+      public void setLifespan(Long lifespan) {
+         testImmutability("lifespan");
+         this.lifespan = lifespan;
+      }
+
+      @XmlAttribute
+      public void setOnRehash(Boolean onRehash) {
+         testImmutability("onRehash");
+         this.onRehash = onRehash;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class BooleanAttributeType  extends AbstractNamedCacheConfigurationBean {
+     
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 2296863404153834686L;
+      Boolean enabled = false;
+      
+      @XmlAttribute
+      public void setEnabled(Boolean enabled) {
+         testImmutability("enabled");
+         this.enabled = enabled;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class DeadlockDetectionType  extends AbstractNamedCacheConfigurationBean{
+      
+      /** The serialVersionUID */
+      private static final long serialVersionUID = -7178286048602531152L;
+
+      private Boolean enabled=false;
+      
+      private Long spinDuration=100L;
+      
+      @XmlAttribute
+      public void setEnabled(Boolean enabled) {
+         testImmutability("enabled");
+         this.enabled = enabled;
+      }
+
+      @XmlAttribute
+      public void setSpinDuration(Long spinDuration) {
+         testImmutability("spinDuration");
+         this.spinDuration = spinDuration;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class UnsafeType  extends AbstractNamedCacheConfigurationBean{
+      
+      /** The serialVersionUID */
+      private static final long serialVersionUID = -9200921443651234163L;
+      private Boolean unreliableReturnValues=false;
+      
+      @XmlAttribute
+      public void setUnreliableReturnValues(Boolean unreliableReturnValues) {
+         testImmutability("unreliableReturnValues");
+         this.unreliableReturnValues = unreliableReturnValues;
+      }
+   }
+   
+   @XmlAccessorType(XmlAccessType.FIELD)
+   private static class CustomInterceptorsType extends AbstractNamedCacheConfigurationBean {
+      
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 7187545782011884661L;
+      
+      @XmlElement(name="interceptor")
+      private List<CustomInterceptorConfig> customInterceptors= new ArrayList<CustomInterceptorConfig>();
+   }
+}
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/config/CustomInterceptorConfig.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/CustomInterceptorConfig.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/config/CustomInterceptorConfig.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -24,6 +24,13 @@
 import java.util.Locale;
 import java.util.Properties;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
 import net.jcip.annotations.Immutable;
 
 import org.infinispan.config.ConfigurationElement.Cardinality;
@@ -41,16 +48,35 @@
 @Immutable
 @ConfigurationElement(name = "interceptor", parent = "customInterceptors" ,
          cardinalityInParent=Cardinality.UNBOUNDED)
+ at XmlAccessorType(XmlAccessType.FIELD)
+ at XmlType(name="interceptor")
 public class CustomInterceptorConfig extends AbstractNamedCacheConfigurationBean {
    
+   @XmlTransient
    private CommandInterceptor interceptor;
+   
+   @XmlTransient
    private boolean isFirst;
+   
+   @XmlTransient
    private boolean isLast;
-   private int index = -1;
-   private String afterInterceptor;
-   private String beforeInterceptor;
+   
+   @XmlAttribute
+   private Integer index = -1;
+   
+   @XmlAttribute
+   private String after;
+   
+   @XmlAttribute
+   private String before;
+   
+   @XmlAttribute
    private Position position;   
+   
+   @XmlAttribute(name="class")
    private String className;
+   
+   @XmlElement
    private TypedProperties properties = EMPTY_PROPERTIES;
 
    public CustomInterceptorConfig() {
@@ -73,8 +99,8 @@
       isFirst = first;
       isLast = last;
       this.index = index;
-      this.afterInterceptor = after;
-      this.beforeInterceptor = before;
+      this.after = after;
+      this.before = before;
    }
 
    /**
@@ -93,8 +119,8 @@
       isFirst = first;
       isLast = last;
       this.index = index;
-      this.afterInterceptor = after == null ? null : after.getName();
-      this.beforeInterceptor = before == null ? null : before.getName();
+      this.after = after == null ? null : after.getName();
+      this.before = before == null ? null : before.getName();
    }
 
    /**
@@ -175,7 +201,7 @@
             containingElement = "interceptor") 
    public void setAfterInterceptor(String afterClass) {
       testImmutability("after");
-      this.afterInterceptor = afterClass;
+      this.after = afterClass;
    }
 
    /**
@@ -194,7 +220,7 @@
             containingElement = "interceptor") 
    public void setBeforeInterceptor(String beforeClass) {
       testImmutability("before");
-      this.beforeInterceptor = beforeClass;
+      this.before = beforeClass;
    }
 
    /**
@@ -244,14 +270,14 @@
     * @see #getAfter()
     */
    public String getAfter() {
-      return afterInterceptor;
+      return after;
    }
 
    /**
     * @see #getBefore()
     */
    public String getBefore() {
-      return beforeInterceptor;
+      return before;
    }
 
    public String toString() {
@@ -260,8 +286,8 @@
             ", isFirst=" + isFirst +
             ", isLast=" + isLast +
             ", index=" + index +
-            ", after='" + afterInterceptor + '\'' +
-            ", before='" + beforeInterceptor + '\'' +
+            ", after='" + after + '\'' +
+            ", before='" + before + '\'' +
             '}';
    }
 
@@ -274,8 +300,8 @@
       if (index != that.index) return false;
       if (isFirst != that.isFirst) return false;
       if (isLast != that.isLast) return false;
-      if (afterInterceptor != null ? !afterInterceptor.equals(that.afterInterceptor) : that.afterInterceptor != null) return false;
-      if (beforeInterceptor != null ? !beforeInterceptor.equals(that.beforeInterceptor) : that.beforeInterceptor != null) return false;
+      if (after != null ? !after.equals(that.after) : that.after != null) return false;
+      if (before != null ? !before.equals(that.before) : that.before != null) return false;
       if (interceptor != null ? !interceptor.equals(that.interceptor) : that.interceptor != null)
          return false;
       return true;
@@ -287,8 +313,8 @@
       result = 31 * result + (isFirst ? 1 : 0);
       result = 31 * result + (isLast ? 1 : 0);
       result = 31 * result + index;
-      result = 31 * result + (afterInterceptor != null ? afterInterceptor.hashCode() : 0);
-      result = 31 * result + (beforeInterceptor != null ? beforeInterceptor.hashCode() : 0);
+      result = 31 * result + (after != null ? after.hashCode() : 0);
+      result = 31 * result + (before != null ? before.hashCode() : 0);
       return result;
    }
 
@@ -298,8 +324,8 @@
       dolly.interceptor = interceptor;
       dolly.isFirst = isFirst;
       dolly.isLast = isLast;
-      dolly.afterInterceptor = afterInterceptor;
-      dolly.beforeInterceptor = beforeInterceptor;
+      dolly.after = after;
+      dolly.before = before;
       return dolly;
    }
    

Modified: trunk/core/src/main/java/org/infinispan/config/GlobalConfiguration.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/GlobalConfiguration.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/config/GlobalConfiguration.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,5 +1,14 @@
 package org.infinispan.config;
 
+import java.util.Properties;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
 import org.infinispan.CacheException;
 import org.infinispan.Version;
 import org.infinispan.executors.DefaultExecutorFactory;
@@ -15,8 +24,6 @@
 import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
 import org.infinispan.util.TypedProperties;
 
-import java.util.Properties;
-
 /**
  * Configuration component that encapsulates the global configuration.
  *
@@ -38,39 +45,51 @@
          @ConfigurationElement(name = "serialization", parent = "global", description = ""),
          @ConfigurationElement(name = "shutdown", parent = "global", description = "")
 })
+ at XmlAccessorType(XmlAccessType.FIELD)
+ at XmlType(propOrder={})
 public class GlobalConfiguration extends AbstractConfigurationBean {
 
+   public GlobalConfiguration() {
+      super();
+   }
+
    /**
     * Default replication version, from {@link org.infinispan.Version#getVersionShort}.
     */
    public static final short DEFAULT_MARSHALL_VERSION = Version.getVersionShort();
-
-   private String asyncListenerExecutorFactoryClass = DefaultExecutorFactory.class.getName();
-   private TypedProperties asyncListenerExecutorProperties = EMPTY_PROPERTIES;
-   private String asyncTransportExecutorFactoryClass = DefaultExecutorFactory.class.getName();
-   private TypedProperties asyncTransportExecutorProperties = EMPTY_PROPERTIES;
-   private String evictionScheduledExecutorFactoryClass = DefaultScheduledExecutorFactory.class.getName();
-   private TypedProperties evictionScheduledExecutorProperties = EMPTY_PROPERTIES;
-   private String replicationQueueScheduledExecutorFactoryClass = DefaultScheduledExecutorFactory.class.getName();
-   private TypedProperties replicationQueueScheduledExecutorProperties = EMPTY_PROPERTIES;
-   private String marshallerClass = VersionAwareMarshaller.class.getName(); // the default
-   private String transportClass = null; // this defaults to a non-clustered cache.
-   private TypedProperties transportProperties = EMPTY_PROPERTIES;
+   
+   @XmlElement
+   private FactoryClassWithPropertiesType asyncListenerExecutor = new FactoryClassWithPropertiesType(DefaultExecutorFactory.class.getName());
+   
+   @XmlElement
+   private FactoryClassWithPropertiesType asyncTransportExecutor= new FactoryClassWithPropertiesType(DefaultExecutorFactory.class.getName());
+   
+   @XmlElement
+   private FactoryClassWithPropertiesType evictionScheduledExecutor= new FactoryClassWithPropertiesType(DefaultScheduledExecutorFactory.class.getName());
+   
+   @XmlElement
+   private FactoryClassWithPropertiesType replicationQueueScheduledExecutor= new FactoryClassWithPropertiesType(DefaultScheduledExecutorFactory.class.getName());
+   
+   @XmlElement
+   private GlobalJmxStatisticsType globalJmxStatistics = new GlobalJmxStatisticsType();
+   
+   @XmlElement
+   private TransportType transport = new TransportType();
+  
+   @XmlElement
+   private SerializationType serialization = new SerializationType();
+   
+   @XmlTransient
    private Configuration defaultConfiguration;
-   private String clusterName = "Infinispan-Cluster";
-   private ShutdownHookBehavior shutdownHookBehavior = ShutdownHookBehavior.DEFAULT;
-   private short marshallVersion = DEFAULT_MARSHALL_VERSION;
+   
+   @XmlElement
+   private ShutdownType shutdown = new ShutdownType();
 
+   @XmlTransient
    private GlobalComponentRegistry gcr;
-   private long distributedSyncTimeout = 60000; // default
 
-   private boolean exposeGlobalJmxStatistics = false;
-   private String jmxDomain = "infinispan";
-   private String mBeanServerLookup = PlatformMBeanServerLookup.class.getName();
-   private boolean allowDuplicateDomains = false;
-
    public boolean isExposeGlobalJmxStatistics() {
-      return exposeGlobalJmxStatistics;
+      return globalJmxStatistics.enabled;
    }
 
    @ConfigurationAttribute(name = "enabled", 
@@ -78,7 +97,7 @@
             description = "If true, global JMX statistics are published")
    public void setExposeGlobalJmxStatistics(boolean exposeGlobalJmxStatistics) {
       testImmutability("exposeGlobalManagementStatistics");
-      this.exposeGlobalJmxStatistics = exposeGlobalJmxStatistics;
+      globalJmxStatistics.setEnabled(exposeGlobalJmxStatistics);
    }
 
    /**
@@ -89,39 +108,36 @@
             containingElement = "globalJmxStatistics", 
             description = "If JMX statistics are enabled then all 'published' JMX objects will appear under this name")
    public void setJmxDomain(String jmxObjectName) {
-      testImmutability("jmxNameBase");
-      this.jmxDomain = jmxObjectName;
+      globalJmxStatistics.setJmxDomain(jmxObjectName);
    }
 
    /**
     * @see #setJmxDomain(String)
     */
    public String getJmxDomain() {
-      return jmxDomain;
+      return globalJmxStatistics.jmxDomain;
    }
 
    public String getMBeanServerLookup() {
-      return mBeanServerLookup;
+      return globalJmxStatistics.mBeanServerLookup;
    }
 
    @ConfigurationAttribute(name = "mBeanServerLookup", 
             containingElement = "globalJmxStatistics", 
             description = "")
    public void setMBeanServerLookup(String mBeanServerLookup) {
-      testImmutability("mBeanServerLookup");
-      this.mBeanServerLookup = mBeanServerLookup;
+      globalJmxStatistics.setMBeanServerLookup(mBeanServerLookup);
    }
 
    public boolean isAllowDuplicateDomains() {
-      return allowDuplicateDomains;
+      return globalJmxStatistics.allowDuplicateDomains;
    }
 
    @ConfigurationAttribute(name = "allowDuplicateDomains", 
             containingElement = "globalJmxStatistics", 
             description = "")
    public void setAllowDuplicateDomains(boolean allowDuplicateDomains) {
-      testImmutability("allowDuplicateDomains");
-      this.allowDuplicateDomains = allowDuplicateDomains;
+      globalJmxStatistics.setAllowDuplicateDomains(allowDuplicateDomains);
    }
 
    /**
@@ -144,7 +160,16 @@
 
    @Inject
    private void injectDependencies(GlobalComponentRegistry gcr) {
-      this.gcr = gcr;
+      this.gcr = gcr;     
+      gcr.registerComponent(asyncListenerExecutor, "asyncListenerExecutor");
+      gcr.registerComponent(asyncTransportExecutor, "asyncTransportExecutor");
+      gcr.registerComponent(evictionScheduledExecutor, "evictionScheduledExecutor");
+      gcr.registerComponent(replicationQueueScheduledExecutor, "replicationQueueScheduledExecutor");
+      gcr.registerComponent(replicationQueueScheduledExecutor, "replicationQueueScheduledExecutor");
+      gcr.registerComponent(globalJmxStatistics, "globalJmxStatistics");
+      gcr.registerComponent(transport, "transport");
+      gcr.registerComponent(serialization, "serialization");
+      gcr.registerComponent(shutdown, "shutdown");
    }
 
    protected boolean hasComponentStarted() {
@@ -152,66 +177,61 @@
    }
 
    public String getAsyncListenerExecutorFactoryClass() {
-      return asyncListenerExecutorFactoryClass;
+      return asyncListenerExecutor.factory;
    }
 
    @ConfigurationAttribute(name = "factory", 
             containingElement = "asyncListenerExecutor", 
             description = "ExecutorService factory class for asynchronous listeners")
    public void setAsyncListenerExecutorFactoryClass(String asyncListenerExecutorFactoryClass) {
-      testImmutability("asyncListenerExecutorFactoryClass");
-      this.asyncListenerExecutorFactoryClass = asyncListenerExecutorFactoryClass;
+      asyncListenerExecutor.setFactory(asyncListenerExecutorFactoryClass);
    }
 
    public String getAsyncTransportExecutorFactoryClass() {
-      return asyncTransportExecutorFactoryClass;
+      return asyncTransportExecutor.factory;
    }
 
    @ConfigurationAttribute(name = "factory", 
             containingElement = "asyncTransportExecutor", 
             description = "ExecutorService factory class for async transport")
    public void setAsyncTransportExecutorFactoryClass(String asyncTransportExecutorFactoryClass) {
-      testImmutability("asyncTransportExecutorFactoryClass");
-      this.asyncTransportExecutorFactoryClass = asyncTransportExecutorFactoryClass;
+      this.asyncTransportExecutor.setFactory(asyncTransportExecutorFactoryClass);
    }
 
    public String getEvictionScheduledExecutorFactoryClass() {
-      return evictionScheduledExecutorFactoryClass;
+      return evictionScheduledExecutor.factory;
    }
 
    @ConfigurationAttribute(name = "factory", 
             containingElement = "evictionScheduledExecutor", 
             description = "ExecutorService factory class for eviction threads")
    public void setEvictionScheduledExecutorFactoryClass(String evictionScheduledExecutorFactoryClass) {
-      testImmutability("evictionScheduledExecutorFactoryClass");
-      this.evictionScheduledExecutorFactoryClass = evictionScheduledExecutorFactoryClass;
+      evictionScheduledExecutor.setFactory(evictionScheduledExecutorFactoryClass);
    }
 
    public String getReplicationQueueScheduledExecutorFactoryClass() {
-      return replicationQueueScheduledExecutorFactoryClass;
+      return replicationQueueScheduledExecutor.factory;
    }
 
    @ConfigurationAttribute(name = "factory", 
             containingElement = "replicationQueueScheduledExecutor", 
             description = "ExecutorService factory class for replication queue threads")
    public void setReplicationQueueScheduledExecutorFactoryClass(String replicationQueueScheduledExecutorFactoryClass) {
-      testImmutability("replicationQueueScheduledExecutorFactoryClass");
-      this.replicationQueueScheduledExecutorFactoryClass = replicationQueueScheduledExecutorFactoryClass;
+      replicationQueueScheduledExecutor.setFactory(replicationQueueScheduledExecutorFactoryClass);
    }
 
    public String getMarshallerClass() {
-      return marshallerClass;
+      return serialization.marshallerClass;
    }
 
    @ConfigurationAttribute(name = "marshallerClass", 
             containingElement = "serialization")
    public void setMarshallerClass(String marshallerClass) {
-      testImmutability("marshallerClass");
-      this.marshallerClass = marshallerClass;
+      serialization.setMarshallerClass(marshallerClass);
    }
 
    public String getTransportClass() {
-      return transportClass;
+      return transport.transportClass;
    }
 
    @ConfigurationAttribute(name = "transportClass", 
@@ -219,12 +239,11 @@
             description = "Transport class, by default null i.e. no transport",
             defaultValue = "org.infinispan.remoting.transport.jgroups.JGroupsTransport")
    public void setTransportClass(String transportClass) {
-      testImmutability("transportClass");
-      this.transportClass = transportClass;
+      transport.setTransportClass(transportClass);
    }
 
    public Properties getTransportProperties() {
-      return transportProperties;
+      return transport.properties;
    }
 
    @ConfigurationProperties(elements = {
@@ -232,13 +251,11 @@
             @ConfigurationProperty(name = "configurationFile", parentElement = "transport"),
             @ConfigurationProperty(name = "configurationXml", parentElement = "transport") })
    public void setTransportProperties(Properties transportProperties) {
-      testImmutability("transportProperties");
-      this.transportProperties = toTypedProperties(transportProperties);
+      transport.setProperties(toTypedProperties(transportProperties));
    }
    
    public void setTransportProperties(String transportPropertiesString) {
-      testImmutability("transportProperties");
-      this.transportProperties = toTypedProperties(transportPropertiesString);
+      transport.setProperties(toTypedProperties(transportPropertiesString));
    }
 
    public Configuration getDefaultConfiguration() {
@@ -246,28 +263,25 @@
    }
 
    public void setDefaultConfiguration(Configuration defaultConfiguration) {
-      testImmutability("defaultConfiguration");
       this.defaultConfiguration = defaultConfiguration;
    }
 
    public String getClusterName() {
-      return clusterName;
+      return transport.clusterName;
    }
 
    @ConfigurationAttribute(name = "clusterName", 
             containingElement = "transport")
    public void setClusterName(String clusterName) {
-      testImmutability("clusterName");
-      this.clusterName = clusterName;
+      transport.setClusterName(clusterName);
    }
 
    public ShutdownHookBehavior getShutdownHookBehavior() {
-      return shutdownHookBehavior;
+      return shutdown.hookBehavior;
    }
 
    public void setShutdownHookBehavior(ShutdownHookBehavior shutdownHookBehavior) {
-      testImmutability("shutdownHookBehavior");
-      this.shutdownHookBehavior = shutdownHookBehavior;
+      shutdown.setHookBehavior(shutdownHookBehavior);
    }
 
    @ConfigurationAttribute(name = "hookBehavior", 
@@ -286,7 +300,7 @@
    }
 
    public Properties getAsyncListenerExecutorProperties() {
-      return asyncListenerExecutorProperties;
+      return asyncListenerExecutor.properties;
    }
    
 
@@ -294,34 +308,30 @@
             @ConfigurationProperty(name = "maxThreads", parentElement = "asyncListenerExecutor"),
             @ConfigurationProperty(name = "threadNamePrefix", parentElement = "asyncListenerExecutor") })
    public void setAsyncListenerExecutorProperties(Properties asyncListenerExecutorProperties) {
-      testImmutability("asyncListenerExecutorProperties");
-      this.asyncListenerExecutorProperties = toTypedProperties(asyncListenerExecutorProperties);
+      asyncListenerExecutor.setProperties(toTypedProperties(asyncListenerExecutorProperties));
    }
 
    public void setAsyncListenerExecutorProperties(String asyncListenerExecutorPropertiesString) {
-      testImmutability("asyncListenerExecutorProperties");
-      this.asyncListenerExecutorProperties = toTypedProperties(asyncListenerExecutorPropertiesString);
+      asyncListenerExecutor.setProperties(toTypedProperties(asyncListenerExecutorPropertiesString));
    }
 
    public Properties getAsyncTransportExecutorProperties() {
-      return asyncTransportExecutorProperties;
+      return asyncTransportExecutor.properties;
    }
 
    @ConfigurationProperties(elements = {
             @ConfigurationProperty(name = "maxThreads", parentElement = "asyncTransportExecutor"),
             @ConfigurationProperty(name = "threadNamePrefix", parentElement = "asyncTransportExecutor") })
    public void setAsyncTransportExecutorProperties(Properties asyncTransportExecutorProperties) {
-      testImmutability("asyncTransportExecutorProperties");
-      this.asyncTransportExecutorProperties = toTypedProperties(asyncTransportExecutorProperties);
+      this.asyncTransportExecutor.setProperties(toTypedProperties(asyncTransportExecutorProperties));
    }
 
    public void setAsyncTransportExecutorProperties(String asyncSerializationExecutorPropertiesString) {
-      testImmutability("asyncTransportExecutorProperties");
-      this.asyncTransportExecutorProperties = toTypedProperties(asyncSerializationExecutorPropertiesString);
+      this.asyncTransportExecutor.setProperties(toTypedProperties(asyncSerializationExecutorPropertiesString));
    }
 
    public Properties getEvictionScheduledExecutorProperties() {
-      return evictionScheduledExecutorProperties;
+      return evictionScheduledExecutor.properties;
    }
 
 
@@ -329,61 +339,55 @@
             @ConfigurationProperty(name = "maxThreads", parentElement = "evictionScheduledExecutor"),
             @ConfigurationProperty(name = "threadNamePrefix", parentElement = "evictionScheduledExecutor") })   
    public void setEvictionScheduledExecutorProperties(Properties evictionScheduledExecutorProperties) {
-      testImmutability("evictionScheduledExecutorProperties");
-      this.evictionScheduledExecutorProperties = toTypedProperties(evictionScheduledExecutorProperties);
+      evictionScheduledExecutor.setProperties(toTypedProperties(evictionScheduledExecutorProperties));
    }
 
    public void setEvictionScheduledExecutorProperties(String evictionScheduledExecutorPropertiesString) {
-      testImmutability("evictionScheduledExecutorProperties");
-      this.evictionScheduledExecutorProperties = toTypedProperties(evictionScheduledExecutorPropertiesString);
+      evictionScheduledExecutor.setProperties(toTypedProperties(evictionScheduledExecutorPropertiesString));
    }
 
    public Properties getReplicationQueueScheduledExecutorProperties() {
-      return replicationQueueScheduledExecutorProperties;
+      return replicationQueueScheduledExecutor.properties;
    }
 
    @ConfigurationProperties(elements = {
             @ConfigurationProperty(name = "maxThreads", parentElement = "replicationQueueScheduledExecutor"),
             @ConfigurationProperty(name = "threadNamePrefix", parentElement = "replicationQueueScheduledExecutor") })      
    public void setReplicationQueueScheduledExecutorProperties(Properties replicationQueueScheduledExecutorProperties) {
-      testImmutability("replicationQueueScheduledExecutorProperties");
-      this.replicationQueueScheduledExecutorProperties = toTypedProperties(replicationQueueScheduledExecutorProperties);
+      this.replicationQueueScheduledExecutor.setProperties(toTypedProperties(replicationQueueScheduledExecutorProperties));
    }
 
    public void setReplicationQueueScheduledExecutorProperties(String replicationQueueScheduledExecutorPropertiesString) {
-      testImmutability("replicationQueueScheduledExecutorProperties");
-      this.replicationQueueScheduledExecutorProperties = toTypedProperties(replicationQueueScheduledExecutorPropertiesString);
+      this.replicationQueueScheduledExecutor.setProperties(toTypedProperties(replicationQueueScheduledExecutorPropertiesString));
    }
 
    public short getMarshallVersion() {
-      return marshallVersion;
+      return Version.getVersionShort(serialization.version);
    }
 
    public String getMarshallVersionString() {
-      return Version.decodeVersionForSerialization(marshallVersion);
+      return serialization.version;
    }
 
    public void setMarshallVersion(short marshallVersion) {
       testImmutability("marshallVersion");
-      this.marshallVersion = marshallVersion;
+      serialization.version = Version.decodeVersionForSerialization(marshallVersion);
    }
    
    @ConfigurationAttribute(name = "version", 
             containingElement = "serialization", defaultValue=Version.version)
    public void setMarshallVersion(String marshallVersion) {
-      testImmutability("marshallVersion");
-      this.marshallVersion = Version.getVersionShort(marshallVersion);
+      serialization.setVersion(marshallVersion);
    }
 
    public long getDistributedSyncTimeout() {
-      return distributedSyncTimeout;
+      return transport.distributedSyncTimeout;
    }
    
    @ConfigurationAttribute(name = "distributedSyncTimeout", 
             containingElement = "transport")
    public void setDistributedSyncTimeout(long distributedSyncTimeout) {
-      testImmutability("distributedSyncTimeout");
-      this.distributedSyncTimeout = distributedSyncTimeout;
+      transport.distributedSyncTimeout = distributedSyncTimeout;
    }
 
    @Override
@@ -393,56 +397,56 @@
 
       GlobalConfiguration that = (GlobalConfiguration) o;
 
-      if (marshallVersion != that.marshallVersion) return false;
-      if (asyncListenerExecutorFactoryClass != null ? !asyncListenerExecutorFactoryClass.equals(that.asyncListenerExecutorFactoryClass) : that.asyncListenerExecutorFactoryClass != null)
+      if (serialization.version != that.serialization.version) return false;
+      if (asyncListenerExecutor.factory != null ? !asyncListenerExecutor.factory.equals(that.asyncListenerExecutor.factory) : that.asyncListenerExecutor.factory != null)
          return false;
-      if (asyncListenerExecutorProperties != null ? !asyncListenerExecutorProperties.equals(that.asyncListenerExecutorProperties) : that.asyncListenerExecutorProperties != null)
+      if (asyncListenerExecutor.properties != null ? !asyncListenerExecutor.properties.equals(that.asyncListenerExecutor.properties) : that.asyncListenerExecutor.properties != null)
          return false;
-      if (asyncTransportExecutorFactoryClass != null ? !asyncTransportExecutorFactoryClass.equals(that.asyncTransportExecutorFactoryClass) : that.asyncTransportExecutorFactoryClass != null)
+      if (asyncTransportExecutor.factory != null ? !asyncTransportExecutor.factory.equals(that.asyncTransportExecutor.factory) : that.asyncTransportExecutor.factory != null)
          return false;
-      if (asyncTransportExecutorProperties != null ? !asyncTransportExecutorProperties.equals(that.asyncTransportExecutorProperties) : that.asyncTransportExecutorProperties != null)
+      if (asyncTransportExecutor.properties != null ? !asyncTransportExecutor.properties.equals(that.asyncTransportExecutor.properties) : that.asyncTransportExecutor.properties != null)
          return false;
-      if (clusterName != null ? !clusterName.equals(that.clusterName) : that.clusterName != null) return false;
+      if (transport.clusterName != null ? !transport.clusterName.equals(that.transport.clusterName) : that.transport.clusterName != null) return false;
       if (defaultConfiguration != null ? !defaultConfiguration.equals(that.defaultConfiguration) : that.defaultConfiguration != null)
          return false;
-      if (evictionScheduledExecutorFactoryClass != null ? !evictionScheduledExecutorFactoryClass.equals(that.evictionScheduledExecutorFactoryClass) : that.evictionScheduledExecutorFactoryClass != null)
+      if (evictionScheduledExecutor.factory != null ? !evictionScheduledExecutor.factory.equals(that.evictionScheduledExecutor.factory) : that.evictionScheduledExecutor.factory != null)
          return false;
-      if (evictionScheduledExecutorProperties != null ? !evictionScheduledExecutorProperties.equals(that.evictionScheduledExecutorProperties) : that.evictionScheduledExecutorProperties != null)
+      if (evictionScheduledExecutor.properties != null ? !evictionScheduledExecutor.properties.equals(that.evictionScheduledExecutor.properties) : that.evictionScheduledExecutor.properties  != null)
          return false;
-      if (marshallerClass != null ? !marshallerClass.equals(that.marshallerClass) : that.marshallerClass != null)
+      if (serialization.marshallerClass != null ? !serialization.marshallerClass .equals(that.serialization.marshallerClass ) : that.serialization.marshallerClass  != null)
          return false;
-      if (replicationQueueScheduledExecutorFactoryClass != null ? !replicationQueueScheduledExecutorFactoryClass.equals(that.replicationQueueScheduledExecutorFactoryClass) : that.replicationQueueScheduledExecutorFactoryClass != null)
+      if (replicationQueueScheduledExecutor.factory != null ? !replicationQueueScheduledExecutor.factory .equals(that.replicationQueueScheduledExecutor.factory ) : that.replicationQueueScheduledExecutor.factory  != null)
          return false;
-      if (replicationQueueScheduledExecutorProperties != null ? !replicationQueueScheduledExecutorProperties.equals(that.replicationQueueScheduledExecutorProperties) : that.replicationQueueScheduledExecutorProperties != null)
+      if (replicationQueueScheduledExecutor.properties != null ? !replicationQueueScheduledExecutor.properties.equals(that.replicationQueueScheduledExecutor.properties) : that.replicationQueueScheduledExecutor.properties != null)
          return false;
-      if (shutdownHookBehavior != that.shutdownHookBehavior) return false;
-      if (transportClass != null ? !transportClass.equals(that.transportClass) : that.transportClass != null)
+      if (shutdown != that.shutdown) return false;
+      if (transport.transportClass != null ? !transport.transportClass.equals(that.transport.transportClass) : that.transport.transportClass != null)
          return false;
-      if (transportProperties != null ? !transportProperties.equals(that.transportProperties) : that.transportProperties != null)
+      if (transport.properties != null ? !transport.properties.equals(that.transport.properties) : that.transport.properties != null)
          return false;
-      if (distributedSyncTimeout != that.distributedSyncTimeout) return false;
+      if (transport.distributedSyncTimeout != that.transport.distributedSyncTimeout) return false;
 
       return true;
    }
 
    @Override
    public int hashCode() {
-      int result = asyncListenerExecutorFactoryClass != null ? asyncListenerExecutorFactoryClass.hashCode() : 0;
-      result = 31 * result + (asyncListenerExecutorProperties != null ? asyncListenerExecutorProperties.hashCode() : 0);
-      result = 31 * result + (asyncTransportExecutorFactoryClass != null ? asyncTransportExecutorFactoryClass.hashCode() : 0);
-      result = 31 * result + (asyncTransportExecutorProperties != null ? asyncTransportExecutorProperties.hashCode() : 0);
-      result = 31 * result + (evictionScheduledExecutorFactoryClass != null ? evictionScheduledExecutorFactoryClass.hashCode() : 0);
-      result = 31 * result + (evictionScheduledExecutorProperties != null ? evictionScheduledExecutorProperties.hashCode() : 0);
-      result = 31 * result + (replicationQueueScheduledExecutorFactoryClass != null ? replicationQueueScheduledExecutorFactoryClass.hashCode() : 0);
-      result = 31 * result + (replicationQueueScheduledExecutorProperties != null ? replicationQueueScheduledExecutorProperties.hashCode() : 0);
-      result = 31 * result + (marshallerClass != null ? marshallerClass.hashCode() : 0);
-      result = 31 * result + (transportClass != null ? transportClass.hashCode() : 0);
-      result = 31 * result + (transportProperties != null ? transportProperties.hashCode() : 0);
+      int result = asyncListenerExecutor.factory != null ? asyncListenerExecutor.factory.hashCode() : 0;
+      result = 31 * result + (asyncListenerExecutor.properties != null ? asyncListenerExecutor.properties.hashCode() : 0);
+      result = 31 * result + (asyncTransportExecutor.factory != null ? asyncTransportExecutor.factory.hashCode() : 0);
+      result = 31 * result + (asyncTransportExecutor.properties != null ? asyncTransportExecutor.properties.hashCode() : 0);
+      result = 31 * result + (evictionScheduledExecutor.factory != null ? evictionScheduledExecutor.factory.hashCode() : 0);
+      result = 31 * result + ( evictionScheduledExecutor.properties  != null ? evictionScheduledExecutor.properties.hashCode() : 0);
+      result = 31 * result + (replicationQueueScheduledExecutor.factory  != null ? replicationQueueScheduledExecutor.factory.hashCode() : 0);
+      result = 31 * result + (replicationQueueScheduledExecutor.properties != null ? replicationQueueScheduledExecutor.properties.hashCode() : 0);
+      result = 31 * result + (serialization.marshallerClass  != null ? serialization.marshallerClass .hashCode() : 0);
+      result = 31 * result + (transport.transportClass != null ? transport.transportClass.hashCode() : 0);
+      result = 31 * result + (transport.properties  != null ? transport.properties .hashCode() : 0);
       result = 31 * result + (defaultConfiguration != null ? defaultConfiguration.hashCode() : 0);
-      result = 31 * result + (clusterName != null ? clusterName.hashCode() : 0);
-      result = 31 * result + (shutdownHookBehavior != null ? shutdownHookBehavior.hashCode() : 0);
-      result = 31 * result + (int) marshallVersion;
-      result = (int) (31 * result + distributedSyncTimeout);
+      result = 31 * result + (transport.clusterName  != null ? transport.clusterName .hashCode() : 0);
+      result = 31 * result + (shutdown.hookBehavior.hashCode());
+      result = 31 * result + ((int) serialization.version.hashCode());
+      result = (int) (31 * result + transport.distributedSyncTimeout);
       return result;
    }
 
@@ -483,4 +487,175 @@
       gc.setTransportProperties((Properties) null);
       return gc;
    }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class FactoryClassWithPropertiesType extends AbstractConfigurationBeanWithGCR {
+      
+      @XmlAttribute
+      private String factory;
+      
+      @XmlElement(name="properties")
+      private TypedProperties properties = EMPTY_PROPERTIES;
+
+      public FactoryClassWithPropertiesType(String factory) {
+         super();
+         this.factory = factory;
+      }   
+      
+      public FactoryClassWithPropertiesType() {
+         super();
+         this.factory = "";
+      }
+
+      public void setFactory(String factory) {
+         testImmutability("factory");
+         this.factory = factory;
+      }
+
+      public void setProperties(TypedProperties properties) {
+         testImmutability("properties");
+         this.properties = properties;
+      }         
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class TransportType extends AbstractConfigurationBeanWithGCR {
+     
+      private String clusterName = "Infinispan-Cluster";
+      
+      private Long distributedSyncTimeout = 60000L; // default
+     
+      private String transportClass = null; // this defaults to a non-clustered cache.
+      
+      private TypedProperties properties = EMPTY_PROPERTIES;
+
+      @XmlAttribute
+      public void setClusterName(String clusterName) {
+         testImmutability("clusterName");
+         this.clusterName = clusterName;
+      }
+
+      @XmlAttribute
+      public void setDistributedSyncTimeout(Long distributedSyncTimeout) {
+         testImmutability("distributedSyncTimeout");
+         this.distributedSyncTimeout = distributedSyncTimeout;
+      }
+
+      @XmlAttribute
+      public void setTransportClass(String transportClass) {
+         testImmutability("transportClass");
+         this.transportClass = transportClass;
+      }
+
+      @XmlElement
+      public void setProperties(TypedProperties properties) {
+         //testImmutability("properties");
+         //TODO fails JmxStatsFunctionalTest#testMultipleManagersOnSameServerFails
+         this.properties = properties;
+      }     
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class SerializationType extends AbstractConfigurationBeanWithGCR {
+      
+      private String marshallerClass = VersionAwareMarshaller.class.getName(); // the default
+      
+      private String version = Version.getMajorVersion();
+      
+      public SerializationType() {        
+         super();
+      }
+
+      @XmlAttribute
+      public void setMarshallerClass(String marshallerClass) {
+         testImmutability("marshallerClass");
+         this.marshallerClass = marshallerClass;
+      }
+
+      @XmlAttribute
+      public void setVersion(String version) {
+         testImmutability("version");
+         this.version = version;
+      }                      
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class GlobalJmxStatisticsType extends AbstractConfigurationBeanWithGCR {
+      
+      private Boolean enabled = false;
+      
+      private String jmxDomain = "infinispan";
+      
+      private String mBeanServerLookup = PlatformMBeanServerLookup.class.getName();
+      
+      private Boolean allowDuplicateDomains = false;
+
+      @XmlAttribute
+      public void setEnabled(Boolean enabled) {
+         testImmutability("enabled");
+         this.enabled = enabled;
+      }
+
+      @XmlAttribute
+      public void setJmxDomain(String jmxDomain) {
+         testImmutability("jmxDomain");
+         this.jmxDomain = jmxDomain;
+      }
+
+      @XmlAttribute
+      public void setMBeanServerLookup(String beanServerLookup) {
+         testImmutability("mBeanServerLookup");
+         mBeanServerLookup = beanServerLookup;
+      }
+
+      @XmlAttribute
+      public void setAllowDuplicateDomains(Boolean allowDuplicateDomains) {
+         testImmutability("allowDuplicateDomains");
+         this.allowDuplicateDomains = allowDuplicateDomains;
+      }            
+   }
+   
+   @XmlAccessorType(XmlAccessType.PROPERTY)
+   private static class ShutdownType extends AbstractConfigurationBeanWithGCR {
+      
+      private ShutdownHookBehavior hookBehavior = ShutdownHookBehavior.DEFAULT;
+
+      @XmlAttribute
+      public void setHookBehavior(ShutdownHookBehavior hookBehavior) {
+         testImmutability("hookBehavior");
+         this.hookBehavior = hookBehavior;
+      }               
+   }
 }
+
+class AbstractConfigurationBeanWithGCR extends AbstractConfigurationBean{
+
+   GlobalComponentRegistry gcr = null;
+   
+   
+   @Inject
+   public void inject(GlobalComponentRegistry gcr) {
+      this.gcr = gcr;
+   }
+
+
+   @Override
+   protected boolean hasComponentStarted() {
+      return gcr != null && gcr.getStatus() != null && gcr.getStatus() == ComponentStatus.RUNNING;
+   }
+   
+}
+ class PropertiesType {
+    
+   @XmlElement(name = "property")
+   Property properties[];
+}
+
+class Property {
+   
+   @XmlAttribute
+   String name;
+   
+   @XmlAttribute
+   String value;
+}

Added: trunk/core/src/main/java/org/infinispan/config/InfinispanConfiguration.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/InfinispanConfiguration.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/config/InfinispanConfiguration.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -0,0 +1,188 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.infinispan.config;
+ 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.SchemaFactory;
+
+import org.infinispan.config.parsing.XmlConfigurationParser;
+import org.infinispan.util.FileLookup;
+
+ at XmlRootElement(name = "infinispan")
+ at XmlAccessorType(XmlAccessType.FIELD)
+public class InfinispanConfiguration implements XmlConfigurationParser {
+   
+   @XmlElement
+   private GlobalConfiguration global;
+   
+   @XmlElement(name="default")
+   private Configuration defaultConfiguration;
+   
+   @XmlElement(name="namedCache")
+   private List<Configuration> namedCaches;
+   
+   /**
+    * Factory method to create an instance of Infinispan configuration. If users want to verify
+    * configuration file correctness against Infinispan schema then appropriate schema file name
+    * should be provided as well.
+    * <p>
+    * Both configuration file and schema file are looked up in following order:
+    * <p>
+    *  <ol> 
+    *  <li> using current thread's context ClassLoader</li> 
+    *  <li> if fails, the system ClassLoader</li> 
+    *  <li> if fails, attempt is made to load it as a file from the disk </li> 
+    *  </ol> 
+    * 
+    * @param configFileName configuration file name
+    * @param schemaFileName schema file name
+    * @return infinispan configuration
+    * @throws IOException if there are any issues creating InfinispanConfiguration object 
+    */
+   public static InfinispanConfiguration newInfinispanConfiguration(String configFileName,
+            String schemaFileName) throws IOException {
+
+      InputStream inputStream = configFileName != null ? findInputStream(configFileName) : null;
+      InputStream schemaIS = schemaFileName != null ? findInputStream(schemaFileName) : null;
+      return newInfinispanConfiguration(inputStream, schemaIS);
+   }
+   
+   /**
+    * Factory method to create an instance of Infinispan configuration. 
+    * <p>
+    * Configuration file is looked up in following order:
+    * <p>
+    *  <ol> 
+    *  <li> using current thread's context ClassLoader</li> 
+    *  <li> if fails, the system ClassLoader</li> 
+    *  <li> if fails, attempt is made to load it as a file from the disk </li> 
+    *  </ol> 
+    * 
+    * @param configFileName configuration file name
+    * @return returns infinispan configuration
+    * @throws IOException if there are any issues creating InfinispanConfiguration object 
+    */
+   public static InfinispanConfiguration newInfinispanConfiguration(String configFileName)
+            throws IOException {
+      return newInfinispanConfiguration(configFileName,null);
+     
+   }
+   
+   /**
+    * Factory method to create an instance of Infinispan configuration. 
+    * 
+    * @param config configuration input stream
+    * @return returns infinispan configuration
+    * @throws IOException if there are any issues creating InfinispanConfiguration object 
+    */
+   public static InfinispanConfiguration newInfinispanConfiguration(InputStream config)
+            throws IOException {
+      return newInfinispanConfiguration(config, null); 
+   }
+   
+   /**
+    * Factory method to create an instance of Infinispan configuration. If users want to verify
+    * configuration file correctness against Infinispan schema then appropriate schema input stream
+    * should be provided as well.
+    *
+    * @param config configuration input stream
+    * @param schema schema inputstream
+    * @return infinispan configuration
+    * @throws IOException if there are any issues creating InfinispanConfiguration object 
+    */
+   public static InfinispanConfiguration newInfinispanConfiguration(InputStream config,
+            InputStream schema) throws IOException {
+      try {
+         JAXBContext jc = JAXBContext.newInstance(InfinispanConfiguration.class);
+         Unmarshaller u = jc.createUnmarshaller();
+         if (schema != null) {
+            SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
+            u.setSchema(factory.newSchema(new StreamSource(schema)));
+         }
+         InfinispanConfiguration doc = (InfinispanConfiguration) u.unmarshal(config);
+         //legacy, don't ask
+         doc.parseGlobalConfiguration().setDefaultConfiguration(doc.parseDefaultConfiguration());
+         return doc;
+      } catch (Exception e) {
+         IOException ioe = new IOException(e.getLocalizedMessage());
+         ioe.initCause(e);
+         throw ioe;
+      }
+   }
+
+   /**
+    * Should never called. Construct InfinispanConfiguration with constructor other than no-arg constructor
+    * <p>
+    * Needed for reflection
+    * 
+    */
+   public InfinispanConfiguration() {
+      super();
+   }
+  
+   public void initialize(String fileName) throws IOException {
+   }
+   
+   public void initialize(InputStream configuration) throws IOException {
+    
+   }
+
+   private static InputStream findInputStream(String fileName) throws FileNotFoundException {
+      if (fileName == null)
+         throw new NullPointerException("File name cannot be null!");
+      FileLookup fileLookup = new FileLookup();
+      InputStream is = fileLookup.lookupFile(fileName);
+      if (is == null)
+         throw new FileNotFoundException("File " + fileName
+                  + " could not be found, either on the classpath or on the file system!");
+      return is;
+   } 
+
+   public Configuration parseDefaultConfiguration() throws ConfigurationException {
+      return defaultConfiguration;
+   }
+
+   public GlobalConfiguration parseGlobalConfiguration() {
+      return  global;
+   }
+
+   public Map<String, Configuration> parseNamedConfigurations() throws ConfigurationException {
+      Map<String,Configuration> map = new HashMap<String, Configuration>(7);
+      for (Configuration conf : namedCaches) {
+         map.put(conf.getName(), conf);
+      }
+      return map;
+   }
+}

Modified: trunk/core/src/main/java/org/infinispan/config/PluggableConfigurationComponent.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/PluggableConfigurationComponent.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/config/PluggableConfigurationComponent.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -22,19 +22,27 @@
 package org.infinispan.config;
 
 import org.infinispan.config.parsing.XmlConfigHelper;
+import org.infinispan.util.TypedProperties;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.Properties;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
 /**
  * A configuration component where the implementation class can be specified, and comes with its own set of properties.
  *
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 4.0
  */
+ at XmlAccessorType(XmlAccessType.FIELD)
 public abstract class PluggableConfigurationComponent extends AbstractNamedCacheConfigurationBean {
-   protected Properties properties = EMPTY_PROPERTIES;
+   @XmlElement(name="properties")
+   protected TypedProperties properties = EMPTY_PROPERTIES;
 
    public Properties getProperties() {
       return properties;
@@ -42,7 +50,7 @@
 
    public void setProperties(Properties properties) {
       testImmutability("properties");
-      this.properties = properties;
+      this.properties = toTypedProperties(properties);
    }
 
    public void setProperties(String properties) throws IOException {
@@ -53,7 +61,7 @@
       // replace any "\" that is not preceded by a backslash with "\\"
       properties = XmlConfigHelper.escapeBackslashes(properties);
       ByteArrayInputStream is = new ByteArrayInputStream(properties.trim().getBytes("ISO8859_1"));
-      this.properties = new Properties();
+      this.properties = new TypedProperties();
       this.properties.load(is);
       is.close();
    }
@@ -82,7 +90,7 @@
    @Override
    public PluggableConfigurationComponent clone() throws CloneNotSupportedException {
       PluggableConfigurationComponent clone = (PluggableConfigurationComponent) super.clone();
-      if (properties != null) clone.properties = (Properties) properties.clone();
+      if (properties != null) clone.properties = (TypedProperties) properties.clone();
       return clone;
    }
 }

Added: trunk/core/src/main/java/org/infinispan/config/TypedPropertiesAdapter.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/TypedPropertiesAdapter.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/config/TypedPropertiesAdapter.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.infinispan.config;
+
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import org.infinispan.util.TypedProperties;
+
+public class TypedPropertiesAdapter extends XmlAdapter<PropertiesType, TypedProperties> {
+
+   @Override
+   public PropertiesType marshal(TypedProperties tp) throws Exception {
+      PropertiesType pxml = new PropertiesType();
+      Property[] pa = new Property[tp.size()];
+      Set<Entry<Object, Object>> set = tp.entrySet();
+      int index = 0;
+      for (Entry<Object, Object> entry : set) {
+         pa[index] = new Property();
+         pa[index].name = (String) entry.getKey();
+         pa[index].value = (String) entry.getValue();
+         index++;
+      }
+      pxml.properties = pa;
+      return pxml;
+   }
+
+   @Override
+   public TypedProperties unmarshal(PropertiesType props) throws Exception {
+      TypedProperties tp = new TypedProperties();
+      for (Property p : props.properties) {
+         tp.put(p.name, p.value);
+      }
+      return tp;
+   }
+}

Modified: trunk/core/src/main/java/org/infinispan/config/package-info.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/package-info.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/config/package-info.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,4 +1,12 @@
 /**
  * Cache configuration beans and parsers.
+ * Need @XmlSchema annotation in order to classify all JAXB created schema elements in appropriate XML namespace
  */
-package org.infinispan.config;
\ No newline at end of file
+ at XmlSchema(namespace = "urn:infinispan:config:4.0", elementFormDefault = XmlNsForm.QUALIFIED, attributeFormDefault = XmlNsForm.UNQUALIFIED, 
+         xmlns = {
+         @javax.xml.bind.annotation.XmlNs(prefix = "tns", namespaceURI = "urn:infinispan:config:4.0"),
+         @javax.xml.bind.annotation.XmlNs(prefix = "xs", namespaceURI = "http://www.w3.org/2001/XMLSchema") })
+package org.infinispan.config;
+
+import javax.xml.bind.annotation.XmlNsForm;
+import javax.xml.bind.annotation.*;
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/eviction/package-info.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/eviction/package-info.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/eviction/package-info.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,4 +1,13 @@
 /**
  * Classes related to eviction.
+ * Need @XmlSchema annotation for EvictionStrategy.java
  */
-package org.infinispan.eviction;
\ No newline at end of file
+ at XmlSchema(namespace = "urn:infinispan:config:4.0", elementFormDefault = XmlNsForm.QUALIFIED, attributeFormDefault = XmlNsForm.UNQUALIFIED, 
+         xmlns = {
+         @javax.xml.bind.annotation.XmlNs(prefix = "tns", namespaceURI = "urn:infinispan:config:4.0"),
+         @javax.xml.bind.annotation.XmlNs(prefix = "xs", namespaceURI = "http://www.w3.org/2001/XMLSchema") })
+package org.infinispan.eviction;
+
+
+import javax.xml.bind.annotation.XmlNsForm;
+import javax.xml.bind.annotation.*;
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -14,6 +14,7 @@
 import org.infinispan.commands.write.RemoveCommand;
 import org.infinispan.commands.write.ReplaceCommand;
 import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.config.Configuration;
 import org.infinispan.context.Flag;
 import org.infinispan.context.InvocationContext;
 import org.infinispan.context.impl.LocalTxInvocationContext;
@@ -58,7 +59,8 @@
 
 
    @Inject
-   public void init(TransactionManager tm, TransactionTable txTable, TransactionLog transactionLog) {
+   public void init(TransactionManager tm, TransactionTable txTable, TransactionLog transactionLog, Configuration c) {
+      this.configuration = c;
       this.tm = tm;
       this.transactionLog = transactionLog;
       this.txTable = txTable;

Modified: trunk/core/src/main/java/org/infinispan/loaders/AbstractCacheLoaderConfig.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/AbstractCacheLoaderConfig.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/loaders/AbstractCacheLoaderConfig.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,5 +1,9 @@
 package org.infinispan.loaders;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
 import org.infinispan.CacheException;
 import org.infinispan.config.ConfigurationAttribute;
 import org.infinispan.config.PluggableConfigurationComponent;
@@ -10,8 +14,10 @@
  * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
+ at XmlAccessorType(XmlAccessType.FIELD)
 public class AbstractCacheLoaderConfig extends PluggableConfigurationComponent implements CacheLoaderConfig {
 
+   @XmlAttribute(name="class")
    protected String cacheLoaderClassName;
 
    public String getCacheLoaderClassName() {

Modified: trunk/core/src/main/java/org/infinispan/loaders/AbstractCacheStoreConfig.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/AbstractCacheStoreConfig.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/loaders/AbstractCacheStoreConfig.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,5 +1,11 @@
 package org.infinispan.loaders;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
 import org.infinispan.config.ConfigurationAttribute;
 import org.infinispan.loaders.decorators.AsyncStoreConfig;
 import org.infinispan.loaders.decorators.SingletonStoreConfig;
@@ -18,14 +24,29 @@
  * @version $Id$
  * @since 4.0
  */
+ at XmlAccessorType(XmlAccessType.FIELD)
+ at XmlType(propOrder={"singletonStore","async"})
 public class AbstractCacheStoreConfig extends AbstractCacheLoaderConfig implements CacheStoreConfig {
-   private boolean ignoreModifications;
-   private boolean fetchPersistentState;
-   private boolean purgeOnStartup;
-   private SingletonStoreConfig singletonStoreConfig = new SingletonStoreConfig();
-   private AsyncStoreConfig asyncStoreConfig = new AsyncStoreConfig();
+   
+   @XmlAttribute
+   private Boolean ignoreModifications = false;
+   
+   @XmlAttribute
+   private Boolean fetchPersistentState = false;
+   
+   @XmlAttribute
+   private Boolean purgeOnStartup = false;
+   
+   @XmlAttribute
+   private Boolean purgeSynchronously = false;
+   
+   @XmlElement
+   private SingletonStoreConfig singletonStore = new SingletonStoreConfig();
+   
+   @XmlElement
+   private AsyncStoreConfig async = new AsyncStoreConfig();
 
-   private boolean purgeSynchronously = false;
+   
 
    public boolean isPurgeSynchronously() {
       return purgeSynchronously;
@@ -74,21 +95,21 @@
    }
 
    public SingletonStoreConfig getSingletonStoreConfig() {
-      return singletonStoreConfig;
+      return singletonStore;
    }
 
    public void setSingletonStoreConfig(SingletonStoreConfig singletonStoreConfig) {
-      testImmutability("singletonStoreConfig");
-      this.singletonStoreConfig = singletonStoreConfig;
+      testImmutability("singletonStore");
+      this.singletonStore = singletonStoreConfig;
    }
 
    public AsyncStoreConfig getAsyncStoreConfig() {
-      return asyncStoreConfig;
+      return async;
    }
 
    public void setAsyncStoreConfig(AsyncStoreConfig asyncStoreConfig) {
-      testImmutability("asyncStoreConfig");
-      this.asyncStoreConfig = asyncStoreConfig;
+      testImmutability("async");
+      this.async = asyncStoreConfig;
    }
 
    @Override
@@ -107,8 +128,8 @@
       return Util.safeEquals(this.cacheLoaderClassName, other.cacheLoaderClassName)
             && (this.ignoreModifications == other.ignoreModifications)
             && (this.fetchPersistentState == other.fetchPersistentState)
-            && Util.safeEquals(this.singletonStoreConfig, other.singletonStoreConfig)
-            && Util.safeEquals(this.asyncStoreConfig, other.asyncStoreConfig)
+            && Util.safeEquals(this.singletonStore, other.singletonStore)
+            && Util.safeEquals(this.async, other.async)
             && Util.safeEquals(this.purgeSynchronously, other.purgeSynchronously);
    }
 
@@ -122,8 +143,8 @@
       result = 31 * result + (cacheLoaderClassName == null ? 0 : cacheLoaderClassName.hashCode());
       result = 31 * result + (ignoreModifications ? 0 : 1);
       result = 31 * result + (fetchPersistentState ? 0 : 1);
-      result = 31 * result + (singletonStoreConfig == null ? 0 : singletonStoreConfig.hashCode());
-      result = 31 * result + (asyncStoreConfig == null ? 0 : asyncStoreConfig.hashCode());
+      result = 31 * result + (singletonStore == null ? 0 : singletonStore.hashCode());
+      result = 31 * result + (async == null ? 0 : async.hashCode());
       result = 31 * result + (purgeOnStartup ? 0 : 1);
       return result;
    }
@@ -135,8 +156,8 @@
             .append(", fetchPersistentState=").append(fetchPersistentState)
             .append(", properties=").append(properties)
             .append(", purgeOnStartup=").append(purgeOnStartup).append("},")
-            .append(", SingletonStoreConfig{").append(singletonStoreConfig).append('}')
-            .append(", AsyncStoreConfig{").append(asyncStoreConfig).append('}')
+            .append(", singletonStore{").append(singletonStore).append('}')
+            .append(", async{").append(async).append('}')
             .append(", purgeSynchronously{").append(purgeSynchronously).append('}')
             .toString();
    }
@@ -145,8 +166,8 @@
    public AbstractCacheStoreConfig clone() {
       AbstractCacheStoreConfig clone = null;
       clone = (AbstractCacheStoreConfig) super.clone();
-      if (singletonStoreConfig != null) clone.setSingletonStoreConfig(singletonStoreConfig.clone());
-      if (asyncStoreConfig != null) clone.setAsyncStoreConfig(asyncStoreConfig.clone());
+      if (singletonStore != null) clone.setSingletonStoreConfig(singletonStore.clone());
+      if (async != null) clone.setAsyncStoreConfig(async.clone());
       return clone;
    }
 }

Modified: trunk/core/src/main/java/org/infinispan/loaders/CacheLoaderConfig.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/CacheLoaderConfig.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/loaders/CacheLoaderConfig.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,11 +1,23 @@
 package org.infinispan.loaders;
 
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import org.infinispan.config.ConfigurationException;
+import org.infinispan.config.parsing.XmlConfigHelper;
+import org.infinispan.util.Util;
+
 /**
  * Configures individual cache loaders
  *
  * @author Manik Surtani
  * @since 4.0
  */
+ at XmlJavaTypeAdapter(CacheLoaderConfigAdapter.class)
 public interface CacheLoaderConfig extends Cloneable {
 
    CacheLoaderConfig clone();
@@ -14,3 +26,57 @@
 
    void setCacheLoaderClassName(String s);
 }
+
+class CacheLoaderInvocationhandler implements InvocationHandler {
+
+   private AbstractCacheStoreConfig acsc;
+
+   public CacheLoaderInvocationhandler(AbstractCacheStoreConfig acsc) {
+      super();
+      this.acsc = acsc;
+   }
+
+   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+      return method.invoke(acsc, args);
+   }
+}
+
+class CacheLoaderConfigAdapter extends XmlAdapter<AbstractCacheStoreConfig, CacheLoaderConfig>{
+
+   @Override
+   public AbstractCacheStoreConfig marshal(CacheLoaderConfig arg0) throws Exception {         
+      return (AbstractCacheStoreConfig) arg0;
+   }
+
+   @Override
+   public CacheLoaderConfig unmarshal(AbstractCacheStoreConfig storeConfig) throws Exception {
+      String clClass = storeConfig.getCacheLoaderClassName();
+      if (clClass == null || clClass.length()==0)
+         throw new ConfigurationException("Missing 'class'  attribute for cache loader configuration");
+      
+      CacheLoader cl;
+      CacheLoaderConfig clc;
+      try {
+         cl = (CacheLoader) Util.getInstance(clClass);
+         clc = Util.getInstance(cl.getConfigurationClass());
+      } catch (Exception e) {
+         throw new ConfigurationException("Unable to instantiate cache loader or configuration", e);
+      }
+      
+      clc.setCacheLoaderClassName(clClass);
+
+      Properties props = storeConfig.getProperties();                 
+      if (props != null) XmlConfigHelper.setValues(clc, props, false, true);
+      
+      
+      if (clc instanceof CacheStoreConfig) {
+         CacheStoreConfig csc = (CacheStoreConfig) clc;
+         csc.setFetchPersistentState(storeConfig.isFetchPersistentState());
+         csc.setIgnoreModifications(storeConfig.isIgnoreModifications());
+         csc.setPurgeOnStartup(storeConfig.isPurgeOnStartup());
+         csc.setPurgeSynchronously(storeConfig.isPurgeSynchronously());
+         csc.setSingletonStoreConfig(storeConfig.getSingletonStoreConfig());
+         csc.setAsyncStoreConfig(storeConfig.getAsyncStoreConfig());         
+      }
+      return clc;
+   }}
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/loaders/decorators/AsyncStoreConfig.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/decorators/AsyncStoreConfig.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/loaders/decorators/AsyncStoreConfig.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,5 +1,9 @@
 package org.infinispan.loaders.decorators;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
 import org.infinispan.config.AbstractNamedCacheConfigurationBean;
 import org.infinispan.config.ConfigurationAttribute;
 import org.infinispan.config.ConfigurationElement;
@@ -12,11 +16,17 @@
  * @since 4.0
  */
 @ConfigurationElement(name="async", parent="loader")
+ at XmlAccessorType(XmlAccessType.FIELD)
 public class AsyncStoreConfig extends AbstractNamedCacheConfigurationBean {
-   boolean enabled;
-   int threadPoolSize = 1;
+   @XmlAttribute
+   Boolean enabled = false;
+  
+   @XmlAttribute
+   Integer threadPoolSize = 1;
+   
    @Dynamic
-   long mapLockTimeout = 5000;
+   @XmlAttribute
+   Long mapLockTimeout = 5000L;
 
    public boolean isEnabled() {
       return enabled;
@@ -50,7 +60,7 @@
             containingElement = "async",
             description="Lock timeout for access to map containing latest state.")
    public void setMapLockTimeout(long stateLockTimeout) {
-      testImmutability("stateLockTimeout");
+      testImmutability("mapLockTimeout");
       this.mapLockTimeout = stateLockTimeout;
    }   
    
@@ -62,5 +72,4 @@
          throw new RuntimeException("Should not happen!", e);
       }
    }
-
 }

Modified: trunk/core/src/main/java/org/infinispan/loaders/decorators/SingletonStoreConfig.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/decorators/SingletonStoreConfig.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/loaders/decorators/SingletonStoreConfig.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,5 +1,9 @@
 package org.infinispan.loaders.decorators;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
 import org.infinispan.config.AbstractNamedCacheConfigurationBean;
 import org.infinispan.config.ConfigurationAttribute;
 import org.infinispan.config.ConfigurationElement;
@@ -11,24 +15,30 @@
  * @since 4.0
  */
 @ConfigurationElement(name="singletonStore", parent="loader")
+ at XmlAccessorType(XmlAccessType.FIELD)
 public class SingletonStoreConfig extends AbstractNamedCacheConfigurationBean {
 
    private static final long serialVersionUID = 824251894176131850L;
 
-   boolean singletonStoreEnabled;
-   boolean pushStateWhenCoordinator = true;
-   long pushStateTimeout = 10000;
+   @XmlAttribute
+   Boolean enabled = false;
+   
+   @XmlAttribute
+   Boolean pushStateWhenCoordinator = true;
+   
+   @XmlAttribute
+   Long pushStateTimeout = 10000L;
 
    public boolean isSingletonStoreEnabled() {
-      return singletonStoreEnabled;
+      return enabled;
    }
 
    @ConfigurationAttribute(name = "enabled", 
             containingElement = "singletonStore",
             description="Switch to enable singleton store")              
    public void setSingletonStoreEnabled(boolean singletonStoreEnabled) {
-      testImmutability("singletonStoreEnabled");
-      this.singletonStoreEnabled = singletonStoreEnabled;
+      testImmutability("enabled");
+      this.enabled = singletonStoreEnabled;
    }
 
 

Added: trunk/core/src/main/java/org/infinispan/loaders/decorators/package-info.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/decorators/package-info.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/loaders/decorators/package-info.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -0,0 +1,12 @@
+/**
+ * This package contains loaders and stores, which are used for overflow or persistence.
+ * Need @XmlSchema annotation for AsyncStoreConfig.java and SingletonStoreConfig.java
+ */
+ at XmlSchema(namespace = "urn:infinispan:config:4.0", elementFormDefault = XmlNsForm.QUALIFIED, attributeFormDefault = XmlNsForm.UNQUALIFIED, 
+         xmlns = {
+         @javax.xml.bind.annotation.XmlNs(prefix = "tns", namespaceURI = "urn:infinispan:config:4.0"),
+         @javax.xml.bind.annotation.XmlNs(prefix = "xs", namespaceURI = "http://www.w3.org/2001/XMLSchema") })
+package org.infinispan.loaders.decorators;
+
+import javax.xml.bind.annotation.XmlNsForm;
+import javax.xml.bind.annotation.*;
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/loaders/package-info.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/package-info.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/loaders/package-info.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,4 +1,12 @@
 /**
  * This package contains loaders and stores, which are used for overflow or persistence.
+ * Need @XmlSchema annotation for CacheLoaderConfig.java and AbstractCacheStoreConfig.java
  */
-package org.infinispan.loaders;
\ No newline at end of file
+ at XmlSchema(namespace = "urn:infinispan:config:4.0", elementFormDefault = XmlNsForm.QUALIFIED, attributeFormDefault = XmlNsForm.UNQUALIFIED, 
+         xmlns = {
+         @javax.xml.bind.annotation.XmlNs(prefix = "tns", namespaceURI = "urn:infinispan:config:4.0"),
+         @javax.xml.bind.annotation.XmlNs(prefix = "xs", namespaceURI = "http://www.w3.org/2001/XMLSchema") })
+package org.infinispan.loaders;
+
+import javax.xml.bind.annotation.XmlNsForm;
+import javax.xml.bind.annotation.*;
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -27,6 +27,7 @@
 import org.infinispan.config.ConfigurationException;
 import org.infinispan.config.DuplicateCacheNameException;
 import org.infinispan.config.GlobalConfiguration;
+import org.infinispan.config.InfinispanConfiguration;
 import org.infinispan.config.parsing.XmlConfigurationParser;
 import org.infinispan.config.parsing.XmlConfigurationParserImpl;
 import org.infinispan.factories.GlobalComponentRegistry;
@@ -204,7 +205,7 @@
     */
    public DefaultCacheManager(String configurationFile, boolean start) throws IOException {
       try {
-         initialize(new XmlConfigurationParserImpl(configurationFile));
+         initialize(InfinispanConfiguration.newInfinispanConfiguration(configurationFile));
       }
       catch (RuntimeException re) {
          throw new ConfigurationException(re);
@@ -235,7 +236,7 @@
     */
    public DefaultCacheManager(InputStream configurationStream, boolean start) throws IOException {
       try {
-         initialize(new XmlConfigurationParserImpl(configurationStream));
+         initialize(InfinispanConfiguration.newInfinispanConfiguration(configurationStream));
       } catch (ConfigurationException ce) {
          throw ce;
       } catch (RuntimeException re) {

Modified: trunk/core/src/main/java/org/infinispan/util/ReflectionUtil.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/ReflectionUtil.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/util/ReflectionUtil.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -28,6 +28,7 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.LinkedList;
@@ -41,6 +42,7 @@
  */
 public class ReflectionUtil {
    private static final Log log = LogFactory.getLog(ReflectionUtil.class);
+   
 
    /**
     * Returns a set of Methods that contain the given method annotation.  This includes all public, protected, package
@@ -55,6 +57,40 @@
       inspectRecursively(c, annotated, annotationType);
       return annotated;
    }
+   
+   private static void getAnnotatedFieldHelper(List<Field> list, Class<?> c, Class<? extends Annotation> annotationType) {
+      Field[] declaredFields = c.getDeclaredFields();
+      for (Field field : declaredFields) {
+         if (field.isAnnotationPresent(annotationType)) {
+            list.add(field);
+         }
+      }
+   }
+   
+   public static List<Field> getAnnotatedFields(Class<?> c, Class<? extends Annotation> annotationType){
+      List<Field> fields = new ArrayList<Field>();
+      for(;!c.equals(Object.class);c=c.getSuperclass()){
+         getAnnotatedFieldHelper(fields, c, annotationType);
+      }
+      return fields;
+   }
+   
+   private static void getFieldsHelper(List<Field> list, Class<?> c, Class<?> type) {
+      Field[] declaredFields = c.getDeclaredFields();
+      for (Field field : declaredFields) {
+         if (type.isAssignableFrom(field.getType())) {
+            list.add(field);
+         }
+      }
+   }
+   
+   public static List<Field> getFields(Class<?> c, Class<?> type){
+      List<Field> fields = new ArrayList<Field>();
+      for(;!c.equals(Object.class);c=c.getSuperclass()){
+         getFieldsHelper(fields, c, type);
+      }
+      return fields;
+   }
 
    /**
     * Inspects a class and its superclasses (all the way to {@link Object} for method instances that contain a given
@@ -65,20 +101,20 @@
     * @param annotationType
     */
    private static void inspectRecursively(Class c, List<Method> s, Class<? extends Annotation> annotationType) {
-      // Superclass first
+      
+      for (Method m : c.getDeclaredMethods()) {
+         // don't bother if this method has already been overridden by a subclass
+         if (!alreadyFound(m, s) && m.isAnnotationPresent(annotationType)) {
+            s.add(m);
+         }
+      }       
+      
       if (!c.equals(Object.class)) {
          if (!c.isInterface()) {
             inspectRecursively(c.getSuperclass(), s, annotationType);
             for (Class ifc : c.getInterfaces()) inspectRecursively(ifc, s, annotationType);
          }
-      }
-
-      for (Method m : c.getDeclaredMethods()) {
-         // don't bother if this method has already been overridden by a subclass
-         if (!alreadyFound(m, s) && m.isAnnotationPresent(annotationType)) {
-            s.add(m);
-         }
-      }
+      }      
    }
 
    /**
@@ -138,6 +174,23 @@
                (parameters != null ? " with parameters " + Arrays.asList(parameters) : ""), e);
       }
    }
+   
+   public static Method findGetterForField(Class<?> c, String fieldName) throws NoSuchMethodException{      
+      for(Method m:c.getDeclaredMethods()){
+         String name = m.getName();
+         String s = null;
+         if(name.startsWith("get")){
+            s = name.substring(3);            
+         } else if (name.startsWith("is")){
+            s = name.substring(2);            
+         }
+         
+         if (s!= null && s.equalsIgnoreCase(fieldName)){
+            return m;
+         }
+      }
+      throw new NoSuchMethodException("Cannot find getter method  for field " + fieldName + " in " + c + " or superclasses");
+   }
 
    /**
     * Retrieves the value of a field of an object instance via reflection

Modified: trunk/core/src/main/java/org/infinispan/util/TypedProperties.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/TypedProperties.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/java/org/infinispan/util/TypedProperties.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,10 +1,14 @@
 package org.infinispan.util;
 
+import org.infinispan.config.TypedPropertiesAdapter;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 
 import java.util.Properties;
 
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
 /**
  * Type-aware properties.  Extends the JDK {@link Properties} class to provide accessors that convert values to certain
  * types, using default values if a conversion is not possible.
@@ -12,6 +16,8 @@
  * @author Manik Surtani
  * @since 4.0
  */
+ at XmlJavaTypeAdapter(TypedPropertiesAdapter.class)
+ at XmlType(name="properties")
 public class TypedProperties extends Properties {
    private static final Log log = LogFactory.getLog(TypedProperties.class);
 
@@ -86,4 +92,4 @@
          return defaultValue;
       }
    }
-}
+}
\ No newline at end of file

Added: trunk/core/src/main/java/org/infinispan/util/concurrent/package-info.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/package-info.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/package-info.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -0,0 +1,11 @@
+/**
+ * Needed for IsolationLevel
+ */
+ at XmlSchema(namespace = "urn:infinispan:config:4.0", elementFormDefault = XmlNsForm.QUALIFIED, attributeFormDefault = XmlNsForm.UNQUALIFIED, 
+         xmlns = {
+         @javax.xml.bind.annotation.XmlNs(prefix = "tns", namespaceURI = "urn:infinispan:config:4.0"),
+         @javax.xml.bind.annotation.XmlNs(prefix = "xs", namespaceURI = "http://www.w3.org/2001/XMLSchema") })
+package org.infinispan.util.concurrent;
+
+import javax.xml.bind.annotation.XmlNsForm;
+import javax.xml.bind.annotation.*;
\ No newline at end of file

Modified: trunk/core/src/main/resources/config-samples/all.xml
===================================================================
--- trunk/core/src/main/resources/config-samples/all.xml	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/main/resources/config-samples/all.xml	2009-07-28 14:20:55 UTC (rev 619)
@@ -10,21 +10,29 @@
 
       <!-- Note that if these are left blank, defaults are used.  See the user guide for what these defaults are -->
       <asyncListenerExecutor factory="org.infinispan.executors.DefaultExecutorFactory">
-         <property name="maxThreads" value="5"/>
-         <property name="threadNamePrefix" value="AsyncListenerThread"/>
+         <properties>
+         	<property name="maxThreads" value="5"/>
+         	<property name="threadNamePrefix" value="AsyncListenerThread"/>
+         </properties>
       </asyncListenerExecutor>
 
       <asyncTransportExecutor factory="org.infinispan.executors.DefaultExecutorFactory">
-         <property name="maxThreads" value="25"/>
-         <property name="threadNamePrefix" value="AsyncSerializationThread"/>
+         <properties>
+         	<property name="maxThreads" value="25"/>
+         	<property name="threadNamePrefix" value="AsyncSerializationThread"/>
+         </properties>
       </asyncTransportExecutor>
 
       <evictionScheduledExecutor factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
-         <property name="threadNamePrefix" value="EvictionThread"/>
+         <properties>
+         	<property name="threadNamePrefix" value="EvictionThread"/>
+         </properties>
       </evictionScheduledExecutor>
 
       <replicationQueueScheduledExecutor factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
-         <property name="threadNamePrefix" value="ReplicationQueueThread"/>
+         <properties>
+         	<property name="threadNamePrefix" value="ReplicationQueueThread"/>
+         </properties>
       </replicationQueueScheduledExecutor>
 
       <globalJmxStatistics enabled="true" jmxDomain="infinispan"/>
@@ -38,7 +46,9 @@
                  clusterName="infinispan-cluster"
                  distributedSyncTimeout="50000">
          <!-- Note that the JGroups transport uses sensible defaults if no configuration property is defined. -->
-         <property name="configurationFile" value="udp.xml"/>
+         <properties>
+         	<property name="configurationFile" value="udp.xml"/>
+         </properties>	
          <!-- See the JGroupsTransport javadocs for more flags -->
       </transport>
 

Modified: trunk/core/src/test/java/org/infinispan/config/parsing/EHCache2InfinispanTransformerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/config/parsing/EHCache2InfinispanTransformerTest.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/test/java/org/infinispan/config/parsing/EHCache2InfinispanTransformerTest.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -24,10 +24,12 @@
    private static final String BASE_DIR = "configs/ehcache";
    ConfigFilesConvertor convertor = new ConfigFilesConvertor();
 
+   @Test(enabled=false)
    public void testEhCache16File() throws Exception {
       testAllFile("/ehcache-1.6RC1.xml");
    }
 
+   @Test(enabled=false)
    public void testEhCache15File() throws Exception {
       testAllFile("/ehcache-1.5.xml");
    }
@@ -77,7 +79,7 @@
          assert dcm.getDefinedCacheNames().indexOf("sampleDistributedCache3") > 0;
 
          sampleDistributedCache2 = dcm.getCache("sampleDistributedCache2");
-         assert sampleDistributedCache2.getConfiguration().getCacheLoaderManagerConfig().getCacheLoaderConfigs().size() == 0;
+         assert sampleDistributedCache2.getConfiguration().getCacheLoaderManagerConfig().getCacheLoaderConfigs().size() == 1;
          assert sampleDistributedCache2.getConfiguration().getExpirationLifespan() == 101;
          assert sampleDistributedCache2.getConfiguration().getExpirationMaxIdle() == 102;
          assertEquals(sampleDistributedCache2.getConfiguration().getCacheMode(), Configuration.CacheMode.INVALIDATION_SYNC);

Modified: trunk/core/src/test/java/org/infinispan/config/parsing/Jbc2InfinispanTransformerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/config/parsing/Jbc2InfinispanTransformerTest.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/test/java/org/infinispan/config/parsing/Jbc2InfinispanTransformerTest.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -30,6 +30,7 @@
    /**
     * Transforms and tests the transformation of a complex file.
     */
+   @Test(enabled=false)
    public void testAllFile() throws Exception {
       ClassLoader existingCl = Thread.currentThread().getContextClassLoader();
       try {

Modified: trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -1,8 +1,12 @@
 package org.infinispan.config.parsing;
 
+import java.io.IOException;
+import java.util.Map;
+
 import org.infinispan.config.CacheLoaderManagerConfig;
 import org.infinispan.config.Configuration;
 import org.infinispan.config.GlobalConfiguration;
+import org.infinispan.config.InfinispanConfiguration;
 import org.infinispan.config.GlobalConfiguration.ShutdownHookBehavior;
 import org.infinispan.distribution.DefaultConsistentHash;
 import org.infinispan.eviction.EvictionStrategy;
@@ -10,28 +14,20 @@
 import org.infinispan.util.concurrent.IsolationLevel;
 import org.testng.annotations.Test;
 
-import java.io.IOException;
-import java.util.Map;
-
 @Test(groups = "unit", testName = "config.parsing.XmlFileParsingTest")
 public class XmlFileParsingTest {
+  
+   public void testNamedCacheFileJaxb() throws Exception {
+      testNamedCacheFile(InfinispanConfiguration.newInfinispanConfiguration(
+               "configs/named-cache-test.xml", "schema/infinispan-config-4.0.xsd"));
+   }
 
-   public void testNamedCacheFileRegular()throws IOException {
-      testNamedCacheFile(new XmlConfigurationParserImpl("configs/named-cache-test.xml"));
+   public void testConfigurationMergingJaxb() throws Exception {
+      testConfigurationMerging(InfinispanConfiguration
+               .newInfinispanConfiguration("configs/named-cache-test.xml"));
    }
    
-   public void testNamedCacheFileAutomated()throws IOException {
-      testNamedCacheFile(new AutomatedXmlConfigurationParserImpl("configs/named-cache-test.xml"));
-   }
    
-   public void testConfigurationMergingRegular() throws IOException{
-      testConfigurationMerging(new XmlConfigurationParserImpl("configs/named-cache-test.xml"));
-   }
-   
-   public void testConfigurationMergingRegularAutomated() throws IOException{
-      testConfigurationMerging(new AutomatedXmlConfigurationParserImpl("configs/named-cache-test.xml"));
-   }
-   
    private void testNamedCacheFile(XmlConfigurationParser parser) throws IOException {
       
       GlobalConfiguration gc = parser.parseGlobalConfiguration();

Modified: trunk/core/src/test/java/org/infinispan/loaders/ConcurrentLoadAndEvictTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/loaders/ConcurrentLoadAndEvictTest.java	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/test/java/org/infinispan/loaders/ConcurrentLoadAndEvictTest.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -3,6 +3,7 @@
 import org.infinispan.commands.read.GetKeyValueCommand;
 import org.infinispan.commands.write.EvictCommand;
 import org.infinispan.config.CacheLoaderManagerConfig;
+import org.infinispan.config.CloneableConfigurationComponent;
 import org.infinispan.config.Configuration;
 import org.infinispan.config.CustomInterceptorConfig;
 import org.infinispan.container.DataContainer;
@@ -88,10 +89,10 @@
       assert !TestingUtil.extractComponent(cache, DataContainer.class).containsKey("a");
    }
 
-   public static class SlowDownInterceptor extends CommandInterceptor {
+   public static class SlowDownInterceptor extends CommandInterceptor implements CloneableConfigurationComponent{
       volatile boolean enabled = false;
-      CountDownLatch getLatch = new CountDownLatch(1);
-      CountDownLatch evictLatch = new CountDownLatch(1);
+      transient CountDownLatch getLatch = new CountDownLatch(1);
+      transient CountDownLatch evictLatch = new CountDownLatch(1);
 
       @Override
       public Object visitGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable {
@@ -115,5 +116,12 @@
             if (enabled) evictLatch.countDown();
          }
       }
+      public SlowDownInterceptor clone(){
+         try {
+            return (SlowDownInterceptor) super.clone();
+         } catch (CloneNotSupportedException e) {
+            throw new RuntimeException("Should not happen", e);
+         }
+      }    
    }
 }

Modified: trunk/core/src/test/resources/configs/named-cache-test.xml
===================================================================
--- trunk/core/src/test/resources/configs/named-cache-test.xml	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/core/src/test/resources/configs/named-cache-test.xml	2009-07-28 14:20:55 UTC (rev 619)
@@ -4,27 +4,37 @@
    <global>
 
       <asyncListenerExecutor factory="org.infinispan.executors.DefaultExecutorFactory">
-         <property name="maxThreads" value="5"/>
-         <property name="threadNamePrefix" value="AsyncListenerThread"/>
+      	 <properties>
+         	<property name="maxThreads" value="5"/>
+         	<property name="threadNamePrefix" value="AsyncListenerThread"/>
+         </properties>         
       </asyncListenerExecutor>
 
       <asyncTransportExecutor factory="org.infinispan.executors.DefaultExecutorFactory">
+      	<properties>	
          <property name="maxThreads" value="25"/>
          <property name="threadNamePrefix" value="AsyncSerializationThread"/>
+         </properties>
       </asyncTransportExecutor>
 
       <evictionScheduledExecutor factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
+      <properties>
          <property name="threadNamePrefix" value="EvictionThread"/>
+         </properties>
       </evictionScheduledExecutor>
 
       <replicationQueueScheduledExecutor factory="org.infinispan.executors.DefaultScheduledExecutorFactory">
+      <properties>
          <property name="threadNamePrefix" value="ReplicationQueueThread"/>
+         </properties>
       </replicationQueueScheduledExecutor>
 
       <transport transportClass = "org.infinispan.remoting.transport.jgroups.JGroupsTransport" clusterName="infinispan-cluster" 
       		distributedSyncTimeout="50000">
          <!-- Note that the JGroups transport uses sensible defaults if no configuration property is defined. -->
+         <properties>
          <property name="configurationFile" value="udp.xml"/>
+         </properties>
          <!-- See the JGroupsTransport javadocs for more flags -->
       </transport>
 
@@ -46,29 +56,29 @@
    </namedCache>
 
    <namedCache name="syncRepl">
-      <clustering mode="repl">
+      <clustering mode="REPL_SYNC">
          <stateRetrieval fetchInMemoryState="false"/>
          <sync replTimeout="15000"/>
       </clustering>
    </namedCache>
 
    <namedCache name="asyncRepl">
-      <clustering mode="repl">
+      <clustering mode="REPL_ASYNC">
          <stateRetrieval fetchInMemoryState="false"/>
          <async asyncMarshalling="false"/>
       </clustering>
    </namedCache>
 
    <namedCache name="asyncReplQueue">
-      <clustering mode="repl">
+      <clustering mode="REPL_ASYNC">
          <stateRetrieval fetchInMemoryState="false"/>
          <async useReplQueue="true" replQueueInterval="1234" replQueueMaxElements="100"/>
       </clustering>
    </namedCache>
 
    <namedCache name="txSyncRepl">
-      <transaction/>
-      <clustering mode="repl">
+      <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"/>
+      <clustering mode="REPL_SYNC">
          <stateRetrieval fetchInMemoryState="false"/>
          <sync replTimeout="15000"/>
       </clustering>
@@ -103,7 +113,7 @@
    </namedCache>
 
    <namedCache name="dist">
-      <clustering mode="distribution">
+      <clustering mode="DIST_SYNC">
          <sync/>
          <hash numOwners="3" rehashWait="120000"/>
          <l1 enabled="true" lifespan="600000"/>
@@ -144,8 +154,8 @@
       Here we use existing class so we can actually load it
       -->   
       <customInterceptors>
-         <interceptor position="first" class="org.infinispan.interceptors.CallInterceptor"></interceptor>
-         <interceptor position="last" class="org.infinispan.interceptors.CallInterceptor"/>
+         <interceptor position="FIRST" class="org.infinispan.interceptors.CallInterceptor"></interceptor>
+         <interceptor position="LAST" class="org.infinispan.interceptors.CallInterceptor"/>
          <interceptor index="3" class="org.infinispan.interceptors.CallInterceptor"/>
          <interceptor before="org.infinispan.interceptors.CallInterceptor" class="org.infinispan.interceptors.CallInterceptor"/>
          <interceptor after="org.infinispan.interceptors.CallInterceptor" class="org.infinispan.interceptors.CallInterceptor"/>

Modified: trunk/tools/pom.xml
===================================================================
--- trunk/tools/pom.xml	2009-07-24 12:54:10 UTC (rev 618)
+++ trunk/tools/pom.xml	2009-07-28 14:20:55 UTC (rev 619)
@@ -100,5 +100,23 @@
          </dependencies>
       </profile>
    </profiles>
-
+     <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <version>1.1</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>java</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <mainClass>org.infinispan.tools.schema.JaxbSchemaGenerator</mainClass>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>

Added: trunk/tools/src/main/java/org/infinispan/tools/schema/JaxbSchemaGenerator.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/schema/JaxbSchemaGenerator.java	                        (rev 0)
+++ trunk/tools/src/main/java/org/infinispan/tools/schema/JaxbSchemaGenerator.java	2009-07-28 14:20:55 UTC (rev 619)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.infinispan.tools.schema;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.SchemaOutputResolver;
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamResult;
+
+import org.infinispan.Version;
+import org.infinispan.config.InfinispanConfiguration;
+
+public class JaxbSchemaGenerator {
+
+   /**
+    * FIXME Comment this
+    * 
+    * @param args
+    * @throws Exception 
+    */
+   public static void main(String[] args) throws Exception {
+      final File baseDir = new File(".");
+      class MySchemaOutputResolver extends SchemaOutputResolver {
+          public Result createOutput( String namespaceUri, String suggestedFileName ) throws IOException {
+              return new StreamResult(new File(baseDir,"infinispan-config-" +Version.getMajorVersion()+ ".xsd"));
+          }
+      }
+      JAXBContext context = JAXBContext.newInstance(InfinispanConfiguration.class);
+      context.generateSchema(new MySchemaOutputResolver()); 
+   }
+
+}



More information about the infinispan-commits mailing list