tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anat...@apache.org
Subject [2/9] incubator-tamaya git commit: TAMAYA-19: Code cleanup.
Date Sat, 06 Dec 2014 01:03:24 GMT
TAMAYA-19: Code cleanup.


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

Branch: refs/heads/master
Commit: 816207892d468c5537e86b2bf495494ea382ec4e
Parents: 6a489cb
Author: anatole <anatole@apache.org>
Authored: Fri Dec 5 00:25:54 2014 +0100
Committer: anatole <anatole@apache.org>
Committed: Fri Dec 5 00:25:54 2014 +0100

----------------------------------------------------------------------
 .../org/apache/tamaya/AggregationPolicy.java    |  17 +-
 .../apache/tamaya/ConfigChangeSetBuilder.java   |   2 +-
 .../java/org/apache/tamaya/ConfigFunctions.java |  42 +-
 .../java/org/apache/tamaya/Configuration.java   |  28 +-
 .../org/apache/tamaya/ConfigurationManager.java |  17 -
 .../org/apache/tamaya/PropertyProvider.java     |  10 +-
 .../apache/tamaya/PropertyProviderBuilder.java  | 472 ++++++++++++++++
 .../org/apache/tamaya/PropertyProviders.java    | 548 -------------------
 .../spi/ConfigurationManagerSingletonSpi.java   |  13 -
 .../tamaya/spi/PropertyProviderBuilderSpi.java  | 203 +++++++
 .../spi/PropertyProvidersSingletonSpi.java      | 198 -------
 .../TestConfigServiceSingletonSpi.java          |  11 -
 12 files changed, 718 insertions(+), 843 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/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 85f77b1..886e193 100644
--- a/api/src/main/java/org/apache/tamaya/AggregationPolicy.java
+++ b/api/src/main/java/org/apache/tamaya/AggregationPolicy.java
@@ -33,34 +33,27 @@ public interface AggregationPolicy {
     public String aggregate(String key, String value1, String value2);
 
     /** Ignore overrides, only extend (additive). */
-    public static AggregationPolicy IGNORE_DUPLICATES() {
-        return (k, v1, v2) -> v1 == null? v2 : v1;
-    }
+    public static final AggregationPolicy IGNORE_DUPLICATES = (k, v1, v2) -> v1 == null? v2 : v1;
 
     /** Combine multiple values into a comma separated list. */
-    public static AggregationPolicy COMBINE() {
-        return (k, v1, v2) -> v1 != null && v2 != null ? v1 + ',' + v2: v2;
-    }
+    public static final AggregationPolicy COMBINE = (k, v1, v2) -> v1 != null && v2 != null ? v1 + ',' + v2: v2;
 
     /**
      * Interpret later keys as override (additive and override), replacing
      * the key loaded earlier/fromMap previous contained
      * {@link org.apache.tamaya.PropertyProvider}.
      */
-    public static AggregationPolicy OVERRIDE() {
-        return (k, v1, v2) -> v2;
-    }
+    public static final AggregationPolicy OVERRIDE = (k, v1, v2) -> v2;
 
     /**
      * Throw an exception, when keys are not disjunctive (strictly
      * additive).
      */
-    public static AggregationPolicy EXCEPTION() {
-        return (String key, String value, String newValue) -> {
+    public static final AggregationPolicy EXCEPTION =
+        (String key, String value, String newValue) -> {
             if(value!=null && newValue!=null && !value.equals(newValue)){
                 throw new ConfigException("Conflicting values encountered key="+key+", value="+value+", newValue="+newValue);
             }
             return newValue;
         };
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/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 be3cba2..a38a99b 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
@@ -291,7 +291,7 @@ public final class ConfigChangeSetBuilder {
     }
 
     /**
-     * Compares the two property providers/configurations and creates a collection current all changes
+     * Compares the two property config/configurations and creates a collection current all changes
      * that must be appied to render {@code map1} into {@code map2}.
      * @param map1 the source map, not null.
      * @param map2 the target map, not null.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/api/src/main/java/org/apache/tamaya/ConfigFunctions.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigFunctions.java b/api/src/main/java/org/apache/tamaya/ConfigFunctions.java
index a466b63..c732120 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigFunctions.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigFunctions.java
@@ -28,12 +28,14 @@ public final class ConfigFunctions {
     /**
      * Private singleton constructor.
      */
-    private ConfigFunctions(){}
+    private ConfigFunctions() {
+    }
 
     /**
      * Creates a ConfigOperator that creates a Configuration containing only keys
      * that are contained in the given area (non recursive). Hereby
      * the area key is stripped away fromMap the resulting key.
+     *
      * @param areaKey the area key, not null
      * @return the area configuration, with the areaKey stripped away.
      */
@@ -44,32 +46,34 @@ public final class ConfigFunctions {
     /**
      * Creates a ConfigOperator that creates a Configuration containing only keys
      * that are contained in the given area (non recursive).
-     * @param areaKey the area key, not null
+     *
+     * @param areaKey   the area key, not null
      * @param stripKeys if set to true, the area key is stripped away fromMap the resulting key.
      * @return the area configuration, with the areaKey stripped away.
      */
-    public static ConfigOperator selectArea(String areaKey, boolean stripKeys){
+    public static ConfigOperator selectArea(String areaKey, boolean stripKeys) {
         return config -> {
             Map<String, String> area = new HashMap<>();
             area.putAll(
                     config.toMap().entrySet().stream()
-                    .filter(e -> isKeyInArea(e.getKey(), areaKey))
-                    .collect(Collectors.toMap(
-                            e -> stripKeys? e.getKey().substring(areaKey.length()+1) : e.getKey(),
-                            e -> e.getValue())));
-            return PropertyProviders.fromMap(area).toConfiguration();
+                            .filter(e -> isKeyInArea(e.getKey(), areaKey))
+                            .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();
         };
     }
 
     /**
      * Calculates the current area key and compares it with the given key.
-     * @param key the fully qualified entry key, not null
+     *
+     * @param key     the fully qualified entry key, not null
      * @param areaKey the area key, not null
      * @return true, if the entry is exact in this area
      */
-    public static boolean isKeyInArea(String key, String areaKey){
+    public static boolean isKeyInArea(String key, String areaKey) {
         int lastIndex = key.lastIndexOf('.');
-        String curAreaKey =  lastIndex > 0 ? key.substring(0, lastIndex) : "";
+        String curAreaKey = lastIndex > 0 ? key.substring(0, lastIndex) : "";
         return curAreaKey.equals(areaKey);
     }
 
@@ -77,6 +81,7 @@ public final class ConfigFunctions {
      * Creates a ConfigOperator that creates a Configuration containing only keys
      * that are contained in the given area (recursive). Hereby
      * the area key is stripped away fromMap the resulting key.
+     *
      * @param areaKey the area key, not null
      * @return the area configuration, with the areaKey stripped away.
      */
@@ -87,21 +92,22 @@ public final class ConfigFunctions {
     /**
      * Creates a ConfigOperator that creates a Configuration containing only keys
      * that are contained in the given area (recursive).
-     * @param areaKey the area key, not null
+     *
+     * @param areaKey   the area key, not null
      * @param stripKeys if set to true, the area key is stripped away fromMap the resulting key.
      * @return the area configuration, with the areaKey stripped away.
      */
-    public static ConfigOperator selectAreaRecursive(String areaKey, boolean stripKeys){
+    public static ConfigOperator selectAreaRecursive(String areaKey, boolean stripKeys) {
         return config -> {
             Map<String, String> area = new HashMap<>();
             String lookupKey = areaKey + '.';
             area.putAll(
                     config.toMap().entrySet().stream()
-                    .filter(e -> e.getKey().startsWith(lookupKey))
-                    .collect(Collectors.toMap(
-                            e -> stripKeys? e.getKey().substring(areaKey.length()+1) : e.getKey(),
-                            e -> e.getValue())));
-            return PropertyProviders.fromMap(area).toConfiguration();
+                            .filter(e -> e.getKey().startsWith(lookupKey))
+                            .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();
         };
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/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 f5e2ed7..e076ea0 100644
--- a/api/src/main/java/org/apache/tamaya/Configuration.java
+++ b/api/src/main/java/org/apache/tamaya/Configuration.java
@@ -28,7 +28,7 @@ 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 providers in well defined tree like structure,
+ * {@link PropertyProvider} 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>
@@ -250,7 +250,7 @@ public interface Configuration extends PropertyProvider{
     }
 
     /**
-     * Field that allows property providers to be versioned, meaning that each change on a provider requires this value
+     * Field that allows property config to be versioned, meaning that each change on a provider requires this value
      * to be incremented by one. This can be easily used to implement versioning (and optimistic locking)
      * in distributed (remote) usage scenarios.
      * @return the version current the current instance, or 'N/A'.
@@ -262,9 +262,7 @@ public interface Configuration extends PropertyProvider{
      * @param l the listener, not null.
      */
     default void addPropertyChangeListener(PropertyChangeListener l){
-        addConfigChangeListener((p) -> {
-            if (p.getSource() == this) l.propertyChange(p);
-        });
+        throw new UnsupportedOperationException("Change listeners not supported by default.");
     }
 
     /**
@@ -272,9 +270,7 @@ public interface Configuration extends PropertyProvider{
      * @param l the listener, not null.
      */
     default void removePropertyChangeListener(PropertyChangeListener l){
-        removeConfigChangeListener((p) -> {
-            if (p.getSource() == this) l.propertyChange(p);
-        });
+        throw new UnsupportedOperationException("Change listeners not supported by default.");
     }
 
     /**
@@ -367,20 +363,4 @@ public interface Configuration extends PropertyProvider{
         return ConfigurationManager.evaluateValue(config, expression);
     }
 
-    /**
-     * Adds a (global) {@link java.beans.PropertyChangeListener} instance that listens to all kind current config changes.
-     * @param listener the {@link java.beans.PropertyChangeListener} instance to be added, not null.
-     */
-    public static void addConfigChangeListener(PropertyChangeListener listener){
-        ConfigurationManager.addConfigChangeListener(listener);
-    }
-
-    /**
-     * Removes a (global) {@link java.beans.PropertyChangeListener} instance that listens to all kind current config changes,
-     * if one is currently registered.
-     * @param listener the {@link java.beans.PropertyChangeListener} instance to be removed, not null.
-     */
-    public static void removeConfigChangeListener(PropertyChangeListener listener){
-        ConfigurationManager.removeConfigChangeListener(listener);
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/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 d714f71..7271e64 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
@@ -144,21 +144,4 @@ final class ConfigurationManager{
         return Optional.of(configManagerSingletonSpi).get().evaluateValue(config, expression);
     }
 
-    /**
-     * Adds a (global) {@link java.beans.PropertyChangeListener} instance that listens to all kind current config changes.
-     * @param listener the {@link java.beans.PropertyChangeListener} instance to be added, not null.
-     */
-    public static void addConfigChangeListener(PropertyChangeListener listener){
-        Optional.of(configManagerSingletonSpi).get().addPropertyChangeListener(listener);
-    }
-
-    /**
-     * Removes a (global) {@link java.beans.PropertyChangeListener} instance that listens to all kind current config changes,
-     * if one is currently registered.
-     * @param listener the {@link java.beans.PropertyChangeListener} instance to be removed, not null.
-     */
-    public static void removeConfigChangeListener(PropertyChangeListener listener){
-        Optional.of(configManagerSingletonSpi).get().removePropertyChangeListener(listener);
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/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
index 6572e3e..0d225a4 100644
--- a/api/src/main/java/org/apache/tamaya/PropertyProvider.java
+++ b/api/src/main/java/org/apache/tamaya/PropertyProvider.java
@@ -25,7 +25,7 @@ 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 providers are the building blocks out current which complex
+ * Property config are the building blocks out current which complex
  * configuration is setup.
  * <p/>
  * <h3>Implementation Requirements</h3>
@@ -43,6 +43,13 @@ import java.util.Set;
 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.
@@ -146,4 +153,5 @@ public interface PropertyProvider {
             }
         };
     }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/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
new file mode 100644
index 0000000..d3af701
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/PropertyProviderBuilder.java
@@ -0,0 +1,472 @@
+/*
+ * 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.URI;
+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 {
+    /**
+     * 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 current meta info, or null, if a default should be generated.
+     */
+    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.metaInfo = Objects.requireNonNull(metaInfo);
+    }
+
+    /**
+     * Private singleton constructor.
+     */
+    private PropertyProviderBuilder(PropertyProvider provider) {
+        this.metaInfo = 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 create(MetaInfo.of(name));
+    }
+
+
+    /**
+     * 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;
+    }
+
+    public PropertyProviderBuilder addProviders(PropertyProvider... providers) {
+        List<PropertyProvider> allProviders = Arrays.asList(providers);
+        if (this.current != null) {
+            allProviders.add(0, this.current);
+        }
+        MetaInfo mi = this.metaInfo;
+        if (mi == null) {
+            mi = MetaInfoBuilder.of("aggregate").setEnvironment(Environment.current()).build();
+        }
+        this.current = Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .aggregate(this.aggregationPolicy, mi, allProviders);
+        this.metaInfo = null;
+        return this;
+    }
+
+    /**
+     * Creates a new {@link }PropertyMap} using the given command line arguments
+     *
+     * @param args the command line arguments, not null.
+     * @return a new {@link }PropertyMap} instance with the given arguments contained as properties.
+     */
+    public PropertyProviderBuilder addArgs(String... args) {
+        MetaInfo mi = this.metaInfo;
+        if (mi == null) {
+            mi = MetaInfoBuilder.of("args").setEnvironment(Environment.current()).build();
+        }
+        PropertyProvider argProvider = Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .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 fromMap resources evaluated on
+     * paths with lower order are overriding any duplicate values fromMap previous paths hereby.
+     *
+     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
+     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
+     */
+    public PropertyProviderBuilder addPaths(String... paths) {
+        MetaInfo mi = this.metaInfo;
+        if (mi == null) {
+            mi = MetaInfoBuilder.of("aggregate").setEnvironment(Environment.current()).build();
+        } else {
+            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).set("paths", Arrays.toString(paths)).build();
+        }
+        return addProviders(Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .fromPaths(aggregationPolicy, mi, 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 fromMap resources evaluated on
+     * paths with lower order are overriding any duplicate values fromMap previous paths hereby.
+     *
+     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
+     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
+     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
+     */
+    public PropertyProviderBuilder addPaths(List<String> paths) {
+        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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .fromPaths(aggregationPolicy, metaInfo, 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 uris the uris to be read, not null.
+     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
+     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
+     */
+    public PropertyProviderBuilder addUris(URI... uris) {
+        MetaInfo mi = this.metaInfo;
+        if (mi == null) {
+            mi = MetaInfoBuilder.of("aggregate").set("uris", Arrays.toString(uris)).setEnvironment(Environment.current()).build();
+        } else {
+            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).set("paths", uris.toString()).build();
+        }
+        return addProviders(Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .fromUris(this.aggregationPolicy, mi, Arrays.asList(uris)));
+    }
+
+
+    /**
+     * Creates a new read-only {@link org.apache.tamaya.PropertyProvider} by using the given Map.
+     *
+     * @param map the properties to be included, not null.
+     * @return a new {@link }PropertyMap} instance with the given properties fromMap the Map instance passed.
+     */
+    public PropertyProviderBuilder addMap(Map<String, String> map) {
+        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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .fromMap(metaInfo, map));
+    }
+
+
+    /**
+     * 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.
+     */
+    public PropertyProviderBuilder addEnvironmentProperties() {
+        MetaInfo mi = this.metaInfo;
+        if (mi == null) {
+            mi = MetaInfoBuilder.of("with env-props").setEnvironment(Environment.current()).build();
+        } else {
+            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
+        }
+        return addProviders(Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .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.
+     */
+    public PropertyProviderBuilder addSystemProperties() {
+        MetaInfo mi = this.metaInfo;
+        if (mi == null) {
+            mi = MetaInfoBuilder.of("with sys-props").setEnvironment(Environment.current()).build();
+        } else {
+            mi = MetaInfoBuilder.of(metaInfo).setEnvironment(Environment.current()).build();
+        }
+        return addProviders(Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .fromSystemProperties());
+    }
+
+    /**
+     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing all property maps given, hereby later maps in the array override
+     * properties fromMap previous instances.
+     *
+     * @param providers the maps to be included, not null.
+     * @return the union instance containing all given maps.
+     */
+    public PropertyProviderBuilder aggregate(PropertyProvider... providers) {
+        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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .aggregate(aggregationPolicy, mi, Arrays.asList(providers)));
+    }
+
+
+    /**
+     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing all property maps given, hereby later maps in the array override
+     * properties fromMap previous instances.
+     *
+     * @param providers the maps to be included, not null.
+     * @return the union instance containing all given maps.
+     */
+    public PropertyProviderBuilder aggregate(List<PropertyProvider> providers) {
+        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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .aggregate(aggregationPolicy, metaInfo, 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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .mutable(null, 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 providers the maps to be included, not null.
+     * @return the intersecting instance containing all given maps.
+     */
+    public PropertyProviderBuilder intersect(PropertyProvider... providers) {
+        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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .intersected(aggregationPolicy, mi, Arrays.asList(providers)));
+    }
+
+
+    /**
+     * 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 providers the maps to be subtracted, not null.
+     * @return the intersecting instance containing all given maps.
+     */
+    public PropertyProviderBuilder subtract(PropertyProvider... providers) {
+        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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .subtracted(current, mi, Arrays.asList(providers));
+        return this;
+    }
+
+
+    /**
+     * 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 filter the filtger 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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .filtered(filter, mi, current);
+        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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .contextual(mapSupplier, mi, 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 delegates the delegated parent map instance, not null.
+     * @return the new delegating instance.
+     */
+    public PropertyProviderBuilder addDefaults(Map<String, String> delegates) {
+        MetaInfo mi = this.metaInfo;
+        if (mi == null) {
+            mi = MetaInfoBuilder.of("filtered").setEnvironment(Environment.current()).set("delegates", delegates.toString()).build();
+        } else {
+            mi = MetaInfoBuilder.of(metaInfo).set("delegates", delegates.toString()).setEnvironment(Environment.current()).build();
+        }
+        current = Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .delegating(current, mi, delegates);
+        return this;
+    }
+
+    /**
+     * 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 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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .replacing(current, mi, replacementMap);
+        return this;
+    }
+
+    public PropertyProvider build() {
+        if (current != null) {
+            return current;
+        }
+        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .empty(metaInfo);
+    }
+
+    /**
+     * 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 freeze() {
+        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();
+        }
+        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
+                .freezed(mi, current);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/api/src/main/java/org/apache/tamaya/PropertyProviders.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/PropertyProviders.java b/api/src/main/java/org/apache/tamaya/PropertyProviders.java
deleted file mode 100644
index a7f509a..0000000
--- a/api/src/main/java/org/apache/tamaya/PropertyProviders.java
+++ /dev/null
@@ -1,548 +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.PropertyProvidersSingletonSpi;
-
-import java.net.URI;
-import java.util.*;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.logging.Logger;
-
-/**
- * Accessor factory for several standard {@link PropertyProvider} instances, usable for creating {@code Configuration}
- * parts.
- */
-public final class PropertyProviders {
-
-    private static final PropertyProvidersSingletonSpi spi = loadPropertyProvidersSingletonSpi();
-
-    private static final Logger LOG = Logger.getLogger(PropertyProviders.class.getName());
-
-    /**
-     * Private singleton constructor.
-     */
-    private PropertyProviders() {
-    }
-
-    /**
-     * 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 PropertyProvidersSingletonSpi loadPropertyProvidersSingletonSpi() {
-        return Bootstrap.getService(PropertyProvidersSingletonSpi.class);
-    }
-
-    /**
-     * Creates a new {@link }PropertyMap} using the given command line arguments
-     *
-     * @param args the command line arguments, not null.
-     * @return a new {@link }PropertyMap} instance with the given arguments contained as properties.
-     */
-    public static PropertyProvider fromArgs(String... args) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromArgs(null, args);
-    }
-
-    /**
-     * 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.
-     */
-    public static PropertyProvider fromArgs(MetaInfo metaInfo, String... args) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromArgs(metaInfo, 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 aggregationPolicy the aggregationPolicy to be used, not null.
-     * @param paths             the paths to be resolved by the {@code PathResolverService} , not null.
-     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
-     */
-    public static PropertyProvider fromPaths(AggregationPolicy aggregationPolicy, String... paths) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromPaths(aggregationPolicy, null, 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 fromMap resources evaluated on
-     * paths with lower order are overriding any duplicate values fromMap previous paths hereby.
-     *
-     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
-     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromPaths(String... paths) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromPaths(AggregationPolicy.EXCEPTION(), null, 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 fromMap resources evaluated on
-     * paths with lower order are overriding any duplicate values fromMap previous paths hereby.
-     *
-     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
-     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromPaths(List<String> paths) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromPaths(AggregationPolicy.EXCEPTION(), null, 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 fromMap resources evaluated on
-     * paths with lower order are overriding any duplicate values fromMap previous paths hereby.
-     *
-     * @param aggregationPolicy the aggregationPolicy to be used, not null.
-     * @param paths             the paths to be resolved by the {@code PathResolverService} , not null.
-     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
-     */
-    public static PropertyProvider fromPaths(AggregationPolicy aggregationPolicy, List<String> paths) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromPaths(aggregationPolicy, null, 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 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.
-     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromPaths(MetaInfo metaInfo, List<String> paths) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromPaths(AggregationPolicy.EXCEPTION(), metaInfo, 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 fromMap resources evaluated on
-     * paths with lower order are overriding any duplicate values fromMap previous paths hereby.
-     * @param aggregationPolicy the aggregationPolicy to be used, not null.
-     * @param metaInfo the meat information to be provided additionally.
-     * @param paths    the paths to be resolved by the {@code PathResolverService} , not null.
-     * @return a new {@link }PropertyMap} instance with the given paths contained as properties.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromPaths(AggregationPolicy aggregationPolicy, MetaInfo metaInfo, List<String> paths) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromPaths(aggregationPolicy, metaInfo, 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 uris the uris to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromUris(URI... uris) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromUris(AggregationPolicy.EXCEPTION(), null, Arrays.asList(uris));
-    }
-
-    /**
-     * 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 aggregationPolicy the aggregationPolicy to be used, not null.
-     * @param uris the uris to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromUris(AggregationPolicy aggregationPolicy, URI... uris) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromUris(aggregationPolicy, null, Arrays.asList(uris));
-    }
-
-    /**
-     * 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 uris the uris to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromUris(List<URI> uris) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromUris(AggregationPolicy.EXCEPTION(), null, uris);
-    }
-
-    /**
-     * 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 aggregationPolicy the aggregationPolicy to be used, not null.
-     * @param uris the uris to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromUris(AggregationPolicy aggregationPolicy, List<URI> uris) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromUris(aggregationPolicy, null, uris);
-    }
-
-    /**
-     * 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 uris     the uris to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromUris(MetaInfo metaInfo, URI... uris) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromUris(AggregationPolicy.EXCEPTION(), metaInfo, Arrays.asList(uris));
-    }
-
-    /**
-     * 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 aggregationPolicy the aggregationPolicy to be used, not null.
-     * @param metaInfo the meat information to be provided additionally.
-     * @param uris     the uris to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     */
-    public static PropertyProvider fromUris(AggregationPolicy aggregationPolicy, MetaInfo metaInfo, URI... uris) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromUris(aggregationPolicy, metaInfo, Arrays.asList(uris));
-    }
-
-    /**
-     * 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 uris     the uris to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider fromUris(MetaInfo metaInfo, List<URI> uris) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromUris(AggregationPolicy.EXCEPTION(), metaInfo, uris);
-    }
-
-    /**
-     * 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 aggregationPolicy the aggregationPolicy to be used, not null.
-     * @param metaInfo the meat information to be provided additionally.
-     * @param uris     the uris to be read, not null.
-     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
-     */
-    public static PropertyProvider fromUris(AggregationPolicy aggregationPolicy, MetaInfo metaInfo, List<URI> uris) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromUris(aggregationPolicy, metaInfo, uris);
-    }
-
-    /**
-     * Creates a new read-only {@link org.apache.tamaya.PropertyProvider} by using the given Map.
-     *
-     * @param map the properties to be included, not null.
-     * @return a new {@link }PropertyMap} instance with the given properties fromMap the Map instance passed.
-     */
-    public static PropertyProvider fromMap(Map<String, String> map) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromMap(null, map);
-    }
-
-
-    /**
-     * 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.
-     */
-    public static PropertyProvider fromMap(MetaInfo metaInfo, Map<String, String> map) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .fromMap(metaInfo, map);
-    }
-
-    /**
-     * Get an empty and immutable PropertyProvider instance.
-     *
-     * @return an empty and immutable PropertyProvider instance, never null.
-     */
-    public static PropertyProvider empty() {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .empty(null);
-    }
-
-    /**
-     * Get an empty and immutable PropertyProvider instance.
-     *
-     * @return an empty and mutable PropertyProvider instance, never null.
-     */
-    public static PropertyProvider emptyMutable() {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .emptyMutable(null);
-    }
-
-    /**
-     * 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..
-     */
-    public static PropertyProvider empty(MetaInfo metaInfo) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .empty(metaInfo);
-    }
-
-    /**
-     * Get an empty and mutable 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..
-     */
-    public static PropertyProvider emptyMutable(MetaInfo metaInfo) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .emptyMutable(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.
-     */
-    public static PropertyProvider fromEnvironmentProperties() {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .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.
-     */
-    public static PropertyProvider fromSystemProperties() {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .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.
-     */
-    public static PropertyProvider freezed(PropertyProvider provider) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .freezed(null, provider);
-    }
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing all property maps given, hereby later maps in the array override
-     * properties fromMap previous instances.
-     * @param mapping       the AggregateMapping to be used, not null.
-     * @param metaInfo the meta information to be provided additionally.
-     * @param providers the maps to be included, not null.
-     * @return the union instance containing all given maps.
-     */
-    public static PropertyProvider aggregate(AggregationPolicy mapping, MetaInfo metaInfo, PropertyProvider... providers){
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .aggregate(mapping, metaInfo, Arrays.asList(providers));
-    }
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing all property maps given, hereby later maps in the array override
-     * properties fromMap previous instances.
-     *
-     * @param providers the maps to be included, not null.
-     * @return the union instance containing all given maps.
-     */
-    public static PropertyProvider aggregate(PropertyProvider... providers) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .aggregate(AggregationPolicy.OVERRIDE(), null, Arrays.asList(providers));
-    }
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing all property maps given, hereby later maps in the array override
-     * properties fromMap previous instances.
-     *
-     * @param providers the maps to be included, not null.
-     * @return the union instance containing all given maps.
-     */
-    public static PropertyProvider aggregate(List<PropertyProvider> providers) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .aggregate(AggregationPolicy.OVERRIDE(), null, providers);
-    }
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing all property maps given, hereby using the given AggregationPolicy.
-     *
-     * @param mapping       the AggregateMapping to be used, not null.
-     * @param propertyMaps the maps to be included, not null.
-     * @return the aggregated instance containing all given maps.
-     */
-    public static PropertyProvider aggregate(AggregationPolicy mapping, PropertyProvider... propertyMaps) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .aggregate(mapping, null, Arrays.asList(propertyMaps));
-    }
-
-    /**
-     * Creates a new {@link org.apache.tamaya.PropertyProvider} containing all property maps given, hereby using the given AggregationPolicy.
-     *
-     * @param mapping    the AggregateMapping to be used, not null.
-     * @param providers the providers to be included, not null.
-     * @return the aggregated instance containing all given maps.
-     */
-    public static PropertyProvider aggregate(AggregationPolicy mapping, List<PropertyProvider> providers) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .aggregate(mapping, null, 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.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .mutable(null, 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 aggregationPolicy the aggregationPolicy to be used, not null.
-     * @param providers the maps to be included, not null.
-     * @return the intersecting instance containing all given maps.
-     */
-    public static PropertyProvider intersected(AggregationPolicy aggregationPolicy, PropertyProvider... providers) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .intersected(aggregationPolicy, Arrays.asList(providers));
-    }
-
-    /**
-     * 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 providers the maps to be included, not null.
-     * @return the intersecting instance containing all given maps.
-     * @throws ConfigException if duplicate entries are encountered (AggregationPolicy.EXCEPTION).
-     */
-    public static PropertyProvider intersected(PropertyProvider... providers) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .intersected(AggregationPolicy.OVERRIDE(), Arrays.asList(providers));
-    }
-
-    /**
-     * 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 target         the base map, not null.
-     * @param providers the maps to be subtracted, not null.
-     * @return the intersecting instance containing all given maps.
-     */
-    public static PropertyProvider subtracted(PropertyProvider target, PropertyProvider... providers) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .subtracted(target, Arrays.asList(providers));
-    }
-
-
-    /**
-     * 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 provider the base map instance, not null.
-     * @param filter      the filtger to be applied, not null.
-     * @return the new filtering instance.
-     */
-    public static PropertyProvider filtered(Predicate<String> filter, PropertyProvider provider) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .filtered(filter, provider);
-    }
-
-    /**
-     * 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 static PropertyProvider contextual(Supplier<PropertyProvider> mapSupplier,
-                                              Supplier<String> isolationKeySupplier) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .contextual(mapSupplier, 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 mainMap   the main map instance, not null.
-     * @param parentMap the delegated parent map instance, not null.
-     * @return the new delegating instance.
-     */
-    public static PropertyProvider delegating(PropertyProvider mainMap, Map<String, String> parentMap) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .delegating(mainMap, 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 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.
-     */
-    public static PropertyProvider replacing(PropertyProvider mainMap, Map<String, String> replacementMap) {
-        return Optional.of(spi).orElseThrow(() -> new IllegalStateException("No PropertyProvidersSingletonSpi available."))
-                .replacing(mainMap, replacementMap);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/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 ab63ee9..175f5b5 100644
--- a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
+++ b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
@@ -102,17 +102,4 @@ public interface ConfigurationManagerSingletonSpi{
      */
     String evaluateValue(Configuration config, String expression);
 
-    /**
-     * Adds a (global) {@link java.beans.PropertyChangeListener} instance that listens to all kind current config changes.
-     * @param listener the {@link java.beans.PropertyChangeListener} instance to be added, not null.
-     */
-    void addPropertyChangeListener(PropertyChangeListener listener);
-
-    /**
-     * Removes a (global) {@link java.beans.PropertyChangeListener} instance that listens to all kind current config changes,
-     * if one is currently registered.
-     * @param listener the {@link java.beans.PropertyChangeListener} instance to be removed, not null.
-     */
-    void removePropertyChangeListener(PropertyChangeListener listener);
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/81620789/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
new file mode 100644
index 0000000..c72bfee
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/spi/PropertyProviderBuilderSpi.java
@@ -0,0 +1,203 @@
+/*
+ * 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.net.URI;
+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(AggregationPolicy aggregationPolicy, MetaInfo metaInfo, 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 uris     the uris to be read, not null.
+     * @return a new {@link }PropertyMap} instance based on the given paths/resources found.
+     */
+    PropertyProvider fromUris(AggregationPolicy aggregationPolicy, MetaInfo metaInfo, List<URI> uris);
+
+    /**
+     * 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);
+
+    /**
+     * Get an empty and mutable 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 emptyMutable(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 mapping to be used, not null.
+     * @param propertyMaps the maps to be included, not null.
+     * @return the aggregated instance containing all given maps.
+     */
+    PropertyProvider aggregate(AggregationPolicy policy, MetaInfo metaInfo, 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(AggregationPolicy policy, MetaInfo metaInfo, 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(PropertyProvider target, MetaInfo metaInfo, 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(Predicate<String> filter, MetaInfo metaInfo, 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(Supplier<PropertyProvider> mapSupplier,MetaInfo metaInfo,
+                                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(PropertyProvider mainMap, MetaInfo metaInfo, 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(PropertyProvider mainMap, MetaInfo metaInfo, Map<String, String> replacementMap);
+}


Mime
View raw message