You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2016/08/26 14:49:36 UTC

incubator-tamaya git commit: TAMAYA-171: Simplified API for Mutable configuration delegating to corresponding mutable PropertySources, controlled by policy to decie how changes get applied.

Repository: incubator-tamaya
Updated Branches:
  refs/heads/master 4e54af6c5 -> 5e16e4b20


TAMAYA-171: Simplified API for Mutable configuration delegating to corresponding mutable PropertySources, controlled by policy to decie how changes get applied.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/5e16e4b2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/5e16e4b2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/5e16e4b2

Branch: refs/heads/master
Commit: 5e16e4b205bd0663060c3c1c53f227cb2f26b509
Parents: 4e54af6
Author: anatole <an...@apache.org>
Authored: Fri Aug 26 16:49:17 2016 +0200
Committer: anatole <an...@apache.org>
Committed: Fri Aug 26 16:49:17 2016 +0200

----------------------------------------------------------------------
 .../resources/findbugs/findbugs-exclude.xml     |   2 +-
 .../tamaya/consul/ConsulPropertySource.java     |  14 +-
 .../apache/tamaya/etcd/EtcdPropertySource.java  |  15 +-
 .../mutableconfig/ChangePropagationPolicy.java  |  26 +--
 .../mutableconfig/MutableConfiguration.java     | 124 +----------
 .../MutableConfigurationProvider.java           | 174 +++++-----------
 .../internal/DefaultMutableConfiguration.java   | 203 ++-----------------
 .../DefaultMutableConfigurationSpi.java         |   6 +-
 .../AbstractMutablePropertySource.java          | 168 ---------------
 .../propertysources/ConfigChangeContext.java    | 175 ----------------
 .../MutablePropertiesPropertySource.java        |  19 +-
 .../MutableXmlPropertiesPropertySource.java     |  16 +-
 .../mutableconfig/spi/ConfigChangeRequest.java  | 176 ++++++++++++++++
 .../spi/MutableConfigurationProviderSpi.java    |   6 +-
 .../spi/MutablePropertySource.java              | 101 +--------
 .../mutableconfig/MutableConfigurationTest.java |  66 +++---
 16 files changed, 345 insertions(+), 946 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/buildconfigurations/src/main/resources/findbugs/findbugs-exclude.xml
----------------------------------------------------------------------
diff --git a/buildconfigurations/src/main/resources/findbugs/findbugs-exclude.xml b/buildconfigurations/src/main/resources/findbugs/findbugs-exclude.xml
index 14533e9..50255d9 100644
--- a/buildconfigurations/src/main/resources/findbugs/findbugs-exclude.xml
+++ b/buildconfigurations/src/main/resources/findbugs/findbugs-exclude.xml
@@ -52,7 +52,7 @@ under the License.
     </Match>
 
     <Match>
-        <Class name='org.apache.tamaya.integration.cdi.internal.TamayaCDIIntegration'/>
+        <Class name='org.apache.tamaya.integration.cdi.TamayaCDIIntegration'/>
         <Method name="initBeanManager"/>
     </Match>
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/integration/consul/src/main/java/org/apache/tamaya/consul/ConsulPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/integration/consul/src/main/java/org/apache/tamaya/consul/ConsulPropertySource.java b/modules/integration/consul/src/main/java/org/apache/tamaya/consul/ConsulPropertySource.java
index 9b61840..89c903b 100644
--- a/modules/integration/consul/src/main/java/org/apache/tamaya/consul/ConsulPropertySource.java
+++ b/modules/integration/consul/src/main/java/org/apache/tamaya/consul/ConsulPropertySource.java
@@ -18,13 +18,14 @@
  */
 package org.apache.tamaya.consul;
 
+import com.fasterxml.jackson.databind.deser.Deserializers;
 import com.google.common.base.Optional;
 import com.google.common.net.HostAndPort;
 import com.orbitz.consul.Consul;
 import com.orbitz.consul.KeyValueClient;
 import com.orbitz.consul.model.kv.Value;
-import org.apache.tamaya.mutableconfig.propertysources.AbstractMutablePropertySource;
-import org.apache.tamaya.mutableconfig.propertysources.ConfigChangeContext;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 import org.apache.tamaya.spi.PropertyValueBuilder;
 
@@ -39,7 +40,8 @@ import java.util.logging.Logger;
  * {@code consul.prefix} as system property maps the consul based onfiguration
  * to this prefix namespace. Consul servers are configured as {@code consul.urls} system or environment property.
  */
-public class ConsulPropertySource extends AbstractMutablePropertySource {
+public class ConsulPropertySource extends Deserializers.Base
+implements MutablePropertySource{
     private static final Logger LOG = Logger.getLogger(ConsulPropertySource.class.getName());
 
     private String prefix = System.getProperty("tamaya.consul.prefix", "");
@@ -165,20 +167,20 @@ public class ConsulPropertySource extends AbstractMutablePropertySource {
     }
 
     @Override
-    protected void commitInternal(ConfigChangeContext context) {
+    public void applyChange(ConfigChangeRequest configChange) {
         for(HostAndPort hostAndPort: ConsulBackends.getConsulBackends()){
             try{
                 Consul consul = Consul.builder().withHostAndPort(hostAndPort).build();
                 KeyValueClient kvClient = consul.keyValueClient();
 
-                for(String k: context.getRemovedProperties()){
+                for(String k: configChange.getRemovedProperties()){
                     try{
                         kvClient.deleteKey(k);
                     } catch(Exception e){
                         LOG.info("Failed to remove key from consul: " + k);
                     }
                 }
-                for(Map.Entry<String,String> en:context.getAddedProperties().entrySet()){
+                for(Map.Entry<String,String> en:configChange.getAddedProperties().entrySet()){
                     String key = en.getKey();
                     try{
                         kvClient.putValue(key,en.getValue());

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/integration/etcd/src/main/java/org/apache/tamaya/etcd/EtcdPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/integration/etcd/src/main/java/org/apache/tamaya/etcd/EtcdPropertySource.java b/modules/integration/etcd/src/main/java/org/apache/tamaya/etcd/EtcdPropertySource.java
index f84fd0d..5e129f7 100644
--- a/modules/integration/etcd/src/main/java/org/apache/tamaya/etcd/EtcdPropertySource.java
+++ b/modules/integration/etcd/src/main/java/org/apache/tamaya/etcd/EtcdPropertySource.java
@@ -18,10 +18,11 @@
  */
 package org.apache.tamaya.etcd;
 
-import org.apache.tamaya.mutableconfig.propertysources.AbstractMutablePropertySource;
-import org.apache.tamaya.mutableconfig.propertysources.ConfigChangeContext;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 import org.apache.tamaya.spi.PropertyValueBuilder;
+import org.apache.tamaya.spisupport.BasePropertySource;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -35,7 +36,8 @@ import java.util.logging.Logger;
  * to this prefix namespace. Etcd servers are configured as {@code etcd.server.urls} system or environment property.
  * ETcd can be disabled by setting {@code tamaya.etcdprops.disable} either as env or system property.
  */
-public class EtcdPropertySource extends AbstractMutablePropertySource{
+public class EtcdPropertySource extends BasePropertySource
+        implements MutablePropertySource{
     private static final Logger LOG = Logger.getLogger(EtcdPropertySource.class.getName());
 
     private String prefix = System.getProperty("tamaya.etcd.prefix", "");
@@ -167,16 +169,16 @@ public class EtcdPropertySource extends AbstractMutablePropertySource{
     }
 
     @Override
-    protected void commitInternal(ConfigChangeContext context) {
+    public void applyChange(ConfigChangeRequest configChange) {
         for(EtcdAccessor accessor: EtcdBackends.getEtcdBackends()){
             try{
-                for(String k: context.getRemovedProperties()){
+                for(String k: configChange.getRemovedProperties()){
                     Map<String,String> res = accessor.delete(k);
                     if(res.get("_ERROR")!=null){
                         LOG.info("Failed to remove key from etcd: " + k);
                     }
                 }
-                for(Map.Entry<String,String> en:context.getAddedProperties().entrySet()){
+                for(Map.Entry<String,String> en:configChange.getAddedProperties().entrySet()){
                     String key = en.getKey();
                     Integer ttl = null;
                     int index = en.getKey().indexOf('?');
@@ -203,4 +205,5 @@ public class EtcdPropertySource extends AbstractMutablePropertySource{
             }
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
index 350ca09..5378166 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/ChangePropagationPolicy.java
@@ -18,10 +18,10 @@
  */
 package org.apache.tamaya.mutableconfig;
 
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
 import org.apache.tamaya.spi.PropertySource;
 
 import java.util.Collection;
-import java.util.Map;
 
 /**
  * Policy that defines how changes are applied to the available
@@ -46,28 +46,8 @@ public interface ChangePropagationPolicy {
      * Method being called when a multiple key/value pairs are added or updated.
      * @param propertySources the property sources, including readable property sources of the current configuration,
      *                        never null.
-     * @param transactionID the transaction ID, not null.
-     * @param changes the key/values being added or updated, not null.
+     * @param configChange the configuration change, not null.
      */
-    void applyChanges(String transactionID, Collection<PropertySource> propertySources, Map<String,String> changes);
-
-    /**
-     * Method being called when a single key/value pair has been added or updated.
-     * @param propertySources the property sources, including readable property sources of the current configuration,
-     *                        never null.
-     * @param transactionID the transaction ID, not null.
-     * @param key the key, not null.
-     * @param value the value, not null.
-     */
-    void applyChange(String transactionID, Collection<PropertySource> propertySources, String key, String value);
-
-    /**
-     * Method being called when a multiple keys has been removed from the configuration.
-     * @param propertySources the property sources, including readable property sources of the current configuration,
-     *                        never null.
-     * @param transactionID the transaction ID, not null.
-     * @param keys the keys being removed, not null.
-     */
-    void applyRemove(String transactionID, Collection<PropertySource> propertySources, String... keys);
+    void applyChange(ConfigChangeRequest configChange, Collection<PropertySource> propertySources);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
index 90b0673..451769e 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfiguration.java
@@ -19,11 +19,9 @@
 package org.apache.tamaya.mutableconfig;
 
 import org.apache.tamaya.Configuration;
-import org.apache.tamaya.mutableconfig.propertysources.ConfigChangeContext;
-import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
 
 import java.util.Collection;
-import java.util.List;
 import java.util.Map;
 
 
@@ -44,16 +42,7 @@ import java.util.Map;
 public interface MutableConfiguration extends Configuration {
 
     /**
-     * Starts a new transaction, if necessary, and returns the transaction id. New transaction are, similar to Java EE,
-     * bound to the current thread. As a consequences all properties added , updated or removed must be managed by
-     * a corresponding context, isolated by thread. The {@link MutablePropertySource} get the right transaction id
-     * passed, when writing (committing) any changes applied.
-     * @return the transaction id, not null.
-     */
-    String startTransaction();
-
-    /**
-     * Commits the request. After a commit the change is not editable anymore. All changes applied will be written to
+     * Storesd the changes. After a commit the change is not editable anymore. All changes applied will be written to
      * the corresponding configuration backend.
      *
      * NOTE that changes applied must not necessarily be visible in the current {@link Configuration} instance,
@@ -61,117 +50,22 @@ public interface MutableConfiguration extends Configuration {
      * configured.
      * @throws org.apache.tamaya.ConfigException if the request already has been committed or cancelled, or the commit fails.
      */
-    void commitTransaction();
-
-    /**
-     * Rollback any changes leaving everything unchanged. This will rollback all changes applied since the last commit.
-     */
-    void rollbackTransaction();
-
-    /**
-     * Get the current transaction id.
-     * @return the current transaction id, or null, if no transaction is active.
-     */
-    String getTransactionId();
-
-    /**
-     * Get the current autoCommit policy. AutoCommit will commit the transaction after each change applied.
-     * @return the current autoCommit policy, by default false.
-     */
-    boolean getAutoCommit();
-
-    /**
-     * Set the {@link ChangePropagationPolicy}.
-     * @see #getChangePropagationPolicy()
-     * @param changePropagationPolicy the policy, not null.
-     */
-    void setChangePropagationPolicy(ChangePropagationPolicy changePropagationPolicy);
-
-    /**
-     * Access the active {@link ChangePropagationPolicy}.This policy controls how configuration changes are written/published
-     * to the known {@link MutablePropertySource} instances of a {@link Configuration}.
-     * @return he active {@link ChangePropagationPolicy}, never null.
-     */
-    ChangePropagationPolicy getChangePropagationPolicy();
+    void store();
 
     /**
      * Access the current configuration change context, built up on all the change context of the participating
-     * {@link MutablePropertySource} instances.
+     * {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource} instances.
      * @return the colleted changes as one single config change for the current transaction, or null, if no transaction
      * is active.
      */
-    ConfigChangeContext getConfigChangeContext();
-
-    /**
-     * Set the autoCommit policy to be used for this configuration instance.
-     * @param autoCommit the new autoCommit policy.
-     * @throws IllegalStateException when there are uncommitted changes.
-     */
-    void setAutoCommit(boolean autoCommit);
-
-
-    /**
-     * Identifies the configuration backend that are targeted by this instance and which are
-     * also responsible for writing back the changes applied.
-     *
-     * @return the property sources identified, in order of their occurrence/priority (most significant first).
-     */
-    List<MutablePropertySource> getMutablePropertySources();
+    ConfigChangeRequest getConfigChangeRequest();
 
     /**
-     * Checks if a configuration key is writable (or it can be added).
-     *
-     * @param keyExpression the key to be checked for write access (including creation), not null. Here this could also
-     *                      be a regular expression, such "as a.b.c.*".
-     * @return the boolean
-     */
-    boolean isWritable(String keyExpression);
-
-    /**
-     * Identifies the configuration backends that supports writing the given key(s).
-     * @param keyExpression the key to be checked for write access (including creation), not null. Here this could also
-     *                      be a regular expression, such "as a.b.c.*".
-     * @return the property sources identified, in order of their occurrence/priority (most significant first).
-     */
-    List<MutablePropertySource> getPropertySourcesThatCanWrite(String keyExpression);
-
-    /**
-     * Checks if a configuration key is removable. This also implies that it is writable, but there might be writable
-     * keys that cannot be removedProperties.
-     *
-     * @param keyExpression the keyExpression the key to be checked for write access (including creation), not null.
-     *                      Here this could also
-     *                      be a regular expression, such "as a.b.c.*".
-     * @return the boolean
-     */
-    boolean isRemovable(String keyExpression);
-
-    /**
-     * Identifies the configuration backend that know the given key(s) and support removing it/them.
-     * @param keyExpression the key to be checked for write access (including creation), not null. Here this could also
-     *                      be a regular expression, such "as a.b.c.*".
-     * @return the property sources identified, in order of their occurrence/priority (most significant first).
-     */
-    List<MutablePropertySource> getPropertySourcesThatCanRemove(String keyExpression);
-
-    /**
-     * Checks if any keys of the given type already exist in the write backend. <b>NOTE:</b> there may be backends that
-     * are not able to support lookups with regular expressions. In most such cases you should pass the keys to
-     * lookup explicitly.
-     *
-     * @param keyExpression the key to be checked for write access (including creation), not null. Here this could
-     *                      also be a regular expression, such "as a.b.c.*".
-     * @return true, if there is any key found matching the expression.
-     */
-    boolean isExisting(String keyExpression);
-
-    /**
-     * Identifies the configuration backend that know the given key(s).
-     * @param keyExpression the key to be checked for write access (including creation), not null. Here this could also
-     *                      be a regular expression, such "as a.b.c.*".
-     * @return the property sources identified, in order of their occurrence/priority (most significant first).
+     * Access the active {@link ChangePropagationPolicy}.This policy controls how configuration changes are written/published
+     * to the known {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource} instances of a {@link Configuration}.
+     * @return he active {@link ChangePropagationPolicy}, never null.
      */
-    List<MutablePropertySource> getPropertySourcesThatKnow(String keyExpression);
+    ChangePropagationPolicy getChangePropagationPolicy();
 
     /**
      * Sets a property.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
index 98c918b..1a54b44 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/MutableConfigurationProvider.java
@@ -21,6 +21,7 @@ package org.apache.tamaya.mutableconfig;
 import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.Configuration;
 import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
 import org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi;
 import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
 import org.apache.tamaya.spi.PropertySource;
@@ -29,7 +30,6 @@ import org.apache.tamaya.spi.ServiceContextManager;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 import java.util.logging.Logger;
 
@@ -70,22 +70,46 @@ public final class MutableConfigurationProvider {
      *
      * @return a new MutableConfiguration instance
      */
-    public static MutableConfiguration getMutableConfiguration(){
+    public static MutableConfiguration createMutableConfiguration(){
         return mutableConfigurationProviderSpi.createMutableConfiguration(
-                ConfigurationProvider.getConfiguration());
+                ConfigurationProvider.getConfiguration(), getApplyMostSignificantOnlyChangePolicy());
+    }
+
+    /**
+     * Creates a new {@link MutableConfiguration} for the given default configuration, using all
+     * {@link MutablePropertySource} instances found in its context and {@code autoCommit = false}.
+     * @param changePropgationPolicy policy that defines how a change is written back and which property
+     *                               sources are finally eligible for a write operation.
+     * @return a new MutableConfiguration instance, with the given change policy active.
+     */
+    public static MutableConfiguration createMutableConfiguration(ChangePropagationPolicy changePropgationPolicy){
+        return mutableConfigurationProviderSpi.createMutableConfiguration(
+                ConfigurationProvider.getConfiguration(), changePropgationPolicy);
     }
 
 
     /**
      * Creates a new {@link MutableConfiguration} for the given configuration, using all
-     * {@link MutablePropertySource} instances found in its context and {@code autoCommit = false}.
+     * {@link MutablePropertySource} instances found in its context and {@code MOST_SIGNIFICANT_ONLY_POLICY}
+     * configuration writing policy.
      *
+     * @param configuration the configuration to use to write the changes/config.
+     * @return a new MutableConfiguration instance
+     */
+    public static MutableConfiguration createMutableConfiguration(Configuration configuration){
+        return createMutableConfiguration(configuration, MOST_SIGNIFICANT_ONLY_POLICY);
+    }
+
+    /**
+     * Creates a new {@link MutableConfiguration} for the given configuration, using all
+     * {@link MutablePropertySource} instances found in its context and {@code ALL_POLICY}
+     * configuration writing policy.
      *
      * @param configuration the configuration to use to write the changes/config.
      * @return a new MutableConfiguration instance
      */
-    public static MutableConfiguration getMutableConfiguration(Configuration configuration){
-        return mutableConfigurationProviderSpi.createMutableConfiguration(configuration);
+    public static MutableConfiguration createMutableConfiguration(Configuration configuration, ChangePropagationPolicy changePropgationPolicy){
+        return mutableConfigurationProviderSpi.createMutableConfiguration(configuration, changePropgationPolicy);
     }
 
     /**
@@ -130,47 +154,20 @@ public final class MutableConfigurationProvider {
      */
     private static final ChangePropagationPolicy ALL_POLICY = new ChangePropagationPolicy() {
         @Override
-        public void applyChanges(String transactionID, Collection<PropertySource> propertySources,
-                                 Map<String, String> changes) {
-            for(PropertySource propertySource: propertySources){
-                if(propertySource instanceof MutablePropertySource){
-                    MutablePropertySource target = (MutablePropertySource)propertySource;
-                    for(Map.Entry<String,String> en:changes.entrySet()) {
-                        if (target.isWritable(en.getKey())) {
-                            target.put(transactionID, en.getKey(), en.getValue());
-                        }
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void applyChange(String transactionID, Collection<PropertySource> propertySources,
-                                String key, String value) {
+        public void applyChange(ConfigChangeRequest change, Collection<PropertySource> propertySources) {
             for(PropertySource propertySource: propertySources){
                 if(propertySource instanceof MutablePropertySource){
                     MutablePropertySource target = (MutablePropertySource)propertySource;
-                    if (target.isWritable(key)) {
-                        target.put(transactionID, key, value);
+                    try{
+                        target.applyChange(change);
+                    }catch(ConfigException e){
+                        LOG.warning("Failed to store changes '"+change+"' not applicable to "+target.getName()
+                        +"("+target.getClass().getName()+").");
                     }
                 }
             }
         }
 
-        @Override
-        public void applyRemove(String transactionID, Collection<PropertySource> propertySources,
-                                String... keys) {
-            for(PropertySource propertySource: propertySources){
-                if(propertySource instanceof MutablePropertySource){
-                    MutablePropertySource target = (MutablePropertySource)propertySource;
-                    for(String key:keys) {
-                        if (target.isRemovable(key)) {
-                            target.remove(transactionID, key);
-                        }
-                    }
-                }
-            }
-        }
     };
 
     /**
@@ -179,50 +176,21 @@ public final class MutableConfigurationProvider {
      */
     private static final ChangePropagationPolicy MOST_SIGNIFICANT_ONLY_POLICY = new ChangePropagationPolicy() {
         @Override
-        public void applyChanges(String transactionID, Collection<PropertySource> propertySources,
-                                 Map<String, String> changes) {
-            changes:for(Map.Entry<String,String> en:changes.entrySet()) {
-                for(PropertySource propertySource: propertySources){
-                    if(propertySource instanceof MutablePropertySource){
-                        MutablePropertySource target = (MutablePropertySource)propertySource;
-                        if (target.isWritable(en.getKey())) {
-                            target.put(transactionID, en.getKey(), en.getValue());
-                            continue changes;
-                        }
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void applyChange(String transactionID, Collection<PropertySource> propertySources,
-                                String key, String value) {
+        public void applyChange(ConfigChangeRequest change, Collection<PropertySource> propertySources) {
             for(PropertySource propertySource: propertySources){
                 if(propertySource instanceof MutablePropertySource){
                     MutablePropertySource target = (MutablePropertySource)propertySource;
-                    if (target.isWritable(key)) {
-                        target.put(transactionID, key, value);
-                        return;
+                    try{
+                        target.applyChange(change);
+                    }catch(ConfigException e){
+                        LOG.warning("Failed to store changes '"+change+"' not applicable to "+target.getName()
+                                +"("+target.getClass().getName()+").");
                     }
+                    break;
                 }
             }
         }
 
-        @Override
-        public void applyRemove(String transactionID, Collection<PropertySource> propertySources,
-                                String... keys) {
-            keys:for(String key:keys) {
-                for(PropertySource propertySource: propertySources){
-                    if(propertySource instanceof MutablePropertySource){
-                        MutablePropertySource target = (MutablePropertySource)propertySource;
-                        if (target.isRemovable(key)) {
-                            target.remove(transactionID, key);
-                            continue keys;
-                        }
-                    }
-                }
-            }
-        }
     };
 
     /**
@@ -231,15 +199,8 @@ public final class MutableConfigurationProvider {
      */
     private static final ChangePropagationPolicy NONE_POLICY = new ChangePropagationPolicy() {
         @Override
-        public void applyChanges(String transactionID, Collection<PropertySource> propertySources, Map<String, String> changes) {
-        }
-
-        @Override
-        public void applyChange(String transactionID, Collection<PropertySource> propertySources, String key, String value) {
-        }
-
-        @Override
-        public void applyRemove(String transactionID, Collection<PropertySource> propertySources, String... keys) {
+        public void applyChange(ConfigChangeRequest change, Collection<PropertySource> propertySources) {
+            LOG.warning("Cannot store changes '"+change+"': prohibited by change policy (read-only).");
         }
     };
 
@@ -255,49 +216,18 @@ public final class MutableConfigurationProvider {
         }
 
         @Override
-        public void applyChanges(String transactionID, Collection<PropertySource> propertySources,
-                                 Map<String, String> changes) {
-            for(PropertySource propertySource: propertySources){
-                if(propertySource instanceof MutablePropertySource){
-                    if(this.propertySourceNames.contains(propertySource.getName())) {
-                        MutablePropertySource target = (MutablePropertySource) propertySource;
-                        for (Map.Entry<String, String> en : changes.entrySet()) {
-                            if (target.isWritable(en.getKey())) {
-                                target.put(transactionID, en.getKey(), en.getValue());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void applyChange(String transactionID, Collection<PropertySource> propertySources,
-                                String key, String value) {
-            for(PropertySource propertySource: propertySources){
-                if(propertySource instanceof MutablePropertySource){
-                    if(this.propertySourceNames.contains(propertySource.getName())) {
-                        MutablePropertySource target = (MutablePropertySource) propertySource;
-                        if (target.isWritable(key)) {
-                            target.put(transactionID, key, value);
-                        }
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void applyRemove(String transactionID, Collection<PropertySource> propertySources,
-                                String... keys) {
+        public void applyChange(ConfigChangeRequest change, Collection<PropertySource> propertySources) {
             for(PropertySource propertySource: propertySources){
                 if(propertySource instanceof MutablePropertySource){
                     if(this.propertySourceNames.contains(propertySource.getName())) {
                         MutablePropertySource target = (MutablePropertySource) propertySource;
-                        for (String key : keys) {
-                            if (target.isRemovable(key)) {
-                                target.remove(transactionID, key);
-                            }
+                        try{
+                            target.applyChange(change);
+                        }catch(ConfigException e){
+                            LOG.warning("Failed to store changes '"+change+"' not applicable to "+target.getName()
+                                    +"("+target.getClass().getName()+").");
                         }
+                        break;
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
index bf75bae..ad272ef 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfiguration.java
@@ -24,13 +24,13 @@ import org.apache.tamaya.Configuration;
 import org.apache.tamaya.TypeLiteral;
 import org.apache.tamaya.mutableconfig.ChangePropagationPolicy;
 import org.apache.tamaya.mutableconfig.MutableConfiguration;
-import org.apache.tamaya.mutableconfig.MutableConfigurationProvider;
-import org.apache.tamaya.mutableconfig.propertysources.ConfigChangeContext;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
 import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
 import org.apache.tamaya.spi.ConfigurationContext;
 import org.apache.tamaya.spi.PropertySource;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -44,19 +44,12 @@ import java.util.logging.Logger;
  */
 public class DefaultMutableConfiguration implements MutableConfiguration {
     private static final Logger LOG = Logger.getLogger(DefaultMutableConfiguration.class.getName());
+    private ConfigChangeRequest changeRequest = new ConfigChangeRequest(UUID.randomUUID().toString());
     private final Configuration config;
-    private ChangePropagationPolicy changePropagationPolicy =
-            MutableConfigurationProvider.getApplyAllChangePolicy();
-    private String transactionId;
-    private boolean autoCommit = false;
+    private ChangePropagationPolicy changePropagationPolicy;
 
-    public DefaultMutableConfiguration(Configuration config){
+    public DefaultMutableConfiguration(Configuration config, ChangePropagationPolicy changePropagationPolicy){
         this.config = Objects.requireNonNull(config);
-        this.autoCommit = false;
-    }
-
-    @Override
-    public void setChangePropagationPolicy(ChangePropagationPolicy changePropagationPolicy){
         this.changePropagationPolicy = Objects.requireNonNull(changePropagationPolicy);
     }
 
@@ -66,47 +59,11 @@ public class DefaultMutableConfiguration implements MutableConfiguration {
     }
 
     @Override
-    public void setAutoCommit(boolean autoCommit) {
-        if(transactionId!=null){
-            throw new IllegalStateException("Cannot change autoCommit within a transaction, perform a " +
-                    "commit or rollback first.");
-        }
-        this.autoCommit = autoCommit;
-    }
-
-    @Override
-    public String getTransactionId() {
-        return transactionId;
-    }
-
-    @Override
-    public ConfigChangeContext getConfigChangeContext(){
-        if(this.transactionId==null){
-            return null;
-        }
-        ConfigChangeContext context = new ConfigChangeContext(this.transactionId);
-        long startedAt = Long.MAX_VALUE;
-        for(MutablePropertySource mps:getMutablePropertySources()){
-            ConfigChangeContext subContext = mps.getConfigChangeContext(this.transactionId);
-            if(subContext!=null){
-                context.putAll(subContext.getAddedProperties());
-                context.removeAll(subContext.getRemovedProperties());
-                if(subContext.getStartedAt()<startedAt){
-                    startedAt = subContext.getStartedAt();
-                }
-            }
-        }
-        context.setStartedAt(startedAt);
-        return context;
+    public ConfigChangeRequest getConfigChangeRequest(){
+        return changeRequest;
     }
 
-    @Override
-    public boolean getAutoCommit() {
-        return autoCommit;
-    }
-
-    @Override
-    public List<MutablePropertySource> getMutablePropertySources() {
+    protected List<MutablePropertySource> getMutablePropertySources() {
         List<MutablePropertySource> result = new ArrayList<>();
         for(PropertySource propertySource:this.config.getContext().getPropertySources()) {
             if(propertySource instanceof  MutablePropertySource){
@@ -116,164 +73,35 @@ public class DefaultMutableConfiguration implements MutableConfiguration {
         return result;
     }
 
-    @Override
-    public boolean isWritable(String keyExpression) {
-        for(MutablePropertySource target:getMutablePropertySources()) {
-            if( target.isWritable(keyExpression)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public List<MutablePropertySource> getPropertySourcesThatCanWrite(String keyExpression) {
-        List<MutablePropertySource> result = new ArrayList<>();
-        for(MutablePropertySource propertySource:getMutablePropertySources()) {
-            if(propertySource.isWritable(keyExpression)){
-                result.add(propertySource);
-            }
-        }
-        return result;
-    }
-
-    @Override
-        public boolean isRemovable(String keyExpression) {
-            for(MutablePropertySource target:getMutablePropertySources()) {
-                if( target.isRemovable(keyExpression)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-    @Override
-    public List<MutablePropertySource> getPropertySourcesThatCanRemove(String keyExpression) {
-        List<MutablePropertySource> result = new ArrayList<>();
-        for(MutablePropertySource propertySource:getMutablePropertySources()) {
-            if(propertySource.isRemovable(keyExpression)){
-                result.add(propertySource);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public boolean isExisting(String keyExpression) {
-        return this.config.get(keyExpression)!=null;
-    }
-
-    @Override
-    public List<MutablePropertySource> getPropertySourcesThatKnow(String keyExpression) {
-        List<MutablePropertySource> result = new ArrayList<>();
-        for(MutablePropertySource propertySource:getMutablePropertySources()) {
-            if(propertySource.get(keyExpression)!=null){
-                result.add(propertySource);
-            }
-        }
-        return result;
-    }
 
     @Override
     public MutableConfiguration put(String key, String value) {
-        String taID = startTransaction();
-        changePropagationPolicy.applyChange(taID, getPropertySources(), key, value);
-        if(autoCommit){
-            commitTransaction();
-        }
+        changeRequest.put(key, value);
         return this;
     }
 
     @Override
     public MutableConfiguration putAll(Map<String, String> properties) {
-        String taID = startTransaction();
-        changePropagationPolicy.applyChanges(taID, getPropertySources(), properties);
-        if(autoCommit){
-            commitTransaction();
-        }
+        changeRequest.putAll(properties);
         return this;
     }
 
     @Override
     public MutableConfiguration remove(String... keys) {
-        String taID = startTransaction();
-        changePropagationPolicy.applyRemove(taID, getPropertySources(), keys);
-        for(String key:keys){
-            for(MutablePropertySource target:getMutablePropertySources()) {
-                if (target.isRemovable(key)) {
-                    target.remove(taID, key);
-                }
-            }
-        }
-        if(autoCommit){
-            commitTransaction();
-        }
+        changeRequest.removeAll(Arrays.asList(keys));
         return this;
     }
 
-    @Override
-    public String startTransaction() {
-        String taID = transactionId;
-        if(taID!=null){
-            return taID;
-        }
-        taID = UUID.randomUUID().toString();
-        transactionId = taID;
-        try {
-            for (MutablePropertySource target : getMutablePropertySources()) {
-                target.startTransaction(taID);
-            }
-        }catch(Exception e){
-            rollbackTransaction();
-        }
-        return taID;
-    }
-
-    @Override
-    public void commitTransaction() {
-        String taID = transactionId;
-        if(taID==null){
-            LOG.warning("No active transaction on this thread, ignoring commit.");
-            return;
-        }
-        try {
-            for (MutablePropertySource target : getMutablePropertySources()) {
-                target.commitTransaction(taID);
-            }
-            this.transactionId = null;
-        }catch(Exception e){
-            rollbackTransaction();
-        }
-    }
 
     @Override
-    public void rollbackTransaction() {
-        String taID = transactionId;
-        if(taID==null){
-            LOG.warning("No active transaction on this thread, ignoring rollback.");
-            return;
-        }
-        try {
-            for (MutablePropertySource target : getMutablePropertySources()) {
-                target.rollbackTransaction(taID);
-            }
-        }finally{
-            this.transactionId = null;
-        }
+    public void store() {
+        this.changePropagationPolicy.applyChange(changeRequest, config.getContext().getPropertySources());
     }
 
     @Override
     public MutableConfiguration remove(Collection<String> keys) {
-        String taID = startTransaction();
-        for(String key:keys){
-            for(MutablePropertySource target:getMutablePropertySources()) {
-                if (target.isRemovable(key)) {
-                    target.remove(taID, key);
-                }
-            }
-        }
-        if(autoCommit){
-            commitTransaction();
+        for(MutablePropertySource target:getMutablePropertySources()) {
+            changeRequest.removeAll(keys);
         }
         return this;
     }
@@ -336,7 +164,6 @@ public class DefaultMutableConfiguration implements MutableConfiguration {
     public String toString() {
         return "DefaultMutableConfiguration{" +
                 "config=" + config +
-                ", autoCommit=" + autoCommit +
                 '}';
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
index af52024..a47cd0e 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/internal/DefaultMutableConfigurationSpi.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.mutableconfig.internal;
 
 import org.apache.tamaya.Configuration;
+import org.apache.tamaya.mutableconfig.ChangePropagationPolicy;
 import org.apache.tamaya.mutableconfig.MutableConfiguration;
 import org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi;
 
@@ -30,7 +31,8 @@ import org.apache.tamaya.mutableconfig.spi.MutableConfigurationProviderSpi;
 public class DefaultMutableConfigurationSpi implements MutableConfigurationProviderSpi {
 
     @Override
-    public MutableConfiguration createMutableConfiguration(Configuration configuration) {
-        return new DefaultMutableConfiguration(configuration);
+    public MutableConfiguration createMutableConfiguration(Configuration configuration,
+                                                    ChangePropagationPolicy propagationPolicy){
+        return new DefaultMutableConfiguration(configuration, propagationPolicy);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/AbstractMutablePropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/AbstractMutablePropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/AbstractMutablePropertySource.java
deleted file mode 100644
index 8133ab4..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/AbstractMutablePropertySource.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig.propertysources;
-
-import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
-import org.apache.tamaya.spisupport.BasePropertySource;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Base class for implementing a {@link MutablePropertySource}.
- */
-public abstract class AbstractMutablePropertySource extends BasePropertySource
-        implements MutablePropertySource {
-
-    /**
-     * Map with the curren transactions, identified by transactionId.
-     */
-    protected final Map<String, ConfigChangeContext> transactions = new ConcurrentHashMap<>();
-
-    /**
-     * Constructor udsing zero' as default ordinal.
-     */
-    protected AbstractMutablePropertySource(){
-        super();
-    }
-
-    /**
-     * Constructor allow to pass the default ordinal to be used.
-     * @param defaultOrdinal the default ordinal.
-     */
-    protected AbstractMutablePropertySource(int defaultOrdinal){
-        super(defaultOrdinal);
-    }
-
-    /**
-     * Get a list with property keys removed within the given transaction.
-     * @param transactionId the transaction id, not null.
-     * @return the removed property keys, never null.
-     */
-    protected final Set<String> getRemovedProperties(String transactionId) {
-        ConfigChangeContext ctx = this.transactions.get(transactionId);
-        if(ctx!=null) {
-            return ctx.getRemovedProperties();
-        }
-        return Collections.emptySet();
-    }
-
-    /**
-     * Get a list with property keys added within the given transaction.
-     * @param transactionId the transaction id, not null.
-     * @return the added property keys, never null.
-     */
-    protected final Map<String,String> getAddedProperties(String transactionId) {
-        ConfigChangeContext ctx = this.transactions.get(transactionId);
-        if(ctx!=null) {
-            return ctx.getAddedProperties();
-        }
-        return Collections.emptyMap();
-    }
-
-    @Override
-    public boolean isWritable(String keyExpression) {
-        return true;
-    }
-
-    @Override
-    public boolean isRemovable(String keyExpression) {
-        return true;
-    }
-
-    @Override
-    public final MutablePropertySource put(String transactionId, String key, String value) {
-        ConfigChangeContext ctx = this.transactions.get(transactionId);
-        if(ctx==null) {
-            throw new IllegalStateException("No such transaction: " + transactionId);
-        }
-        ctx.put(key, value);
-        return this;
-    }
-
-    @Override
-    public final MutablePropertySource putAll(String transactionId, Map<String, String> properties) {
-        ConfigChangeContext ctx = this.transactions.get(transactionId);
-        if(ctx==null) {
-            throw new IllegalStateException("No such transaction: " + transactionId);
-        }
-        ctx.putAll(properties);
-        return this;
-    }
-
-    @Override
-    public final MutablePropertySource remove(String transactionId, String... keys) {
-        ConfigChangeContext ctx = this.transactions.get(transactionId);
-        if(ctx==null) {
-            throw new IllegalStateException("No such transaction: " + transactionId);
-        }
-        ctx.removeAll(Arrays.asList(keys));
-        return this;
-    }
-
-    @Override
-    public final MutablePropertySource remove(String transactionId, Collection<String> keys) {
-        ConfigChangeContext ctx = this.transactions.get(transactionId);
-        if(ctx==null) {
-            throw new IllegalStateException("No such transaction: " + transactionId);
-        }
-        ctx.removeAll(keys);
-        return this;
-    }
-
-    @Override
-    public final void startTransaction(String transactionId) {
-        ConfigChangeContext ctx = this.transactions.get(transactionId);
-        if(ctx==null) {
-            this.transactions.put(transactionId, new ConfigChangeContext(transactionId));
-        }
-    }
-
-    @Override
-    public final void commitTransaction(String transactionId) {
-        ConfigChangeContext ctx = this.transactions.remove(transactionId);
-        if(ctx==null) {
-            throw new IllegalStateException("No such transaction: " + transactionId);
-        }
-        commitInternal(ctx);
-    }
-
-
-    /**
-     * Commit of the changes to the current property source. This is the last chance to get changes written back to the
-     * property source. On return the transactional context will be removed.
-     * @param context The configuration change to be committed/applied.
-     */
-    protected abstract void commitInternal(ConfigChangeContext context);
-
-    @Override
-    public final void rollbackTransaction(String transactionId) {
-        this.transactions.remove(transactionId);
-    }
-
-    @Override
-    public ConfigChangeContext getConfigChangeContext(String transactionID){
-        return this.transactions.get(transactionID);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/ConfigChangeContext.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/ConfigChangeContext.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/ConfigChangeContext.java
deleted file mode 100644
index b0f46f1..0000000
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/ConfigChangeContext.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.mutableconfig.propertysources;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Transactional context used for managing configuration changes within an {@link AbstractMutablePropertySource}.
- */
-public final class ConfigChangeContext {
-    /**
-     * The transaction id.
-     */
-    private String transactionId;
-    /**
-     * The starting point.
-     */
-    private long startedAt = System.currentTimeMillis();
-    /**
-     * The Properties.
-     */
-    private final Map<String,String> addedProperties = new HashMap<>();
-    /**
-     * The Removed.
-     */
-    private final Set<String> removedProperties = new HashSet<>();
-
-    /**
-     * Creates a new instance bound to the given transaction.
-     * @param transactionID the transaction ID, not null.
-     */
-    public ConfigChangeContext(String transactionID){
-        this.transactionId = Objects.requireNonNull(transactionID);
-    }
-
-    /**
-     * Sets the started at value. By default {@link #startedAt} is already set on instance creation to
-     * {@code System.currentTimeMillis()}.
-     * @param startedAt the new UTC POSIX timestamp in millis.
-     */
-    public void setStartedAt(long startedAt) {
-        this.startedAt = startedAt;
-    }
-
-    /**
-     * Get the corresppnding transaction ID of this instance.
-     * @return the transaction ID, never null.
-     */
-    public String getTransactionID(){
-        return transactionId;
-    }
-
-    /**
-     * Timestamp in UTC millis, when this transaction (context) was created.
-     * @return the timestamp in millis.
-     */
-    public long getStartedAt(){
-        return startedAt;
-    }
-
-    /**
-     * Get an unmodifiable key/value map of properties added or updated.
-     * @return an unmodifiable key/value map of properties added or updated, never null.
-     */
-    public Map<String,String> getAddedProperties(){
-        return Collections.unmodifiableMap(addedProperties);
-    }
-
-    /**
-     * Get an unmodifiable key set of properties removed.
-     * @return an unmodifiable key set of properties removed, never null.
-     */
-    public Set<String> getRemovedProperties(){
-        return Collections.unmodifiableSet(removedProperties);
-    }
-
-    /**
-     * Adds/updates a new key/value pair.
-     * @param key the key, not null.
-     * @param value the value, not null.
-     */
-    public void put(String key, String value) {
-        this.addedProperties.put(key, value);
-        this.removedProperties.remove(key);
-    }
-
-    /**
-     * Add/updated multiple key/values.
-     * @param properties the keys and values to be added/updated, not null.
-     */
-    public void putAll(Map<String, String> properties) {
-        this.addedProperties.putAll(properties);
-        this.removedProperties.removeAll(properties.keySet());
-    }
-
-    /**
-     * Remove all the given keys, ir present.
-     * @param key the key to be removed, not null.
-     */
-    public void remove(String key) {
-        this.removedProperties.add(key);
-        this.addedProperties.remove(key);
-    }
-
-    /**
-     * Remove all the given keys, ir present.
-     * @param keys the keys to be removed, not null.
-     */
-    public void removeAll(Collection<String> keys) {
-        this.removedProperties.addAll(keys);
-        for(String k:keys) {
-            this.addedProperties.remove(k);
-        }
-    }
-
-    /**
-     * Allows easily to check if no additions/changes an no removals are present in the current transaction.
-     * @return true, if not actions have to be committed.
-     */
-    public boolean isEmpty() {
-        return this.addedProperties.isEmpty() && this.removedProperties.isEmpty();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof ConfigChangeContext)) {
-            return false;
-        }
-        ConfigChangeContext that = (ConfigChangeContext) o;
-        return transactionId.equals(that.transactionId);
-
-    }
-
-    @Override
-    public int hashCode() {
-        return transactionId.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return "TransactionContext{" +
-                "addedProperties=" + addedProperties +
-                ", transactionId=" + transactionId +
-                ", startedAt=" + startedAt +
-                ", removedProperties=" + removedProperties +
-                '}';
-    }
-
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java
index a4105c7..af9bed4 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutablePropertiesPropertySource.java
@@ -19,8 +19,11 @@
 package org.apache.tamaya.mutableconfig.propertysources;
 
 import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 import org.apache.tamaya.spi.PropertyValueBuilder;
+import org.apache.tamaya.spisupport.BasePropertySource;
 
 import java.io.BufferedOutputStream;
 import java.io.File;
@@ -39,12 +42,14 @@ import java.util.logging.Logger;
 /**
  * Simple implementation of a mutable {@link org.apache.tamaya.spi.PropertySource} for .properties files.
  */
-public class MutablePropertiesPropertySource extends AbstractMutablePropertySource {
+public class MutablePropertiesPropertySource extends BasePropertySource
+implements MutablePropertySource{
 
     /**
      * The logger.
      */
     private static final Logger LOG = Logger.getLogger(MutablePropertiesPropertySource.class.getName());
+
     /**
      * Default update interval is 1 minute.
      */
@@ -92,8 +97,6 @@ public class MutablePropertiesPropertySource extends AbstractMutablePropertySour
         }
     }
 
-
-
     @Override
     public PropertyValue get(String key) {
         Map<String,String> properties = getProperties();
@@ -151,9 +154,9 @@ public class MutablePropertiesPropertySource extends AbstractMutablePropertySour
     }
 
     @Override
-    protected void commitInternal(ConfigChangeContext context) {
-        if(context.isEmpty()){
-            LOG.info("Nothing to commit for transaction: " + context.getTransactionID());
+    public void applyChange(ConfigChangeRequest change) {
+        if(change.isEmpty()){
+            LOG.info("Nothing to commit for transaction: " + change.getTransactionID());
             return;
         }
         if(!file.exists()){
@@ -165,7 +168,7 @@ public class MutablePropertiesPropertySource extends AbstractMutablePropertySour
                 throw new ConfigException("Failed to create config file " + file, e);
             }
         }
-        for(Map.Entry<String,String> en:context.getAddedProperties().entrySet()){
+        for(Map.Entry<String,String> en:change.getAddedProperties().entrySet()){
             int index = en.getKey().indexOf('?');
             if(index>0){
                 this.properties.put(en.getKey().substring(0, index), en.getValue());
@@ -173,7 +176,7 @@ public class MutablePropertiesPropertySource extends AbstractMutablePropertySour
                 this.properties.put(en.getKey(), en.getValue());
             }
         }
-        for(String rmKey:context.getRemovedProperties()){
+        for(String rmKey:change.getRemovedProperties()){
             this.properties.remove(rmKey);
         }
         try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))){

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java
index 9049340..514ed1d 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/propertysources/MutableXmlPropertiesPropertySource.java
@@ -19,8 +19,11 @@
 package org.apache.tamaya.mutableconfig.propertysources;
 
 import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.mutableconfig.spi.ConfigChangeRequest;
+import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
 import org.apache.tamaya.spi.PropertyValue;
 import org.apache.tamaya.spi.PropertyValueBuilder;
+import org.apache.tamaya.spisupport.BasePropertySource;
 
 import java.io.BufferedOutputStream;
 import java.io.File;
@@ -39,7 +42,8 @@ import java.util.logging.Logger;
 /**
  * Simple implementation of a mutable {@link org.apache.tamaya.spi.PropertySource} for .xml properties files.
  */
-public class MutableXmlPropertiesPropertySource extends AbstractMutablePropertySource {
+public class MutableXmlPropertiesPropertySource extends BasePropertySource
+implements MutablePropertySource{
 
     /**
      * The logger.
@@ -152,9 +156,9 @@ public class MutableXmlPropertiesPropertySource extends AbstractMutablePropertyS
     }
 
     @Override
-    protected void commitInternal(ConfigChangeContext context) {
-        if(context.isEmpty()){
-            LOG.info("Nothing to commit for transaction: " + context.getTransactionID());
+    public void applyChange(ConfigChangeRequest configChange) {
+        if(configChange.isEmpty()){
+            LOG.info("Nothing to commit for transaction: " + configChange.getTransactionID());
             return;
         }
         if(!file.exists()){
@@ -166,7 +170,7 @@ public class MutableXmlPropertiesPropertySource extends AbstractMutablePropertyS
                 throw new ConfigException("Failed to create config file " + file, e);
             }
         }
-        for(Map.Entry<String,String> en:context.getAddedProperties().entrySet()){
+        for(Map.Entry<String,String> en:configChange.getAddedProperties().entrySet()){
             int index = en.getKey().indexOf('?');
             if(index>0){
                 this.properties.put(en.getKey().substring(0, index), en.getValue());
@@ -174,7 +178,7 @@ public class MutableXmlPropertiesPropertySource extends AbstractMutablePropertyS
                 this.properties.put(en.getKey(), en.getValue());
             }
         }
-        for(String rmKey:context.getRemovedProperties()){
+        for(String rmKey:configChange.getRemovedProperties()){
             this.properties.remove(rmKey);
         }
         try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))){

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/ConfigChangeRequest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/ConfigChangeRequest.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/ConfigChangeRequest.java
new file mode 100644
index 0000000..2349ad1
--- /dev/null
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/ConfigChangeRequest.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.mutableconfig.spi;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Change context used for managing configuration changes within an
+ * {@link org.apache.tamaya.mutableconfig.spi.MutablePropertySource}.
+ */
+public final class ConfigChangeRequest {
+    /**
+     * The transaction id.
+     */
+    private String transactionId;
+    /**
+     * The starting point.
+     */
+    private long startedAt = System.currentTimeMillis();
+    /**
+     * The Properties.
+     */
+    private final Map<String,String> addedProperties = new HashMap<>();
+    /**
+     * The Removed.
+     */
+    private final Set<String> removedProperties = new HashSet<>();
+
+    /**
+     * Creates a new instance bound to the given transaction.
+     * @param transactionID the transaction ID, not null.
+     */
+    public ConfigChangeRequest(String transactionID){
+        this.transactionId = Objects.requireNonNull(transactionID);
+    }
+
+    /**
+     * Sets the started at value. By default {@link #startedAt} is already set on instance creation to
+     * {@code System.currentTimeMillis()}.
+     * @param startedAt the new UTC POSIX timestamp in millis.
+     */
+    public void setStartedAt(long startedAt) {
+        this.startedAt = startedAt;
+    }
+
+    /**
+     * Get the corresppnding transaction ID of this instance.
+     * @return the transaction ID, never null.
+     */
+    public String getTransactionID(){
+        return transactionId;
+    }
+
+    /**
+     * Timestamp in UTC millis, when this transaction (context) was created.
+     * @return the timestamp in millis.
+     */
+    public long getStartedAt(){
+        return startedAt;
+    }
+
+    /**
+     * Get an unmodifiable key/value map of properties added or updated.
+     * @return an unmodifiable key/value map of properties added or updated, never null.
+     */
+    public Map<String,String> getAddedProperties(){
+        return Collections.unmodifiableMap(addedProperties);
+    }
+
+    /**
+     * Get an unmodifiable key set of properties removed.
+     * @return an unmodifiable key set of properties removed, never null.
+     */
+    public Set<String> getRemovedProperties(){
+        return Collections.unmodifiableSet(removedProperties);
+    }
+
+    /**
+     * Adds/updates a new key/value pair.
+     * @param key the key, not null.
+     * @param value the value, not null.
+     */
+    public void put(String key, String value) {
+        this.addedProperties.put(key, value);
+        this.removedProperties.remove(key);
+    }
+
+    /**
+     * Add/updated multiple key/values.
+     * @param properties the keys and values to be added/updated, not null.
+     */
+    public void putAll(Map<String, String> properties) {
+        this.addedProperties.putAll(properties);
+        this.removedProperties.removeAll(properties.keySet());
+    }
+
+    /**
+     * Remove all the given keys, ir present.
+     * @param key the key to be removed, not null.
+     */
+    public void remove(String key) {
+        this.removedProperties.add(key);
+        this.addedProperties.remove(key);
+    }
+
+    /**
+     * Remove all the given keys, ir present.
+     * @param keys the keys to be removed, not null.
+     */
+    public void removeAll(Collection<String> keys) {
+        this.removedProperties.addAll(keys);
+        for(String k:keys) {
+            this.addedProperties.remove(k);
+        }
+    }
+
+    /**
+     * Allows easily to check if no additions/changes an no removals are present in the current transaction.
+     * @return true, if not actions have to be committed.
+     */
+    public boolean isEmpty() {
+        return this.addedProperties.isEmpty() && this.removedProperties.isEmpty();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof ConfigChangeRequest)) {
+            return false;
+        }
+        ConfigChangeRequest that = (ConfigChangeRequest) o;
+        return transactionId.equals(that.transactionId);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return transactionId.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "ConfigChangeRequest{" +
+                "transactionId=" + transactionId +
+                ", startedAt=" + startedAt +
+                ", addedProperties=" + addedProperties +
+                ", removedProperties=" + removedProperties +
+                '}';
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java
index 15ba655..4412085 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutableConfigurationProviderSpi.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.mutableconfig.spi;
 
 import org.apache.tamaya.Configuration;
+import org.apache.tamaya.mutableconfig.ChangePropagationPolicy;
 import org.apache.tamaya.mutableconfig.MutableConfiguration;
 
 
@@ -32,7 +33,10 @@ public interface MutableConfigurationProviderSpi {
     * Creates a new {@link MutableConfiguration} with {@code autoCommit = false} as default.
     *
     * @param configuration the configuration, not null.
+    * @param propagationPolicy policy that defines how changes are published to the property
+    *                          sources.
     * @return a new mutable configuration instance.
     */
-   MutableConfiguration createMutableConfiguration(Configuration configuration);
+   MutableConfiguration createMutableConfiguration(Configuration configuration,
+                                                   ChangePropagationPolicy propagationPolicy);
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java
index 8b2e097..b648341 100644
--- a/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java
+++ b/modules/mutable-config/src/main/java/org/apache/tamaya/mutableconfig/spi/MutablePropertySource.java
@@ -18,12 +18,8 @@
  */
 package org.apache.tamaya.mutableconfig.spi;
 
-import org.apache.tamaya.mutableconfig.propertysources.ConfigChangeContext;
 import org.apache.tamaya.spi.PropertySource;
 
-import java.util.Collection;
-import java.util.Map;
-
 
 /**
  * This interface models a writable backend for configuration data.
@@ -34,35 +30,6 @@ import java.util.Map;
 public interface MutablePropertySource extends PropertySource {
 
     /**
-     * Checks if a configuration key is writable (or it can be added).
-     *
-     * @param key the key to be checked for write access (including creation), not null.
-     * @return true if the key can be added or updated.
-     */
-    boolean isWritable(String key);
-
-    /**
-     * Checks if a configuration key is removable. This also implies that it is writable, but there might be writable
-     * keys that cannot be removedProperties.
-     *
-     * @param key the key to be checked for removal, not null.
-     * @return true, if the key can be removed.
-     */
-    boolean isRemovable(String key);
-
-    /**
-     * Sets a property.
-     *
-     * @param key   the property's key, not null.
-     * @param value the property's value, not null.
-     * @param transactionId the transactionId used to isolate the change, not null.
-     * @return this instance for optional chaining of operations, nrvrt null.
-     * @throws org.apache.tamaya.ConfigException if the key/value cannot be added, or the request is read-only.
-     */
-    MutablePropertySource put(String transactionId, String key, String value);
-
-
-    /**
      * Puts all given configuration entries. This method should check that all given properties are
      * basically removable, as defined by #isWritable. If any of the passed keys is not writable during this initial
      * check, the operation should not perform any configuration changes and throw a {@link org.apache.tamaya.ConfigException}. If errors
@@ -70,71 +37,11 @@ public interface MutablePropertySource extends PropertySource {
      * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
      * remove all entries as far as possible and abort the writing operation.
      *
-     * @param transactionId the transactionId used to isolate the change, not null.
-     * @param properties the properties tobe written, not null.
-     * @return this instance for optional chaining of operations, nrvrt null.
+     * @param configChange the {@link ConfigChangeRequest}, containing the transactionId used to isolate
+     *                     the change, the properties to be added/overridden and the property keys
+     *                     being removed.
      * @throws org.apache.tamaya.ConfigException if any of the given properties could not be written, or the request is read-only.
      */
-    MutablePropertySource putAll(String transactionId, Map<String, String> properties);
-
-    /**
-     * Removes all given configuration entries. This method should check that all given properties are
-     * basically removable, as defined by #isRemovable. If any of the passed keys is not removable during this initial
-     * check, the operation should not perform any configuration changes and throw a {@link org.apache.tamaya.ConfigException}. If errors
-     * occur afterwards, when the properties are effectively written back to the backends, the errors should be
-     * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
-     * remove all entries as far as possible and abort the writing operation.
-     *
-     * @param transactionId the transactionId used to isolate the change, not null.
-     * @param keys the property's keys to be removedProperties, not null.
-     * @return this instance for optional chaining of operations, nrvrt null.
-     * @throws org.apache.tamaya.ConfigException if any of the given keys could not be removedProperties, or the request is read-only.
-     */
-    MutablePropertySource remove(String transactionId, Collection<String> keys);
+    void applyChange(ConfigChangeRequest configChange);
 
-    /**
-     * Removes all given configuration entries. This method should check that all given properties are
-     * basically removable, as defined by #isRemovable. If any of the passed keys is not removable during this initial
-     * check, the operation should not perform any configuration changes and throw a {@link org.apache.tamaya.ConfigException}. If errors
-     * occur afterwards, when the properties are effectively written back to the backends, the errors should be
-     * collected and returned as part of the ConfigException payload. Nevertheless the operation should in that case
-     * remove all entries as far as possible and abort the writing operation.
-     *
-     * @param transactionId the transactionId used to isolate the change, not null.
-     * @param keys the property's keys to be removedProperties, not null.
-     * @return this instance for optional chaining of operations, nrvrt null.
-     * @throws org.apache.tamaya.ConfigException if any of the given keys could not be removedProperties, or the request is read-only.
-     */
-    MutablePropertySource remove(String transactionId, String... keys);
-
-    /**
-     * Commits the request. After a commit the change is not editable anymore. All changes applied will be written to
-     * the corresponding configuration backend.
-     *
-     * NOTE that changes applied must not necessarily be visible in the current {@link org.apache.tamaya.Configuration} instance,
-     * since visibility of changes also depends on the ordinals set on the {@link org.apache.tamaya.spi.PropertySource}s
-     * configured.
-     * @throws org.apache.tamaya.ConfigException if the request already has been committed or cancelled, or the commit fails.
-     * @param transactionId the transaction id, not null.
-     */
-    void commitTransaction(String transactionId);
-
-    /**
-     * Rollback any changes leaving everything unchanged. This will rollback all changes applied since the last commit.
-     * @param transactionId the transaction id, not null.
-     */
-    void rollbackTransaction(String transactionId);
-
-    /**
-     * Start a new transaction context with the given isolation policy.
-     * @param transactionId the transaction id, not null.
-     */
-    void startTransaction(String transactionId);
-
-    /**
-     * Get the transactional context for the given transaction ID.
-     * @param transactionID the transaction ID, not null.
-     * @return the transactional context, or null, if no such cointext is present.
-     */
-    ConfigChangeContext getConfigChangeContext(String transactionID);
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/5e16e4b2/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java
----------------------------------------------------------------------
diff --git a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java
index e873471..814f3ce 100644
--- a/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java
+++ b/modules/mutable-config/src/test/java/org/apache/tamaya/mutableconfig/MutableConfigurationTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tamaya.mutableconfig;
 
+import org.apache.tamaya.Configuration;
 import org.apache.tamaya.ConfigurationProvider;
 import org.apache.tamaya.mutableconfig.internal.WritablePropertiesSource;
 import org.apache.tamaya.mutableconfig.internal.WritableXmlPropertiesSource;
@@ -44,16 +45,17 @@ public class MutableConfigurationTest {
     @Test
     public void testCreateMutableConfiguration() throws Exception {
         File f = File.createTempFile("ConfigChangeRequest",".properties");
-        MutableConfiguration cfg1 = MutableConfigurationProvider.getMutableConfiguration(
-                ConfigurationProvider.getConfiguration());
+        MutableConfiguration cfg1 = MutableConfigurationProvider.createMutableConfiguration(
+                ConfigurationProvider.getConfiguration(),
+                MutableConfigurationProvider.getApplyAllChangePolicy());
         assertNotNull(cfg1);
-        assertNull(cfg1.getTransactionId());
-        assertFalse(cfg1.getAutoCommit());
-        assertEquals(2, cfg1.getMutablePropertySources().size());
-        MutableConfiguration cfg2 = MutableConfigurationProvider.getMutableConfiguration(
+        assertNotNull(cfg1.getConfigChangeRequest());
+        MutableConfiguration cfg2 = MutableConfigurationProvider.createMutableConfiguration(
                 ConfigurationProvider.getConfiguration());
         assertNotNull(cfg2);
-        assert(cfg1!=cfg2);
+        assertNotNull(cfg2.getConfigChangeRequest());
+        assertTrue(cfg1!=cfg2);
+        assertTrue(cfg1.getConfigChangeRequest()!=cfg2.getConfigChangeRequest());
     }
 
     /**
@@ -62,9 +64,20 @@ public class MutableConfigurationTest {
      * @throws Exception the exception
      */
     @Test(expected=NullPointerException.class)
-    public void testNullCreateMutableConfiguration() throws Exception {
-        MutableConfiguration cfg = MutableConfigurationProvider.getMutableConfiguration(
-                null);
+    public void testNullCreateMutableConfiguration1() throws Exception {
+        MutableConfigurationProvider.createMutableConfiguration(
+                (Configuration) null);
+    }
+
+    /**
+     * Test null create change request.
+     *
+     * @throws Exception the exception
+     */
+    @Test(expected=NullPointerException.class)
+    public void testNullCreateMutableConfiguration2() throws Exception {
+        MutableConfigurationProvider.createMutableConfiguration(
+                (ChangePropagationPolicy) null);
     }
 
     /**
@@ -75,15 +88,13 @@ public class MutableConfigurationTest {
     @Test
     public void testReadWriteProperties_WithCancel() throws IOException {
         WritablePropertiesSource.target.delete();
-        MutableConfiguration mutConfig = MutableConfigurationProvider.getMutableConfiguration(
+        MutableConfiguration mutConfig = MutableConfigurationProvider.createMutableConfiguration(
                 ConfigurationProvider.getConfiguration()
         );
         mutConfig.put("key1", "value1");
         Map<String,String> cm = new HashMap<>();
         cm.put("key2", "value2");
         cm.put("key3", "value3");
-        mutConfig.rollbackTransaction();
-        assertFalse(WritablePropertiesSource.target.exists());
     }
 
     /**
@@ -94,7 +105,7 @@ public class MutableConfigurationTest {
     @Test
     public void testReadWriteProperties_WithCommit() throws IOException {
         WritablePropertiesSource.target.delete();
-        MutableConfiguration mutConfig = MutableConfigurationProvider.getMutableConfiguration(
+        MutableConfiguration mutConfig = MutableConfigurationProvider.createMutableConfiguration(
                 ConfigurationProvider.getConfiguration()
         );
         mutConfig.put("key1", "value1");
@@ -102,16 +113,16 @@ public class MutableConfigurationTest {
         cm.put("key2", "value2");
         cm.put("key3", "value3");
         mutConfig.putAll(cm);
-        mutConfig.commitTransaction();
+        mutConfig.store();
         assertTrue(WritablePropertiesSource.target.exists());
-        MutableConfiguration mmutConfig2 = MutableConfigurationProvider.getMutableConfiguration(
+        MutableConfiguration mmutConfig2 = MutableConfigurationProvider.createMutableConfiguration(
                 ConfigurationProvider.getConfiguration()
         );
         mmutConfig2.remove("foo");
         mmutConfig2.remove("key3");
         mmutConfig2.put("key1", "value1.2");
         mmutConfig2.put("key4", "value4");
-        mmutConfig2.commitTransaction();
+        mmutConfig2.store();
         Properties props = new Properties();
         props.load(WritablePropertiesSource.target.toURL().openStream());
         assertEquals(3, props.size());
@@ -128,29 +139,28 @@ public class MutableConfigurationTest {
     @Test
     public void testReadWriteXmlProperties_WithCommit() throws IOException {
         WritableXmlPropertiesSource.target.delete();
-        MutableConfiguration cfg = MutableConfigurationProvider.getMutableConfiguration(
-                ConfigurationProvider.getConfiguration());
+        MutableConfiguration cfg = MutableConfigurationProvider.createMutableConfiguration(
+                ConfigurationProvider.getConfiguration(), MutableConfigurationProvider.getApplyAllChangePolicy());
         cfg.put("key1", "value1");
         Map<String,String> cm = new HashMap<>();
         cm.put("key2", "value2");
         cm.put("key3", "value3");
         cfg.putAll(cm);
-        cfg.commitTransaction();
+        cfg.store();
         assertTrue(WritableXmlPropertiesSource.target.exists());
-        MutableConfiguration cfg2 = MutableConfigurationProvider.getMutableConfiguration(
+        MutableConfiguration cfg2 = MutableConfigurationProvider.createMutableConfiguration(
                 ConfigurationProvider.getConfiguration());
         assertTrue(cfg != cfg2);
         cfg2.remove("foo");
         cfg2.remove("key3");
         cfg2.put("key1", "value1.2");
         cfg2.put("key4", "value4");
-        cfg2.commitTransaction();
+        cfg2.store();
         Properties props = new Properties();
         props.loadFromXML( WritableXmlPropertiesSource.target.toURL().openStream());
         assertEquals(3, props.size());
-        assertEquals("value1.2", props.getProperty("key1"));
+        assertEquals("value1", props.getProperty("key1"));
         assertEquals("value2", props.getProperty("key2"));
-        assertEquals("value4", props.getProperty("key4"));
     }
 
     /**
@@ -161,15 +171,15 @@ public class MutableConfigurationTest {
     @Test
     public void testWriteWithNoChangePolicy() throws IOException {
         WritableXmlPropertiesSource.target.delete();
-        MutableConfiguration cfg = MutableConfigurationProvider.getMutableConfiguration(
-                ConfigurationProvider.getConfiguration());
-        cfg.setChangePropagationPolicy(MutableConfigurationProvider.getApplyNonePolicy());
+        MutableConfiguration cfg = MutableConfigurationProvider.createMutableConfiguration(
+                ConfigurationProvider.getConfiguration(),
+                MutableConfigurationProvider.getApplyNonePolicy());
         cfg.put("key1", "value1");
         Map<String,String> cm = new HashMap<>();
         cm.put("key2", "value2");
         cm.put("key3", "value3");
         cfg.putAll(cm);
-        cfg.commitTransaction();
+        cfg.store();
         assertFalse(WritableXmlPropertiesSource.target.exists());
     }