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 2014/12/13 01:41:06 UTC

[4/4] incubator-tamaya git commit: TAMAYA-3: - Renamed PropertyProvider to PropertySource. - Factored out PropertyProviderBuilder (now to PropertySourceBuilder) into core implemntation (was API). - Removed SPI in favor of harcoded PropertySourceFactory.

TAMAYA-3:
- Renamed PropertyProvider to PropertySource.
- Factored out PropertyProviderBuilder (now to PropertySourceBuilder) into core implemntation (was API).
- Removed SPI in favor of harcoded PropertySourceFactory.


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

Branch: refs/heads/master
Commit: 80bce9ec9971724336288c66b334cf0eb23edeed
Parents: ff1f591
Author: anatole <an...@apache.org>
Authored: Sat Dec 13 01:40:54 2014 +0100
Committer: anatole <an...@apache.org>
Committed: Sat Dec 13 01:40:54 2014 +0100

----------------------------------------------------------------------
 NOTICE                                          |  13 +-
 .../org/apache/tamaya/AggregationPolicy.java    |  58 +-
 .../java/org/apache/tamaya/ConfigChangeSet.java |   8 +-
 .../apache/tamaya/ConfigChangeSetBuilder.java   |  14 +-
 .../java/org/apache/tamaya/Configuration.java   |  52 +-
 .../org/apache/tamaya/ConfigurationManager.java |  31 +-
 .../org/apache/tamaya/PropertyProvider.java     | 161 -----
 .../apache/tamaya/PropertyProviderBuilder.java  | 587 -------------------
 .../java/org/apache/tamaya/PropertySource.java  | 185 ++++++
 .../tamaya/annotation/ConfigChangeListener.java |  37 --
 .../tamaya/annotation/ObservesConfigChange.java |  38 ++
 .../spi/ConfigurationManagerSingletonSpi.java   |  28 +-
 .../tamaya/spi/PropertyProviderBuilderSpi.java  | 206 -------
 .../tamaya/TestConfigServiceSingletonSpi.java   |  17 +
 .../core/config/AbstractConfiguration.java      |  48 +-
 .../tamaya/core/config/ConfigFunctions.java     |   6 +-
 .../core/config/FreezedConfiguration.java       |   5 +-
 ...DefaultConfigurationManagerSingletonSpi.java | 101 +++-
 .../config/EnvPropertiesConfigProvider.java     |   9 +-
 .../tamaya/core/internal/config/Store.java      |  98 ++++
 .../config/SystemPropertiesConfigProvider.java  |   9 +-
 .../config/WeakConfigListenerManager.java       |   2 -
 .../inject/ConfiguredInstancesManager.java      |   4 +-
 .../core/internal/inject/ConfiguredType.java    |   2 +-
 .../properties/ClasspathPropertyProvider.java   | 150 -----
 .../resources/AntPathClasspathsResolver.java    |  56 --
 .../resources/AntPathFilesResolver.java         |  62 --
 .../AbstractClasspathAwarePropertySource.java   |  86 +++
 .../properties/AbstractPropertyProvider.java    | 111 ----
 .../core/properties/AbstractPropertySource.java | 111 ++++
 .../properties/AbstractResourceConfigMap.java   |  86 ---
 .../properties/AggregatedPropertySource.java    | 122 ++++
 .../properties/BuildablePropertySource.java     |  66 +++
 .../properties/ContextualPropertySource.java    | 177 ++++++
 .../DefaultPropertyProviderManager.java         |  79 ---
 .../properties/DelegatingPropertySource.java    | 108 ++++
 .../properties/EnvironmentPropertySource.java   |  43 ++
 .../properties/FileSystemPropertyProvider.java  |  97 ---
 .../properties/FileSystemPropertySource.java    |  97 +++
 .../core/properties/FilteredPropertySource.java |  74 +++
 .../core/properties/FreezedPropertySource.java  |  98 ++++
 .../properties/IntersectingPropertySource.java  |  71 +++
 .../core/properties/MapBasedPropertySource.java | 106 ++++
 .../properties/PathBasedPropertySource.java     |  85 +++
 .../properties/PropertyProviderManager.java     |  74 ---
 .../core/properties/PropertySourceBuilder.java  | 549 +++++++++++++++++
 .../core/properties/PropertySourceFactory.java  | 281 +++++++++
 .../properties/ReplacingPropertySource.java     | 113 ++++
 .../apache/tamaya/core/properties/Store.java    |  98 ----
 .../properties/SubtractingPropertySource.java   |  78 +++
 .../SystemPropertiesPropertySource.java         |  57 ++
 .../core/properties/URLBasedPropertySource.java |  86 +++
 .../tamaya/core/spi/ConfigurationFormat.java    |   2 +-
 .../core/spi/ConfigurationProviderSpi.java      |   5 +
 ...e.tamaya.core.spi.PropertyProviderBuilderSpi |  19 +
 ...apache.tamaya.spi.PropertyProviderBuilderSpi |  19 -
 .../java/org/apache/tamaya/JavaOneDemo.java     |   9 +-
 .../tamaya/core/config/MutableConfigTest.java   |   2 +-
 .../properties/PropertyProviderBuilderTest.java |  54 --
 .../properties/PropertySourceBuilderTest.java   |  52 ++
 .../internal/MutableTestConfigProvider.java     |  10 +-
 .../tamaya/internal/TestConfigProvider.java     |   9 +-
 .../samples/annotations/ConfiguredClass.java    |   4 +-
 .../simple/SimplePropertiesAndCLISample.java    |   8 +-
 .../apache/tamaya/ucs/UC1ReadProperties.java    |  33 +-
 .../apache/tamaya/ucs/UC2CombineProperties.java |  19 +-
 .../java/metamodel/ext/cdi/ConfiguredClass.java |   4 +-
 67 files changed, 3145 insertions(+), 2044 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index 716885f..6010bed 100644
--- a/NOTICE
+++ b/NOTICE
@@ -2,11 +2,12 @@ Apache Tamaya
 Copyright 2014 The Apache Software Foundation.
 
 Initial Contributors:
-Anatole Tresch (atsticks at gmail dot com)
-Werner Keil (werner dot keil at gmail dot com)
-Otávio Goncalves de Santana (otaviopolianasantana at gmail dot com)
-Juven Xu (juvenshun at gmail dot com)
+- Anatole Tresch (atsticks at gmail dot com)
+- Werner Keil (werner dot keil at gmail dot com)
+- Otávio Goncalves de Santana (otaviopolianasantana at gmail dot com)
+- Juven Xu (juvenshun at gmail dot com)
 
 This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-The Spring Framework (http://spring.io/projects).
+- Anatole Tresch (http://github.com/atsticks)
+- The Apache Software Foundation (http://www.apache.org/).
+- The Spring Framework (http://spring.io/projects).

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/AggregationPolicy.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/AggregationPolicy.java b/api/src/main/java/org/apache/tamaya/AggregationPolicy.java
index f7eb420..67d644e 100644
--- a/api/src/main/java/org/apache/tamaya/AggregationPolicy.java
+++ b/api/src/main/java/org/apache/tamaya/AggregationPolicy.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tamaya;
 
+import java.util.logging.Logger;
+
 /**
  * Policy that defines how the different aggregates should be combined.
  */
@@ -41,7 +43,7 @@ public interface AggregationPolicy {
     /**
      * Interpret later keys as override (additive and override), replacing
      * the key loaded earlier/fromMap previous contained
-     * {@link org.apache.tamaya.PropertyProvider}.
+     * {@link PropertySource}.
      */
     public static final AggregationPolicy OVERRIDE = (k, v1, v2) -> v2;
 
@@ -56,4 +58,58 @@ public interface AggregationPolicy {
             }
             return newValue;
         };
+
+    /**
+     * Ignores any duplicates, but logs the conflict encountered to error/severe level.
+     */
+    public static final AggregationPolicy LOG_ERROR =
+            (String key, String value, String newValue) -> {
+                if(value!=null && newValue!=null && !value.equals(newValue)){
+                    Logger.getLogger(AggregationPolicy.class.getName())
+                            .severe(() -> "Conflicting values encountered key=" + key + ", value=" + value + ", newValue=" + newValue);
+                    return value;
+                }
+                return newValue;
+            };
+
+    /**
+     * Ignores any duplicates, but logs the conflict encountered to info level.
+     */
+    public static final AggregationPolicy LOG_WARNING =
+            (String key, String value, String newValue) -> {
+                if(value!=null && newValue!=null && !value.equals(newValue)){
+                    Logger.getLogger(AggregationPolicy.class.getName())
+                            .warning(() -> "Conflicting values encountered key=" + key + ", value=" + value + ", newValue=" + newValue);
+                    return value;
+                }
+                return newValue;
+            };
+
+    /**
+     * Ignores any duplicates, but logs the conflict encountered to info level.
+     */
+    public static final AggregationPolicy LOG_INFO =
+        (String key, String value, String newValue) -> {
+            if(value!=null && newValue!=null && !value.equals(newValue)){
+                Logger.getLogger(AggregationPolicy.class.getName())
+                        .info(() -> "Conflicting values encountered key=" + key + ", value=" + value + ", newValue=" + newValue);
+                return value;
+            }
+            return newValue;
+        };
+
+    /**
+     * Ignores any duplicates, but logs the conflict encountered to debug/finest level.
+     */
+    public static final AggregationPolicy LOG_DEBUG =
+            (String key, String value, String newValue) -> {
+                if(value!=null && newValue!=null && !value.equals(newValue)){
+                    Logger.getLogger(AggregationPolicy.class.getName())
+                            .finest(() -> "Conflicting values encountered key=" + key + ", value=" + value + ", newValue=" + newValue);
+                    return value;
+                }
+                return newValue;
+            };
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java b/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java
index 0a00036..7beab65 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigChangeSet.java
@@ -30,7 +30,7 @@ import java.util.*;
  */
 public final class ConfigChangeSet {
     /** The base property provider/configuration. */
-    private PropertyProvider propertyProvider;
+    private PropertySource propertyProvider;
     /** The base version, usable for optimistic locking. */
     private String baseVersion;
     /** The recorded changes. */
@@ -41,7 +41,7 @@ public final class ConfigChangeSet {
      * @param propertyProvider The base property provider/configuration, not null.
      * @return an empty ConfigChangeSet instance.
      */
-    public static final ConfigChangeSet emptyChangeSet(PropertyProvider propertyProvider){
+    public static final ConfigChangeSet emptyChangeSet(PropertySource propertyProvider){
         return new ConfigChangeSet(propertyProvider, "<empty>", Collections.emptySet());
     }
 
@@ -51,7 +51,7 @@ public final class ConfigChangeSet {
      * @param baseVersion The base version, usable for optimistic locking.
      * @param changes The recorded changes, not null.
      */
-    ConfigChangeSet(PropertyProvider propertyProvider, String baseVersion, Collection<PropertyChangeEvent> changes) {
+    ConfigChangeSet(PropertySource propertyProvider, String baseVersion, Collection<PropertyChangeEvent> changes) {
         this.propertyProvider = Objects.requireNonNull(propertyProvider);
         this.baseVersion = baseVersion;
         changes.forEach((c) -> this.changes.put(c.getPropertyName(), c));
@@ -61,7 +61,7 @@ public final class ConfigChangeSet {
      * Get the underlying property provider/configuration.
      * @return the underlying property provider/configuration, never null.
      */
-    public PropertyProvider getPropertyProvider(){
+    public PropertySource getPropertySource(){
         return this.propertyProvider;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java b/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
index a38a99b..55ea27c 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
@@ -24,7 +24,7 @@ import java.util.*;
 
 /**
  * Models a set current changes to be applied to a configuration/property provider.  Such a set can be applied
- * to any {@link PropertyProvider} instance. If the provider is mutable it may check the
+ * to any {@link PropertySource} instance. If the provider is mutable it may check the
  * version given and apply the changes to the provider/configuration, including triggering current regarding
  * change events.
  *
@@ -34,7 +34,7 @@ public final class ConfigChangeSetBuilder {
     /** The recorded changes. */
     final SortedMap<String, PropertyChangeEvent> delta = new TreeMap<>();
     /** The underlying configuration/provider. */
-    PropertyProvider source;
+    PropertySource source;
     /** The base version, if any. Used for optimistic version checking. */
     String baseVersion;
 
@@ -43,7 +43,7 @@ public final class ConfigChangeSetBuilder {
      * @param source the underlying configuration/provider, not null.
      * @param baseVersion the base version, used for optimistic version checking.
      */
-    private ConfigChangeSetBuilder(PropertyProvider source, String baseVersion) {
+    private ConfigChangeSetBuilder(PropertySource source, String baseVersion) {
         Objects.requireNonNull(source);
         this.source = source;
         this.baseVersion= baseVersion;
@@ -54,7 +54,7 @@ public final class ConfigChangeSetBuilder {
      * @param source the underlying property provider/configuration, not null.
      * @return the builder for chaining.
      */
-    public static ConfigChangeSetBuilder of(PropertyProvider source) {
+    public static ConfigChangeSetBuilder of(PropertySource source) {
         return new ConfigChangeSetBuilder(source, Instant.now().toString());
     }
 
@@ -64,7 +64,7 @@ public final class ConfigChangeSetBuilder {
      * @param baseVersion the base version to be used.
      * @return the builder for chaining.
      */
-    public static ConfigChangeSetBuilder of(PropertyProvider source, String baseVersion) {
+    public static ConfigChangeSetBuilder of(PropertySource source, String baseVersion) {
         return new ConfigChangeSetBuilder(source, baseVersion);
     }
 
@@ -94,7 +94,7 @@ public final class ConfigChangeSetBuilder {
      * @param newState the new target state, not null.
      * @return the builder for chaining.
      */
-    public ConfigChangeSetBuilder addChanges(PropertyProvider newState) {
+    public ConfigChangeSetBuilder addChanges(PropertySource newState) {
         compare(newState, this.source).forEach((c) -> this.delta.put(c.getPropertyName(), c));
         return this;
     }
@@ -297,7 +297,7 @@ public final class ConfigChangeSetBuilder {
      * @param map2 the target map, not null.
      * @return a collection current change events, never null.
      */
-    public static Collection<PropertyChangeEvent> compare(PropertyProvider map1, PropertyProvider map2) {
+    public static Collection<PropertyChangeEvent> compare(PropertySource map1, PropertySource map2) {
         List<PropertyChangeEvent> changes = new ArrayList<>();
 
         for (Map.Entry<String, String> en : map1.toMap().entrySet()) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/Configuration.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/Configuration.java b/api/src/main/java/org/apache/tamaya/Configuration.java
index 7b5b146..70fab89 100644
--- a/api/src/main/java/org/apache/tamaya/Configuration.java
+++ b/api/src/main/java/org/apache/tamaya/Configuration.java
@@ -20,16 +20,16 @@ package org.apache.tamaya;
 
 import com.sun.javafx.scene.control.behavior.OptionalBoolean;
 
-import java.beans.PropertyChangeListener;
 import java.util.*;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 import java.util.stream.Collectors;
 
 /**
  * A configuration models a aggregated set current properties, identified by a unique key, but adds higher level access functions to
- * a {@link PropertyProvider}. Hereby in most cases a configuration is a wrapper around a composite
- * {@link PropertyProvider} instance, which may combine multiple child config in well defined tree like structure,
+ * a {@link PropertySource}. Hereby in most cases a configuration is a wrapper around a composite
+ * {@link PropertySource} instance, which may combine multiple child config in well defined tree like structure,
  * where nodes define logically the rules current priority, filtering, combination and overriding.
  * <br/>
  * <h3>Implementation Requirements</h3>
@@ -43,7 +43,7 @@ import java.util.stream.Collectors;
  * simplifying the development current this interface, e.g. for being backed up by systems and stores that are not part current
  * this library at all.
  */
-public interface Configuration extends PropertyProvider{
+public interface Configuration extends PropertySource {
 
     /**
      * Get the property value as {@link Boolean}.
@@ -258,21 +258,6 @@ public interface Configuration extends PropertyProvider{
      */
     default String getVersion(){return "N/A";}
 
-    /**
-     * Add a ConfigChangeListener to this configuration instance.
-     * @param l the listener, not null.
-     */
-    default void addPropertyChangeListener(PropertyChangeListener l){
-        throw new UnsupportedOperationException("Change listeners not supported by default.");
-    }
-
-    /**
-     * Removes a ConfigChangeListener to this configuration instance.
-     * @param l the listener, not null.
-     */
-    default void removePropertyChangeListener(PropertyChangeListener l){
-        throw new UnsupportedOperationException("Change listeners not supported by default.");
-    }
 
     /**
      * Allows to check if a configuration with a given name is defined.
@@ -364,4 +349,33 @@ public interface Configuration extends PropertyProvider{
         return ConfigurationManager.evaluateValue(config, expression);
     }
 
+    /**
+     * Add a ConfigChangeListener to this configuration instance.
+     * @param predicate the event filtering predicate
+     * @param l the listener, not null.
+     */
+    public static  void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l){
+        ConfigurationManager.addChangeListener(predicate, l);
+    }
+
+    /**
+     * Removes a ConfigChangeListener to this configuration instance.
+     * @param predicate the event filtering predicate
+     * @param l the listener, not null.
+     */
+    public static void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l){
+        ConfigurationManager.removeChangeListener(predicate, l);
+    }
+
+    /**
+     * Method to publish changes on a {@link org.apache.tamaya.Configuration} to all interested parties.
+     * Basically this method gives an abstraction on the effective event bus design fo listeners. In a CDI context
+     * the CDI enterprise event bus should be used internally to do the work, whereas in a SE only environment
+     * a more puristic approach would be useful.
+     * @param configChange the change to be published, not null.
+     */
+    public static void publishChange(ConfigChangeSet configChange){
+        ConfigurationManager.publishChange(configChange);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
index 7271e64..9fc3fdc 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
@@ -21,10 +21,9 @@ package org.apache.tamaya;
 import org.apache.tamaya.spi.Bootstrap;
 import org.apache.tamaya.spi.ConfigurationManagerSingletonSpi;
 
-import java.beans.PropertyChangeListener;
 import java.util.*;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 /**
  * Singleton accessor for accessing {@link Configuration} instances and
@@ -144,4 +143,32 @@ final class ConfigurationManager{
         return Optional.of(configManagerSingletonSpi).get().evaluateValue(config, expression);
     }
 
+    /**
+     * Add a ConfigChangeSet listener to the given configuration instance.
+     * @param predicate the event filtering predicate, or null, for selecting all changes.
+     * @param l the listener, not null.
+     */
+    public static void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
+        Optional.of(configManagerSingletonSpi).get().addChangeListener(predicate, Objects.requireNonNull(l));
+    }
+
+    /**
+     * Removes a ConfigChangeSet listener from the given configuration instance.
+     * @param predicate the event filtering predicate, or null, for selecting all changes.
+     * @param l the listener, not null.
+     */
+    public static void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
+        Optional.of(configManagerSingletonSpi).get().removeChangeListener(predicate, Objects.requireNonNull(l));
+    }
+
+    /**
+     * Method to publish changes on a {@link org.apache.tamaya.Configuration} to all interested parties.
+     * Basically this method gives an abstraction on the effective event bus design fo listeners. In a CDI context
+     * the CDI enterprise event bus should be used internally to do the work, whereas in a SE only environment
+     * a more puristic approach would be useful.
+     * @param configChange the change to be published, not null.
+     */
+    public static void publishChange(ConfigChangeSet configChange) {
+        Optional.of(configManagerSingletonSpi).get().publishChange(Objects.requireNonNull(configChange));
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/PropertyProvider.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/PropertyProvider.java b/api/src/main/java/org/apache/tamaya/PropertyProvider.java
deleted file mode 100644
index 2e54ea2..0000000
--- a/api/src/main/java/org/apache/tamaya/PropertyProvider.java
+++ /dev/null
@@ -1,161 +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;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-/**
- * This interface models a provider that serves configuration properties. The contained
- * properties may be read fromMap single or several sources (composite).<br/>
- * Property config are the building blocks out current which complex
- * configuration is setup.
- * <p/>
- * <h3>Implementation Requirements</h3>
- * <p></p>Implementations current this interface must be
- * <ul>
- * <li>Thread safe.
- * </ul>
- * It is highly recommended that implementations also are
- * <ul>
- * <li>Immutable</li>
- * <li>serializable</li>
- * </ul>
- * </p>
- */
-public interface PropertyProvider {
-
-    /**
-     * Access an empty and immutable PropertyProvider instance.
-     *
-     * @return an empty and immutable PropertyProvider instance, never null.
-     */
-    public static final PropertyProvider EMPTY_PROVIDER = PropertyProviderBuilder.create("<empty>").build();
-
-    /**
-     * Access a property.
-     * @param key the property's key, not null.
-     * @return the property's value.
-     */
-    Optional<String> get(String key);
-
-    /**
-     * Checks if a property is defined.
-     * @param key the property's key, not null.
-     * @return true, if the property is existing.
-     */
-    boolean containsKey(String key);
-
-    /**
-     * Access the current properties as Map.
-     * @return the a corresponding map, never null.
-     */
-    Map<String, String> toMap();
-
-    /**
-     * Get the meta-info current a configuration.
-     * @return the configuration's/config map's metaInfo, or null.
-     */
-    MetaInfo getMetaInfo();
-
-    /**
-     * Compares the given property provider for same
-     * contents, regardless current its current state or runtime implementation.
-     * @param provider the provider to be compared, not null.
-     * @return true, if both property sets equals.
-     */
-    default boolean hasSameProperties(PropertyProvider provider) {
-        return this == provider || ConfigChangeSetBuilder.compare(this, provider).isEmpty();
-    }
-
-    /**
-     * Access the set current property keys, defined by this provider.
-     * @return the key set, never null.
-     */
-    default Set<String> keySet(){
-        return toMap().keySet();
-    }
-
-    /**
-     * Reloads the {@link org.apache.tamaya.PropertyProvider}.
-     */
-    default ConfigChangeSet load(){
-        // by default do nothing
-        return ConfigChangeSet.emptyChangeSet(this);
-    }
-
-    /**
-     * Allows to evaluate if the provider is mutable.
-     * @return true, if the provider is mutable.
-     * @see #apply(ConfigChangeSet)
-     */
-    default boolean isMutable(){
-        return false;
-    }
-
-    /**
-     * Apply a config change to this item. Hereby the change must be related to the same instance.
-     * @param change the config change
-     * @throws ConfigException if an unrelated change was passed.
-     * @throws UnsupportedOperationException when the configuration is not writable.
-     * @see #isMutable()
-     */
-    default void apply(ConfigChangeSet change){
-        throw new UnsupportedOperationException("Config/properties not mutable: "+ this);
-    }
-
-    /**
-     * Allows to quickly check, if a provider is empty.
-     * @return true, if the provier is empty.
-     */
-    default boolean isEmpty(){
-        return keySet().isEmpty();
-    }
-
-    /**
-     * Convert the this PropertyProvider instance to a {@link org.apache.tamaya.Configuration}.
-     * @return the configuration, never null.
-     */
-    default Configuration toConfiguration(){
-        return new Configuration(){
-            @Override
-            public Optional<String> get(String key) {
-                return PropertyProvider.this.get(key);
-            }
-            @Override
-            public boolean containsKey(String key) {
-                return PropertyProvider.this.containsKey(key);
-            }
-            @Override
-            public Map<String, String> toMap() {
-                return PropertyProvider.this.toMap();
-            }
-            @Override
-            public MetaInfo getMetaInfo() {
-                return PropertyProvider.this.getMetaInfo();
-            }
-            @Override
-            public String toString() {
-                return "Configuration [PropertyProvider "+getMetaInfo()+"]";
-            }
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/PropertyProviderBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/PropertyProviderBuilder.java b/api/src/main/java/org/apache/tamaya/PropertyProviderBuilder.java
deleted file mode 100644
index 792cdf6..0000000
--- a/api/src/main/java/org/apache/tamaya/PropertyProviderBuilder.java
+++ /dev/null
@@ -1,587 +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;
-
-import org.apache.tamaya.spi.Bootstrap;
-import org.apache.tamaya.spi.PropertyProviderBuilderSpi;
-
-import java.net.URL;
-import java.util.*;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.logging.Logger;
-
-/**
- * Builder for assembling non trivial property providers.
- */
-public final class PropertyProviderBuilder {
-    private static final Supplier<IllegalStateException> noPropertyProviderAvailable =
-        () -> new IllegalStateException("No PropertyProvidersSingletonSpi available.");
-
-    /**
-     * SPI backing up this builder.
-     */
-    private static final PropertyProviderBuilderSpi spi = loadPropertyProvidersSpi();
-    /**
-     * THe logger used.
-     */
-    private static final Logger LOG = Logger.getLogger(PropertyProviderBuilder.class.getName());
-
-    /**
-     * The final meta info to be used, or null, if a default should be generated.
-     */
-    private MetaInfoBuilder metaInfoBuilder;
-
-    /**
-     * Meta info used for the next operation.
-     */
-    private MetaInfo metaInfo;
-
-    /**
-     * the current property provider, or null.
-     */
-    private PropertyProvider current;
-    /**
-     * The current aggregation policy used, when aggregating providers.
-     */
-    private AggregationPolicy aggregationPolicy = AggregationPolicy.OVERRIDE;
-
-    /**
-     * Private singleton constructor.
-     */
-    private PropertyProviderBuilder(MetaInfo metaInfo) {
-        this.metaInfoBuilder = MetaInfoBuilder.of(Objects.requireNonNull(metaInfo)).setInfo("Built by PropertyProviderBuilder.");
-    }
-
-    /**
-     * Private singleton constructor.
-     */
-    private PropertyProviderBuilder(String name) {
-        this.metaInfoBuilder = MetaInfoBuilder.of(name);
-    }
-
-    /**
-     * Private singleton constructor.
-     */
-    private PropertyProviderBuilder(PropertyProvider provider) {
-        this.metaInfoBuilder = MetaInfoBuilder.of(Objects.requireNonNull(provider).getMetaInfo());
-        this.current = provider;
-    }
-
-    /**
-     * Method to initially load the singleton SPI fromMap the {@link org.apache.tamaya.spi.Bootstrap} mechanism.
-     * The instance loaded will be used until the VM is shutdown. In case use cases require more flexibility
-     * it should be transparently implemented in the SPI implementation. This singleton will simply delegate calls
-     * and not cache any responses.
-     *
-     * @return the SPI, never null.
-     */
-    private static PropertyProviderBuilderSpi loadPropertyProvidersSpi() {
-        return Bootstrap.getService(PropertyProviderBuilderSpi.class);
-    }
-
-    /**
-     * Creates a new builder instance.
-     *
-     * @param provider the base provider to be used, not null.
-     * @return a new builder instance, never null.
-     */
-    public static PropertyProviderBuilder create(PropertyProvider provider) {
-        return new PropertyProviderBuilder(provider);
-    }
-
-    /**
-     * Creates a new builder instance.
-     *
-     * @param metaInfo the meta information, not null.
-     * @return a new builder instance, never null.
-     */
-    public static PropertyProviderBuilder create(MetaInfo metaInfo) {
-        return new PropertyProviderBuilder(metaInfo);
-    }
-
-    /**
-     * Creates a new builder instance.
-     *
-     * @param name the provider name, not null.
-     * @return a new builder instance, never null.
-     */
-    public static PropertyProviderBuilder create(String name) {
-        return new PropertyProviderBuilder(Objects.requireNonNull(name));
-    }
-
-    /**
-     * Creates a new builder instance.
-     *
-     * @return a new builder instance, never null.
-     */
-    public static PropertyProviderBuilder create() {
-        return new PropertyProviderBuilder("<noname>");
-    }
-
-
-
-
-    /**
-     * Sets the aggregation policy to be used, when adding additional property sets. The policy will
-     * be active a slong as the builder is used or it is reset to another value.
-     *
-     * @param aggregationPolicy the aggregation policy, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder withAggregationPolicy(AggregationPolicy aggregationPolicy) {
-        this.aggregationPolicy = Objects.requireNonNull(aggregationPolicy);
-        return this;
-    }
-
-    /**
-     * Sets the meta info to be used for the next operation.
-     *
-     * @param metaInfo the meta info, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder withMetaInfo(MetaInfo metaInfo) {
-        this.metaInfo = Objects.requireNonNull(metaInfo);
-        return this;
-    }
-
-    /**
-     * Adds the given providers with the current active {@link org.apache.tamaya.AggregationPolicy}. By
-     * default {@link org.apache.tamaya.AggregationPolicy#OVERRIDE} is used.
-     * @see #withAggregationPolicy(AggregationPolicy)
-     * @param providers providers to be added, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addProviders(PropertyProvider... providers) {
-        if(providers.length==0){
-            return this;
-        }
-        return addProviders(Arrays.asList(providers));
-    }
-
-    /**
-     * Adds the given providers with the current active {@link org.apache.tamaya.AggregationPolicy}. By
-     * default {@link org.apache.tamaya.AggregationPolicy#OVERRIDE} is used.
-     * @see #withAggregationPolicy(AggregationPolicy)
-     * @param providers providers to be added, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addProviders(List<PropertyProvider> providers) {
-        if(providers.isEmpty()){
-            return this;
-        }
-        List<PropertyProvider> allProviders = new ArrayList<>(providers);
-        if (this.current != null) {
-            allProviders.add(0, this.current);
-        }
-        StringBuilder b = new StringBuilder();
-        providers.forEach(p -> b.append(p.getMetaInfo().toString()).append(','));
-        b.setLength(b.length()-1);
-        String source = b.toString();
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("aggregate").setEnvironment(Environment.current())
-                    .set(MetaInfoBuilder.SOURCE,source).build();
-        }
-
-        this.current = Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                               .aggregate(mi, this.aggregationPolicy, allProviders);
-
-        addProviderChainInfo(source);
-        this.metaInfo = null;
-        return this;
-    }
-
-    private void addProviderChainInfo(String info){
-        String providerChain = metaInfoBuilder.get("providerChain");
-
-        if(providerChain == null){
-            providerChain = "\n  " + info;
-        }
-        else{
-            providerChain = providerChain + ",\n  " + info;
-        }
-        metaInfoBuilder.set("providerChain", providerChain);
-    }
-
-    /**
-     * Creates a new {@link PropertyProvider} using the given command line arguments and adds it
-     * using the current aggregation policy in place.
-     *
-     * @param args the command line arguments, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addArgs(String... args) {
-        if(args.length==0){
-            return this;
-        }
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("args").setEnvironment(Environment.current()).build();
-        }
-        PropertyProvider argProvider = Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                .fromArgs(mi, args);
-        return addProviders(argProvider);
-    }
-
-    /**
-     * Creates a new read-only {@link PropertyProvider} by reading the according path resources. The effective resources read
-     * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
-     * Properties read are aggregated using the current aggregation policy active.
-     *
-     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addPaths(String... paths) {
-        if(paths.length==0){
-            return this;
-        }
-        return addPaths(Arrays.asList(paths));
-    }
-
-
-    /**
-     * Creates a new read-only {@link PropertyProvider} by reading the according path resources. The effective resources read
-     * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
-     * Properties read are aggregated using the current aggregation policy active.
-     *
-     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addPaths(List<String> paths) {
-        if(paths.isEmpty()){
-            return this;
-        }
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("aggregate").set("paths", paths.toString()).setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).set("paths", paths.toString()).build();
-        }
-
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                    .fromPaths(mi, aggregationPolicy, paths));
-    }
-
-    /**
-     * Creates a new read-only {@link PropertyProvider} by reading the according URL resources.
-     * Properties read are aggregated using the current aggregation policy active.
-     *
-     * @param urls the urls to be read, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addURLs(URL... urls) {
-        if(urls.length==0){
-            return this;
-        }
-        return addURLs(Arrays.asList(urls));
-    }
-
-    /**
-     * Creates a new read-only {@link PropertyProvider} by reading the according URL resources.
-     * Properties read are aggregated using the current aggregation policy active.
-     *
-     * @param urls the urls to be read, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addURLs(List<URL> urls) {
-        if(urls.isEmpty()){
-            return this;
-        }
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("aggregate").set("urls", urls.toString()).setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).set("urls", urls.toString()).build();
-        }
-
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                    .fromURLs(mi, this.aggregationPolicy, urls));
-    }
-
-
-    /**
-     * Creates a new read-only {@link PropertyProvider} based on the given map.
-     * Properties read are aggregated using the current aggregation policy active.
-     *
-     * @param map the map to be added, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addMap(Map<String, String> map) {
-        if(map.isEmpty()){
-            return this;
-        }
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("map").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
-        }
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                .fromMap(mi, map));
-    }
-
-
-    /**
-     * Add the current environment properties. Aggregation is based on the current {@link org.apache.tamaya.AggregationPolicy} acvtive.
-     *
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addEnvironmentProperties() {
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("environment.properties").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
-        }
-
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                    .fromEnvironmentProperties());
-    }
-
-    /**
-     * Add the current system properties. Aggregation is based on the current {@link org.apache.tamaya.AggregationPolicy} acvtive.
-     *
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder addSystemProperties() {
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("system.properties").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
-        }
-
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                    .fromSystemProperties());
-    }
-
-    /**
-     * Adds the given {@link org.apache.tamaya.PropertyProvider} instances using the current {@link org.apache.tamaya.AggregationPolicy}
-     * active.
-     *
-     * @param providers the maps to be included, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder aggregate(PropertyProvider... providers) {
-        if(providers.length==0){
-            return this;
-        }
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("aggregate").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
-        }
-
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                    .aggregate(mi, aggregationPolicy, Arrays.asList(providers)));
-    }
-
-
-    /**
-     * Adds the given {@link org.apache.tamaya.PropertyProvider} instances using the current {@link org.apache.tamaya.AggregationPolicy}
-     * active.
-     *
-     * @param providers the maps to be included, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder aggregate(List<PropertyProvider> providers) {
-        if(providers.isEmpty()){
-            return this;
-        }
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("aggregate").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
-        }
-
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                    .aggregate(mi, aggregationPolicy, providers));
-    }
-
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} that is mutable by adding a map based instance that overrides
-     * values fromMap the original map.
-     *
-     * @param provider the provider to be made mutable, not null.
-     * @return the mutable instance.
-     */
-    public static PropertyProvider mutable(PropertyProvider provider) {
-        return Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                       .mutable(null, provider);
-    }
-
-
-    /**
-     * Intersetcs the current properties with the given {@link org.apache.tamaya.PropertyProvider} instance.
-     *
-     * @param providers the maps to be intersected, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder intersect(PropertyProvider... providers) {
-        if(providers.length==0){
-            return this;
-        }
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("intersect").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
-        }
-
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                    .intersected(mi, aggregationPolicy, Arrays.asList(providers)));
-    }
-
-
-    /**
-     * Subtracts with the given {@link org.apache.tamaya.PropertyProvider} instance from the current properties.
-     *
-     * @param providers the maps to be subtracted, not null.
-     * @return the builder for chaining.
-     */
-    public PropertyProviderBuilder subtract(PropertyProvider... providers) {
-        if(providers.length==0){
-            return this;
-        }
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("subtract").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
-        }
-        current = Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                .subtracted(mi, current, Arrays.asList(providers));
-        return this;
-    }
-
-
-    /**
-     * Filters the current properties based on the given predicate..
-     *
-     * @param filter the filter to be applied, not null.
-     * @return the new filtering instance.
-     */
-    public PropertyProviderBuilder filter(Predicate<String> filter) {
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("filtered").setEnvironment(Environment.current()).set("filter", filter.toString()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).set("filter", filter.toString()).setEnvironment(Environment.current()).build();
-        }
-        current = Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                          .filtered(mi, filter, current);
-        addProviderChainInfo("filter->" + filter.toString());
-        this.metaInfo = null;
-        return this;
-    }
-
-    /**
-     * Creates a new contextual {@link org.apache.tamaya.PropertyProvider}. Contextual maps delegate to different instances current PropertyMap depending
-     * on the keys returned fromMap the isolationP
-     *
-     * @param mapSupplier          the supplier creating new provider instances
-     * @param isolationKeySupplier the supplier providing contextual keys based on the current environment.
-     */
-    public PropertyProviderBuilder addContextual(Supplier<PropertyProvider> mapSupplier,
-                                                 Supplier<String> isolationKeySupplier) {
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("contextual").setEnvironment(Environment.current()).set("mapSupplier", mapSupplier.toString()).set("isolationKeySupplier", isolationKeySupplier.toString()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).set("mapSupplier", mapSupplier.toString()).set("isolationKeySupplier", isolationKeySupplier.toString()).setEnvironment(Environment.current()).build();
-        }
-
-        return addProviders(Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                    .contextual(mi, mapSupplier, isolationKeySupplier));
-    }
-
-    /**
-     * Replaces all keys in the current provider by the given map.
-     *
-     * @param replacementMap the map instance, that will replace all corresponding entries in {@code mainMap}, not null.
-     * @return the new delegating instance.
-     */
-    public PropertyProviderBuilder replace(Map<String, String> replacementMap) {
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("replace").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
-        }
-        current = Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                .replacing(mi, current, replacementMap);
-        this.metaInfo = null;
-        addProviderChainInfo("replace->" + replacementMap.toString());
-        return this;
-    }
-
-    /**
-     * Sets an additional key on the final {@link org.apache.tamaya.MetaInfo} of the provider
-     * created.
-     *
-     * @param key the key to be added, not null.
-     * @param value the value to be added, not null.
-     * @return this builder for chaining
-     */
-    public PropertyProviderBuilder setMeta(String key, String value){
-        this.metaInfoBuilder.set(key, value);
-        return this;
-    }
-
-    /**
-     * Build a new property provider based on the input.
-     * @return a new property provider, or null.
-     */
-    public PropertyProvider build()
-    {
-        if (current != null) {
-            return Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                           .build(metaInfoBuilder.build(), current);
-        }
-
-        return Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                       .empty(metaInfoBuilder.build());
-    }
-
-    /**
-     * Creates a {@link PropertyProvider} instance that is serializable and immutable,
-     * so it can be sent over a network connection.
-     *
-     * @return the freezed instance, never null.
-     */
-    public PropertyProvider buildFreezed() {
-        MetaInfo mi = this.metaInfo;
-        if (mi == null) {
-            mi = MetaInfoBuilder.of("freezed").set("freezed", "true").setEnvironment(Environment.current()).build();
-        } else {
-            mi = MetaInfoBuilder.of(metaInfo).set("freezed", "true").setEnvironment(Environment.current()).build();
-        }
-
-        PropertyProvider prov = Optional.ofNullable(spi).orElseThrow(noPropertyProviderAvailable)
-                                        .freezed(mi, current);
-
-        this.metaInfo = null;
-        return prov;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/PropertySource.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/PropertySource.java b/api/src/main/java/org/apache/tamaya/PropertySource.java
new file mode 100644
index 0000000..22d332c
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/PropertySource.java
@@ -0,0 +1,185 @@
+/*
+* 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;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+* This interface models a provider that serves configuration properties. The contained
+* properties may be read fromMap single or several sources (composite).<br/>
+* Property config are the building blocks out current which complex
+* configuration is setup.
+* <p/>
+* <h3>Implementation Requirements</h3>
+* <p></p>Implementations current this interface must be
+* <ul>
+* <li>Thread safe.
+* </ul>
+* It is highly recommended that implementations also are
+* <ul>
+* <li>Immutable</li>
+* <li>serializable</li>
+* </ul>
+* </p>
+*/
+public interface PropertySource {
+
+    /**
+     * Access an empty and immutable PropertyProvider instance.
+     *
+     * @return an empty and immutable PropertyProvider instance, never null.
+     */
+    public static final PropertySource EMPTY_PROPERTYSOURCE = new PropertySource(){
+
+        private MetaInfo metaInfo = MetaInfo.of("<empty>");
+
+        @Override
+        public Optional<String> get(String key) {
+            return Optional.empty();
+        }
+
+        @Override
+        public boolean containsKey(String key) {
+            return false;
+        }
+
+        @Override
+        public Map<String, String> toMap() {
+            return Collections.emptyMap();
+        }
+
+        @Override
+        public MetaInfo getMetaInfo() {
+            return metaInfo;
+        }
+    };
+
+    /**
+     * Access a property.
+     * @param key the property's key, not null.
+     * @return the property's value.
+     */
+    Optional<String> get(String key);
+
+    /**
+     * Checks if a property is defined.
+     * @param key the property's key, not null.
+     * @return true, if the property is existing.
+     */
+    boolean containsKey(String key);
+
+    /**
+     * Access the current properties as Map.
+     * @return the a corresponding map, never null.
+     */
+    Map<String, String> toMap();
+
+    /**
+     * Get the meta-info current a configuration.
+     * @return the configuration's/config map's metaInfo, or null.
+     */
+    MetaInfo getMetaInfo();
+
+    /**
+     * Compares the given property provider for same
+     * contents, regardless current its current state or runtime implementation.
+     * @param provider the provider to be compared, not null.
+     * @return true, if both property sets equals.
+     */
+    default boolean hasSameProperties(PropertySource provider) {
+        return this == provider || ConfigChangeSetBuilder.compare(this, provider).isEmpty();
+    }
+
+    /**
+     * Access the set current property keys, defined by this provider.
+     * @return the key set, never null.
+     */
+    default Set<String> keySet(){
+        return toMap().keySet();
+    }
+
+    /**
+     * Reloads the {@link PropertySource}.
+     */
+    default ConfigChangeSet load(){
+        // by default do nothing
+        return ConfigChangeSet.emptyChangeSet(this);
+    }
+
+    /**
+     * Allows to evaluate if the provider is mutable.
+     * @return true, if the provider is mutable.
+     * @see #apply(ConfigChangeSet)
+     */
+    default boolean isMutable(){
+        return false;
+    }
+
+    /**
+     * Apply a config change to this item. Hereby the change must be related to the same instance.
+     * @param change the config change
+     * @throws ConfigException if an unrelated change was passed.
+     * @throws UnsupportedOperationException when the configuration is not writable.
+     * @see #isMutable()
+     */
+    default void apply(ConfigChangeSet change){
+        throw new UnsupportedOperationException("Config/properties not mutable: "+ this);
+    }
+
+    /**
+     * Allows to quickly check, if a provider is empty.
+     * @return true, if the provier is empty.
+     */
+    default boolean isEmpty(){
+        return keySet().isEmpty();
+    }
+
+    /**
+     * Convert the this PropertyProvider instance to a {@link org.apache.tamaya.Configuration}.
+     * @return the configuration, never null.
+     */
+    default Configuration toConfiguration(){
+        return new Configuration(){
+            @Override
+            public Optional<String> get(String key) {
+                return PropertySource.this.get(key);
+            }
+            @Override
+            public boolean containsKey(String key) {
+                return PropertySource.this.containsKey(key);
+            }
+            @Override
+            public Map<String, String> toMap() {
+                return PropertySource.this.toMap();
+            }
+            @Override
+            public MetaInfo getMetaInfo() {
+                return PropertySource.this.getMetaInfo();
+            }
+            @Override
+            public String toString() {
+                return "Configuration [source: PropertyProvider "+getMetaInfo()+"]";
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/annotation/ConfigChangeListener.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/annotation/ConfigChangeListener.java b/api/src/main/java/org/apache/tamaya/annotation/ConfigChangeListener.java
deleted file mode 100644
index 5329ee6..0000000
--- a/api/src/main/java/org/apache/tamaya/annotation/ConfigChangeListener.java
+++ /dev/null
@@ -1,37 +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.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation to annotate a method on a class to be informed on config changes.
- * The exact behaviour, when configuration change events are sent can be configured
- * on each configured property/method by adding the {@link org.apache.tamaya.annotation.WithLoadPolicy}
- * annotation. By default listeners are only informed about changes that are affecting configured
- * values current the containing class/instance.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(value = { ElementType.METHOD })
-public @interface ConfigChangeListener {
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/annotation/ObservesConfigChange.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/annotation/ObservesConfigChange.java b/api/src/main/java/org/apache/tamaya/annotation/ObservesConfigChange.java
new file mode 100644
index 0000000..ef92b25
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/annotation/ObservesConfigChange.java
@@ -0,0 +1,38 @@
+/*
+ * 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.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to annotate a method on a class to be informed on config changes.
+ * The exact behaviour, when configuration change events are sent can be configured
+ * on each configured property/method by adding the {@link org.apache.tamaya.annotation.WithLoadPolicy}
+ * annotation. By default listeners are informed on all changes of configurations that were used as
+ * input configurations for configuring a class/instance. Additionally {@link org.apache.tamaya.annotation.ConfiguredProperty}
+ * annotations can be added that allows to constrain changes to some limited properties.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.METHOD })
+public @interface ObservesConfigChange {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
index 175f5b5..86b52a4 100644
--- a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
+++ b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
@@ -18,12 +18,12 @@
  */
 package org.apache.tamaya.spi;
 
+import org.apache.tamaya.ConfigChangeSet;
 import org.apache.tamaya.Configuration;
+import org.apache.tamaya.PropertySource;
 
-import java.beans.PropertyChangeListener;
-import java.util.*;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 /**
  * Manager for {@link org.apache.tamaya.Configuration} instances. Implementations must register an instance
@@ -102,4 +102,26 @@ public interface ConfigurationManagerSingletonSpi{
      */
     String evaluateValue(Configuration config, String expression);
 
+    /**
+     * Add a ConfigChangeSet listener to the given configuration instance.
+     * @param predicate the event filtering predicate, or null, for selecting all changes.
+     * @@param l the listener, not null.
+     */
+    void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l);
+
+    /**
+     * Removes a ConfigChangeSet listener from the given configuration instance.
+     * @param predicate the event filtering predicate, or null, for selecting all changes.
+     * @param l the listener, not null.
+     */
+    void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l);
+
+    /**
+     * Method to publish changes on a {@link org.apache.tamaya.Configuration} to all interested parties.
+     * Basically this method gives an abstraction on the effective event bus design fo listeners. In a CDI context
+     * the CDI enterprise event bus should be used internally to do the work, whereas in a SE only environment
+     * a more puristic approach would be useful.
+     * @param configChangeSet the change to be published, not null.
+     */
+    void publishChange(ConfigChangeSet configChangeSet);
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/main/java/org/apache/tamaya/spi/PropertyProviderBuilderSpi.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/PropertyProviderBuilderSpi.java b/api/src/main/java/org/apache/tamaya/spi/PropertyProviderBuilderSpi.java
deleted file mode 100644
index a64a1c9..0000000
--- a/api/src/main/java/org/apache/tamaya/spi/PropertyProviderBuilderSpi.java
+++ /dev/null
@@ -1,206 +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.spi;
-
-import org.apache.tamaya.AggregationPolicy;
-import org.apache.tamaya.MetaInfo;
-import org.apache.tamaya.PropertyProvider;
-
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URL;
-import java.util.*;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-
-/**
- * Singleton backing bean for providing the functionality for {@link org.apache.tamaya.PropertyProviderBuilder}.
- */
-public interface PropertyProviderBuilderSpi {
-
-    /**
-     * Creates a new read-only {@link org.apache.tamaya.PropertyProvider} by using the given Map.
-     *
-     * @param metaInfo the meat information to be provided additionally.
-     * @param map      the properties to be included, not null.
-     * @return a new {@link }PropertyMap} instance with the given properties fromMap the Map instance passed.
-     */
-    PropertyProvider fromMap(MetaInfo metaInfo, Map<String, String> map);
-
-    /**
-     * Creates a new {@link }PropertyMap} using the given command line arguments
-     *
-     * @param metaInfo the meta information to be provided additionally.
-     * @param args     the command line arguments, not null.
-     * @return a new {@link }PropertyMap} instance with the given arguments contained as properties.
-     */
-    PropertyProvider fromArgs(MetaInfo metaInfo, String... args);
-
-    /**
-     * Creates a new read-only {@link PropertyProvider} by reading the according path resources. The effective resources read
-     * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
-     * Properties read fromMap resources evaluated on
-     * paths with lower order are overriding any duplicate values fromMap previous paths hereby.
-     *
-     * @param metaInfo the meat information to be provided additionally.
-     * @param paths    the paths to be resolved by the {@code PathResolverService} , not null.
-     * @param aggregationPolicy the {@link org.apache.tamaya.AggregationPolicy} to be used to resolve conflicts.
-     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
-     */
-    PropertyProvider fromPaths(MetaInfo metaInfo, AggregationPolicy aggregationPolicy, List<String> paths);
-
-
-    /**
-     * Creates a new read-only {@link PropertyProvider} based on the resources defined by the given paths. The effective resources
-     * read hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
-     *
-     * @param metaInfo the meat information to be provided additionally.
-     * @param urls     the urls to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     */
-    PropertyProvider fromURLs(MetaInfo metaInfo, AggregationPolicy aggregationPolicy, List<URL> urls);
-
-    /**
-     * Get an empty and immutable PropertyProvider instance. The meta-information contains the given String
-     * under the key 'info'.
-     *
-     * @return an empty and immutable PropertyProvider instance, never null, with the given Strings as info meta-data..
-     */
-    PropertyProvider empty(MetaInfo metaInfo);
-
-    /**
-     * Returns a read-only {@link org.apache.tamaya.PropertyProvider} reflecting the current runtime environment properties.
-     *
-     * @return a new read-only {@link org.apache.tamaya.PropertyProvider} instance based on the current runtime environment properties.
-     */
-    PropertyProvider fromEnvironmentProperties();
-
-    /**
-     * Creates a new read-only {@link org.apache.tamaya.PropertyProvider} reflecting the current system properties.
-     *
-     * @return a new read-only {@link org.apache.tamaya.PropertyProvider} instance based on the current system properties.
-     */
-    PropertyProvider fromSystemProperties();
-
-    /**
-     * Converts a given {@link PropertyProvider} instance into a serializable and immutable form,
-     * so it can be sent over a network connection.
-     *
-     * @param provider the PropertyProvider to be freezed.
-     * @return the serializable instance.
-     */
-    PropertyProvider freezed(MetaInfo metaInfo, PropertyProvider provider);
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing all property maps given, hereby using the given AggregationPolicy.
-     *
-     * @param policy       the annotation to be used, not null.
-     * @param propertyMaps the maps to be included, not null.
-     * @return the aggregated instance containing all given maps.
-     */
-    PropertyProvider aggregate(MetaInfo metaInfo, AggregationPolicy policy, List<PropertyProvider> propertyMaps);
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} that is mutable by adding a map based instance that overrides
-     * values fromMap the original map.
-     * @param provider the provider to be made mutable, not null.
-     * @return the mutable instance.
-     */
-    PropertyProvider mutable(MetaInfo metaInfo, PropertyProvider provider);
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing only properties that are shared by all given maps,
-     * hereby later maps in the array override  properties fromMap previous instances.
-     *
-     * @param metaInfo the meta information to be provided additionally.
-     * @param propertyMaps the maps to be included, not null.
-     * @return the intersecting instance containing all given maps.
-     */
-    PropertyProvider intersected(MetaInfo metaInfo, AggregationPolicy policy, List<PropertyProvider> propertyMaps);
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing only properties fromMap the target instance, that are not contained
-     * in one current the other maps passed.
-     *
-     * @param metaInfo the meta information to be provided additionally.
-     * @param target         the base map, not null.
-     * @param subtrahendSets the maps to be subtracted, not null.
-     * @return the intersecting instance containing all given maps.
-     */
-    PropertyProvider subtracted(MetaInfo metaInfo, PropertyProvider target, List<PropertyProvider> subtrahendSets);
-
-
-    /**
-     * Creates a filtered {@link org.apache.tamaya.PropertyProvider} (a view) current a given base {@link }PropertyMap}. The filter hereby is
-     * applied dynamically on access, so also runtime changes current the base map are reflected appropriately.
-     *
-     * @param metaInfo the meta information to be provided additionally.
-     * @param propertyMap the base map instance, not null.
-     * @param filter      the filtger to be applied, not null.
-     * @return the new filtering instance.
-     */
-    PropertyProvider filtered(MetaInfo metaInfo, Predicate<String> filter, PropertyProvider propertyMap);
-
-    /**
-     * Creates a new contextual {@link org.apache.tamaya.PropertyProvider}. Contextual maps delegate to different instances current PropertyMap depending
-     * on the keys returned fromMap the isolationP
-     * @param metaInfo the meta information to be provided additionally.
-     * @param mapSupplier          the supplier creating new provider instances
-     * @param isolationKeySupplier the supplier providing contextual keys based on the current environment.
-     */
-    PropertyProvider contextual(MetaInfo metaInfo, Supplier<PropertyProvider> mapSupplier,
-                                Supplier<String> isolationKeySupplier);
-
-
-    /**
-     * Creates a filtered {@link org.apache.tamaya.PropertyProvider} (a view) current a given base {@link }PropertyMap}. The filter hereby is
-     * applied dynamically on access, so also runtime changes current the base map are reflected appropriately.
-     *
-     * @param metaInfo the meta information to be provided additionally.
-     * @param mainMap   the main map instance, not null.
-     * @param parentMap the delegated parent map instance, not null.
-     * @return the new delegating instance.
-     */
-    PropertyProvider delegating(MetaInfo metaInfo, PropertyProvider mainMap, Map<String, String> parentMap);
-
-    /**
-     * Creates a {@link PropertyProvider} where all keys current a current map,
-     * existing in another map are replaced
-     * with the ones fromMap the other {@link PropertyProvider}. The filter hereby is
-     * applied dynamically on access, so also runtime changes current the base map are reflected appropriately.
-     * Keys not existing in the {@code mainMap}, but present in {@code replacementMao} will be hidden.
-     *
-     * @param metaInfo the meta information to be provided additionally.
-     * @param mainMap        the main map instance, which keys, present in {@code replacementMap} will be replaced
-     *                       with the ones
-     *                       in {@code replacementMap}, not null.
-     * @param replacementMap the map instance, that will replace all corresponding entries in {@code mainMap}, not null.
-     * @return the new delegating instance.
-     */
-    PropertyProvider replacing(MetaInfo metaInfo, PropertyProvider mainMap, Map<String, String> replacementMap);
-
-    /**
-     * Create a new PropertyProvider instance given the metaInfo and the baseProvider, masking hereby the base provider's
-     * meta information.
-     * @param metaInfo the meta information to be provided, not null.
-     * @param baseProvider the base provider to be used.
-     * @return a PropertyProvider with the given meta info, providing data from the baseProvider, never null.
-     */
-    PropertyProvider build(MetaInfo metaInfo, PropertyProvider baseProvider);
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java b/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
index e20707e..d044982 100644
--- a/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
+++ b/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
@@ -23,6 +23,8 @@ import org.apache.tamaya.spi.ConfigurationManagerSingletonSpi;
 import java.beans.PropertyChangeListener;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * Created by Anatole on 09.09.2014.
@@ -85,4 +87,19 @@ public class TestConfigServiceSingletonSpi implements ConfigurationManagerSingle
         return expression;
     }
 
+    @Override
+    public void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
+        // ignore
+    }
+
+    @Override
+    public void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
+        // ignore
+    }
+
+    @Override
+    public void publishChange(ConfigChangeSet configChangeSet) {
+        // ignore
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java b/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
index f5a7223..e0ab2fb 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
@@ -19,28 +19,19 @@
 package org.apache.tamaya.core.config;
 
 import org.apache.tamaya.*;
-import org.apache.tamaya.core.properties.AbstractPropertyProvider;
-import org.apache.tamaya.core.properties.Store;
+import org.apache.tamaya.core.properties.AbstractPropertySource;
 import org.apache.tamaya.core.spi.AdapterProviderSpi;
 import org.apache.tamaya.spi.Bootstrap;
 
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.util.*;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
-public abstract class AbstractConfiguration extends AbstractPropertyProvider implements Configuration{
+public abstract class AbstractConfiguration extends AbstractPropertySource implements Configuration{
 
     private static final Logger LOG = Logger.getLogger(AbstractConfiguration.class.getName());
 
     private static final long serialVersionUID = 503764580971917964L;
 
-    /**
-     * The registered change listeners, or null.
-     */
-    private volatile Store<PropertyChangeListener> changeListeners;
-
     private final Object LOCK = new Object();
 
     private String version = UUID.randomUUID().toString();
@@ -89,42 +80,9 @@ public abstract class AbstractConfiguration extends AbstractPropertyProvider imp
             this.version = UUID.randomUUID().toString();
         }
         ConfigChangeSet changeSet = ConfigChangeSetBuilder.of(oldState).addChanges(newState).build();
-        publishPropertyChangeEvents(changeSet.getEvents());
+        Configuration.publishChange(changeSet);
         return changeSet;
     }
 
-    @Override
-    public void addPropertyChangeListener(PropertyChangeListener l){
-        if(this.changeListeners == null){
-            synchronized(LOCK){
-                if(this.changeListeners == null){
-                    this.changeListeners = new Store<>();
-                }
-            }
-        }
-        this.changeListeners.addWeak(l);
-    }
 
-    @Override
-    public void removePropertyChangeListener(PropertyChangeListener l){
-        if(changeListeners == null){
-            return;
-        }
-        this.changeListeners.remove(l);
-    }
-
-    protected void publishPropertyChangeEvents(Collection<PropertyChangeEvent> events){
-        if(changeListeners == null){
-            return;
-        }
-        for(PropertyChangeListener l : changeListeners){
-            for(PropertyChangeEvent evt: events) {
-                try {
-                    l.propertyChange(evt);
-                } catch (Exception e) {
-                    LOG.log(Level.SEVERE, e, () -> "Error thrown by ConfigChangeListener: " + l);
-                }
-            }
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java b/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
index 5ee8160..e28da5e 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
@@ -19,7 +19,7 @@
 package org.apache.tamaya.core.config;
 
 import org.apache.tamaya.Configuration;
-import org.apache.tamaya.PropertyProviderBuilder;
+import org.apache.tamaya.core.properties.PropertySourceBuilder;
 
 import java.util.*;
 import java.util.function.UnaryOperator;
@@ -64,7 +64,7 @@ public final class ConfigFunctions {
                             .collect(Collectors.toMap(
                                     e -> stripKeys ? e.getKey().substring(areaKey.length() + 1) : e.getKey(),
                                     e -> e.getValue())));
-            return PropertyProviderBuilder.create("area: " + areaKey).addMap(area).build().toConfiguration();
+            return PropertySourceBuilder.create("area: " + areaKey).addMap(area).build().toConfiguration();
         };
     }
 
@@ -111,7 +111,7 @@ public final class ConfigFunctions {
                             .collect(Collectors.toMap(
                                     e -> stripKeys ? e.getKey().substring(areaKey.length() + 1) : e.getKey(),
                                     e -> e.getValue())));
-            return PropertyProviderBuilder.create("area (recursive): " + areaKey).addMap(area).build().toConfiguration();
+            return PropertySourceBuilder.create("area (recursive): " + areaKey).addMap(area).build().toConfiguration();
         };
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/80bce9ec/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java b/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
index 306925e..86030bc 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.core.config;
 
 import org.apache.tamaya.*;
+import org.apache.tamaya.core.properties.PropertySourceBuilder;
 
 import java.io.Serializable;
 import java.time.Instant;
@@ -32,12 +33,12 @@ import java.util.Objects;
 final class FreezedConfiguration extends AbstractConfiguration implements Serializable{
     private static final long serialVersionUID = -6373137316556444171L;
 
-    private PropertyProvider properties;
+    private PropertySource properties;
     private String version;
 
     private FreezedConfiguration(Configuration config){
         super(MetaInfoBuilder.of(config.getMetaInfo()).set("freezedAt", Instant.now().toString()).build());
-        this.properties = PropertyProviderBuilder.create(config).buildFreezed();
+        this.properties = PropertySourceBuilder.create(config).buildFreezed();
         this.version = Objects.requireNonNull(config.getVersion());
     }