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/06 02:03:27 UTC

[5/9] incubator-tamaya git commit: TAMAYA-19: Code cleanup.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultPropertyAdaptersSingletonSpi.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultPropertyAdaptersSingletonSpi.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultPropertyAdaptersSingletonSpi.java
new file mode 100644
index 0000000..4f35d3a
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultPropertyAdaptersSingletonSpi.java
@@ -0,0 +1,100 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.PropertyAdapter;
+import org.apache.tamaya.annot.WithPropertyAdapter;
+import org.apache.tamaya.spi.PropertyAdaptersSingletonSpi;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.util.Currency;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by Anatole on 30.09.2014.
+ */
+public class DefaultPropertyAdaptersSingletonSpi implements PropertyAdaptersSingletonSpi{
+
+    private Map<Class,PropertyAdapter> adapters = new ConcurrentHashMap<>();
+
+    public DefaultPropertyAdaptersSingletonSpi(){
+        // Add default adapters
+        register(char.class, (s) -> s.charAt(0));
+        register(int.class, Integer::parseInt);
+        register(byte.class, Byte::parseByte);
+        register(short.class, Short::parseShort);
+        register(boolean.class, Boolean::parseBoolean);
+        register(float.class, Float::parseFloat);
+        register(double.class, Double::parseDouble);
+
+        register(Character.class, (s) -> s.charAt(0));
+        register(Integer.class, Integer::parseInt);
+        register(Byte.class, Byte::parseByte);
+        register(Short.class, Short::parseShort);
+        register(Boolean.class, Boolean::parseBoolean);
+        register(Float.class, Float::parseFloat);
+        register(Double.class, Double::parseDouble);
+        register(BigDecimal.class, BigDecimal::new);
+        register(BigInteger.class, BigInteger::new);
+
+        register(Currency.class, (s) -> Currency.getInstance(s));
+
+        register(LocalDate.class, LocalDate::parse);
+        register(LocalTime.class, LocalTime::parse);
+        register(LocalDateTime.class, LocalDateTime::parse);
+        register(ZoneId.class, ZoneId::of);
+    }
+
+    @Override
+    public <T> PropertyAdapter<T> register(Class<T> targetType, PropertyAdapter<T> adapter){
+        return adapters.put(targetType, adapter);
+    }
+
+    @Override
+    public <T> PropertyAdapter<T> getAdapter(Class<T> targetType, WithPropertyAdapter adapterAnnot){
+        PropertyAdapter adapter = null;
+        Class<? extends PropertyAdapter> configuredAdapter = null;
+        if(adapterAnnot != null){
+            configuredAdapter = adapterAnnot.value();
+            if(!configuredAdapter.equals(PropertyAdapter.class)){
+                try{
+                    adapter = configuredAdapter.newInstance();
+                }
+                catch(Exception e){
+                    throw new ConfigException("Invalid adapter configured.", e);
+                }
+            }
+        }
+        if(adapter == null){
+            adapter = adapters.get(targetType);
+        }
+        return adapter;
+    }
+
+    @Override
+    public boolean isTargetTypeSupported(Class<?> targetType){
+        return adapters.containsKey(targetType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultPropertyProviderBuilderSpi.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultPropertyProviderBuilderSpi.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultPropertyProviderBuilderSpi.java
new file mode 100644
index 0000000..eedeee0
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/DefaultPropertyProviderBuilderSpi.java
@@ -0,0 +1,282 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.AggregationPolicy;
+import org.apache.tamaya.MetaInfo;
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.PropertyProvider;
+import org.apache.tamaya.spi.PropertyProviderBuilderSpi;
+
+import java.net.URL;
+import java.time.Instant;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.logging.Logger;
+
+/**
+ * Default implementation current the singleton backing bean for the {@link org.apache.tamaya.PropertyProviderBuilder}.
+ */
+public class DefaultPropertyProviderBuilderSpi implements PropertyProviderBuilderSpi {
+
+    private final PropertyProvider EMPTY_PROPERTYPROVIDER = fromMap(MetaInfo.of("<empty>"), Collections.emptyMap());
+    private static final PropertyProvider ENV_PROPERTYPROVIDER = new EnvironmentPropertyProvider();
+
+    private static final Logger LOG = Logger.getLogger(DefaultPropertyProviderBuilderSpi.class.getName());
+
+    @Override
+    public PropertyProvider fromArgs(MetaInfo metaInfo, String... args) {
+        if(metaInfo==null){
+            metaInfo = MetaInfo.of("CLI");
+        }
+        // TODO read the CLI with some better library, e.g. move parsing service to ext. service SPI
+        Map<String, String> properties = new HashMap<>();
+        for (int base = 0; base < args.length; base++) {
+            if (args[base].startsWith("--")) {
+                String argKey = args[base].substring(2);
+                String value = "true"; // flag only
+                if (base != args.length - 1) {
+                    if (args[base + 1].startsWith("-")) {
+                        base++;
+                        int eqIndex = argKey.indexOf('=');
+                        if (eqIndex > 0) {
+                            value = argKey.substring(eqIndex + 1);
+                            argKey = argKey.substring(0, eqIndex);
+                        }
+                    } else {
+                        value = args[base + 1];
+                        base += 2;
+                    }
+                }
+                properties.put(argKey, value);
+            } else if (args[base].startsWith("-")) {
+                String argKey = args[base].substring(1);
+                String value = "true"; // flag only
+                if (base != args.length - 1) {
+                    if (args[base + 1].startsWith("-")) {
+                        base++;
+                        int eqIndex = argKey.indexOf('=');
+                        if (eqIndex > 0) {
+                            value = argKey.substring(eqIndex + 1);
+                            argKey = argKey.substring(0, eqIndex);
+                        }
+                    } else {
+                        value = args[base + 1];
+                        base += 2;
+                    }
+                }
+                properties.put(argKey, value);
+            }
+        }
+        return fromMap(metaInfo, properties);
+    }
+
+    @Override
+    public PropertyProvider fromPaths(MetaInfo metaInfo, AggregationPolicy aggregationPolicy, List<String> paths) {
+        if(metaInfo == null){
+            metaInfo = MetaInfoBuilder.of().setInfo("From Paths").set("paths", paths.toString()).build();
+        }
+        return new PathBasedPropertyProvider(metaInfo, paths, aggregationPolicy);
+    }
+
+    @Override
+    public PropertyProvider fromURLs(MetaInfo metaInfo, AggregationPolicy aggregationPolicy, List<URL> resources) {
+        if(metaInfo == null){
+            metaInfo = MetaInfoBuilder.of().setInfo("From Resources").set("resources", resources.toString()).build();
+        }
+        return new URLBasedPropertyProvider(metaInfo, resources, aggregationPolicy);
+    }
+
+    @Override
+    public PropertyProvider fromMap(MetaInfo metaInfo, Map<String, String> map) {
+        if(metaInfo == null){
+            metaInfo = MetaInfoBuilder.of().setInfo("From Map").set("map", map.toString()).build();
+        }
+        return new MapBasedPropertyProvider(metaInfo, map);
+    }
+
+    @Override
+    public PropertyProvider empty(MetaInfo metaInfo) {
+        if(metaInfo==null) {
+            return EMPTY_PROPERTYPROVIDER;
+        }
+        return fromMap(metaInfo, Collections.emptyMap());
+    }
+
+    /**
+     * Returns a read-only {@link PropertyProvider} reflecting the current runtime environment properties.
+     *
+     * @return a new read-only {@link PropertyProvider} instance based on the current runtime environment properties.
+     */
+    @Override
+    public PropertyProvider fromEnvironmentProperties() {
+        return ENV_PROPERTYPROVIDER;
+    }
+
+    /**
+     * Creates a new read-only {@link PropertyProvider} reflecting the current system properties.
+     *
+     * @return a new read-only {@link PropertyProvider} instance based on the current system properties.
+     */
+    @Override
+    public PropertyProvider fromSystemProperties() {
+        return new SystemPropertiesPropertyProvider();
+    }
+
+    @Override
+    public PropertyProvider freezed(MetaInfo metaInfo, PropertyProvider provider) {
+        if(metaInfo==null){
+            metaInfo = MetaInfoBuilder.of().setType("freezed")
+                    .set("provider", provider.toString())
+                    .set("freezedAt", Date.from(Instant.now()).toString())
+                    .build();
+        }
+        else{
+            metaInfo = MetaInfoBuilder.of(metaInfo).setType("freezed")
+                    .set("freezedAt", Date.from(Instant.now()).toString())
+                    .set("provider", provider.toString())
+                    .build();
+        }
+        return FreezedPropertyProvider.of(metaInfo, provider);
+    }
+
+    /**
+     * Creates a new {@link PropertyProvider} containing all property maps given, hereby using the given AggregationPolicy.
+     *
+     * @param policy       the AggregationPolicy to be used, not null.
+     * @param providers the maps to be included, not null.
+     * @return the aggregated instance containing all given maps.
+     */
+    @Override
+    public PropertyProvider aggregate(MetaInfo metaInfo, AggregationPolicy policy, List<PropertyProvider> providers) {
+        if(metaInfo==null){
+            metaInfo = MetaInfoBuilder.of().setInfo("Aggregated")
+                    .set("AggregationPolicy", policy.toString())
+                    .set("config", providers.toString())
+                    .build();
+        }
+        return new AggregatedPropertyProvider(metaInfo, null, policy, providers);
+    }
+
+    /**
+     * Creates a new {@link 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.
+     */
+    @Override
+    public PropertyProvider mutable(MetaInfo metaInfo, PropertyProvider provider) {
+        if(metaInfo==null){
+            metaInfo = MetaInfoBuilder.of(provider.getMetaInfo())
+                    .set("mutableSince", Date.from(Instant.now()).toString())
+                    .build();
+        }
+        PropertyProvider mutableProvider = fromMap(metaInfo,new HashMap<>());
+        List<PropertyProvider> providers = new ArrayList<>(2);
+        providers.add(provider);
+        providers.add(mutableProvider);
+        return new AggregatedPropertyProvider(metaInfo, mutableProvider, AggregationPolicy.OVERRIDE, providers);
+    }
+
+    /**
+     * Creates a new {@link 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 policy to resolve aggregation conflicts.
+     * @param providers the maps to be included, not null.
+     * @return the intersecting instance containing all given maps.
+     */
+    @Override
+    public PropertyProvider intersected(MetaInfo metaInfo, AggregationPolicy aggregationPolicy, List<PropertyProvider> providers) {
+        return new IntersectingPropertyProvider(metaInfo, aggregationPolicy, providers);
+    }
+
+    /**
+     * Creates a new {@link 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 subtrahendSets the maps to be subtracted, not null.
+     * @return the intersecting instance containing all given maps.
+     */
+    @Override
+    public PropertyProvider subtracted(MetaInfo metaInfo, PropertyProvider target, List<PropertyProvider> subtrahendSets) {
+        return new SubtractingPropertyProvider(metaInfo, target,subtrahendSets);
+    }
+
+
+    /**
+     * Creates a filtered {@link 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 propertyMap the base map instance, not null.
+     * @param filter      the filtger to be applied, not null.
+     * @return the new filtering instance.
+     */
+    @Override
+    public PropertyProvider filtered(MetaInfo metaInfo, Predicate<String> filter, PropertyProvider propertyMap) {
+        return new FilteredPropertyProvider(metaInfo, propertyMap, filter);
+    }
+
+    /**
+     * Creates a new contextual {@link 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.
+     */
+    @Override
+    public PropertyProvider contextual(MetaInfo metaInfo, Supplier<PropertyProvider> mapSupplier,
+                                              Supplier<String> isolationKeySupplier) {
+        return new ContextualPropertyProvider(metaInfo, mapSupplier, isolationKeySupplier);
+    }
+
+
+    /**
+     * Creates a filtered {@link 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.
+     */
+    @Override
+    public PropertyProvider delegating(MetaInfo metaInfo, PropertyProvider mainMap, Map<String, String> parentMap) {
+        return new DelegatingPropertyProvider(metaInfo, mainMap, parentMap);
+    }
+
+    /**
+     * Creates a {@link org.apache.tamaya.PropertyProvider} where all keys current a current map,
+     * existing in another map are replaced
+     * with the ones fromMap the other {@link org.apache.tamaya.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.
+     */
+    @Override
+    public PropertyProvider replacing(MetaInfo metaInfo, PropertyProvider mainMap, Map<String, String> replacementMap) {
+        return new ReplacingPropertyProvider(metaInfo, mainMap, replacementMap);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/DelegatingPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/DelegatingPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/DelegatingPropertyProvider.java
new file mode 100644
index 0000000..6182e0f
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/DelegatingPropertyProvider.java
@@ -0,0 +1,108 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.ConfigChangeSet;
+import org.apache.tamaya.MetaInfo;
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.PropertyProvider;
+
+import java.util.*;
+
+/**
+ * Implementation for a {@link org.apache.tamaya.PropertyProvider} that is an aggregate current
+ * multiple child instances. Controlled by an {@link org.apache.tamaya.AggregationPolicy} the
+ * following aggregations are supported:
+ * <ul>
+ * <li><b>IGNORE_DUPLICATES: </b>Ignore all overrides.</li>
+ * <li><b>: </b></li>
+ * <li><b>: </b></li>
+ * <li><b>: </b></li>
+ * </ul>
+ */
+class DelegatingPropertyProvider implements PropertyProvider{
+
+    private static final long serialVersionUID = -1419376385695224799L;
+    private PropertyProvider mainMap;
+    private Map<String,String> parentMap;
+    private MetaInfo metaInfo;
+
+    /**
+     * Creates a mew instance, with aggregation polilcy
+     * {@code AggregationPolicy.OVERRIDE}.
+     *
+     * @param mainMap   The main ConfigMap.
+     * @param parentMap The delegated parent ConfigMap.
+     */
+    public DelegatingPropertyProvider(MetaInfo metaInfo, PropertyProvider mainMap, Map<String,String> parentMap){
+        if(metaInfo==null) {
+            this.metaInfo =
+                    MetaInfoBuilder.of().setType("delegate").set("provider", mainMap.toString()).set("delegate", parentMap.toString())
+                            .build();
+        }
+        else{
+            this.metaInfo =
+                    MetaInfoBuilder.of(metaInfo).setType("delegate").set("provider", mainMap.toString()).set("delegate", parentMap.toString())
+                            .build();
+        }
+        this.parentMap = Objects.requireNonNull(parentMap);
+        this.parentMap = Objects.requireNonNull(parentMap);
+    }
+
+    @Override
+    public ConfigChangeSet load(){
+        return mainMap.load();
+    }
+
+    @Override
+    public boolean containsKey(String key){
+        return keySet().contains(key);
+    }
+
+    @Override
+    public Map<String,String> toMap(){
+        return null;
+    }
+
+    @Override
+    public MetaInfo getMetaInfo(){
+        return this.metaInfo;
+    }
+
+    @Override
+    public Optional<String> get(String key){
+        Optional<String> val = mainMap.get(key);
+        if(!val.isPresent()){
+            return Optional.ofNullable(parentMap.get(key));
+        }
+        return val;
+    }
+
+    @Override
+    public Set<String> keySet(){
+        Set<String> keys = new HashSet<>(mainMap.keySet());
+        keys.addAll(parentMap.keySet());
+        return keys;
+    }
+
+    @Override
+    public String toString(){
+        return super.toString() + "(mainMap=" + mainMap + ", delegate=" + parentMap + ")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/EnvironmentPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/EnvironmentPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/EnvironmentPropertyProvider.java
new file mode 100644
index 0000000..c0ab0de
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/EnvironmentPropertyProvider.java
@@ -0,0 +1,45 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.core.properties.AbstractPropertyProvider;
+
+import java.util.Map;
+
+class EnvironmentPropertyProvider extends AbstractPropertyProvider {
+
+    private static final long serialVersionUID = 4753258482658331010L;
+
+    public Map<String,String> toMap(){
+        return System.getenv();
+    }
+
+    public EnvironmentPropertyProvider(){
+        super(MetaInfoBuilder.of().setType("env-properties").build());
+    }
+
+    @Override
+    public String toString(){
+        return "EnvironmentPropertyMap{" +
+                "props=" + super.toString() +
+                '}';
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/FilteredPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/FilteredPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/FilteredPropertyProvider.java
new file mode 100644
index 0000000..995b782
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/FilteredPropertyProvider.java
@@ -0,0 +1,74 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.ConfigChangeSet;
+import org.apache.tamaya.MetaInfo;
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.PropertyProvider;
+import org.apache.tamaya.core.properties.AbstractPropertyProvider;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+class FilteredPropertyProvider extends AbstractPropertyProvider {
+
+    private static final long serialVersionUID = 4301042530074932562L;
+    private PropertyProvider unit;
+    private Predicate<String> filter;
+
+    public FilteredPropertyProvider(MetaInfo metaInfo, PropertyProvider configuration, Predicate<String> filter){
+        super(metaInfo==null?MetaInfoBuilder.of(configuration.getMetaInfo()).setType("filtered").set("filter", filter.toString()).build():
+                MetaInfoBuilder.of(metaInfo).setType("filtered").set("filter", filter.toString()).build());
+        Objects.requireNonNull(configuration);
+        this.unit = configuration;
+        this.filter = filter;
+    }
+
+    @Override
+    public Map<String,String> toMap(){
+        final Map<String,String> result = new HashMap<>();
+        this.unit.toMap().entrySet().forEach(e -> {
+            if(filter.test(e.getKey())){
+                result.put(e.getKey(), e.getValue());
+            }
+        });
+        return result;
+    }
+
+    @Override
+    public ConfigChangeSet load(){
+        unit.load();
+        return super.load();
+    }
+
+    /**
+     * Apply a config change to this item. Hereby the change must be related to the same instance.
+     * @param change the config change
+     * @throws org.apache.tamaya.ConfigException if an unrelated change was passed.
+     * @throws UnsupportedOperationException when the configuration is not writable.
+     */
+    @Override
+    public void apply(ConfigChangeSet change){
+        this.unit.apply(change);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/FreezedPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/FreezedPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/FreezedPropertyProvider.java
new file mode 100644
index 0000000..af9659a
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/FreezedPropertyProvider.java
@@ -0,0 +1,98 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.ConfigChangeSet;
+import org.apache.tamaya.MetaInfo;
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.PropertyProvider;
+
+import java.io.Serializable;
+import java.time.Instant;
+import java.util.*;
+
+/**
+ * This class models a freezed instance current an {@link org.apache.tamaya.PropertyProvider}.
+ * Created by Anatole on 28.03.14.
+ */
+final class FreezedPropertyProvider implements PropertyProvider, Serializable{
+
+    private static final long serialVersionUID = 3365413090311267088L;
+    private Map<String,Map<String,String>> fieldMMetaInfo = new HashMap<>();
+    private MetaInfo metaInfo;
+    private Map<String,String> properties = new HashMap<>();
+
+    private FreezedPropertyProvider(MetaInfo metaInfo, PropertyProvider propertyMap) {
+        Map<String, String> map = propertyMap.toMap();
+        this.properties.putAll(map);
+        this.properties = Collections.unmodifiableMap(this.properties);
+        if (metaInfo == null) {
+            this.metaInfo =
+                    MetaInfoBuilder.of(propertyMap.getMetaInfo()).set("freezedAt", Instant.now().toString()).build();
+        } else {
+            this.metaInfo = metaInfo;
+        }
+    }
+
+    public static PropertyProvider of(MetaInfo metaInfo, PropertyProvider propertyProvider){
+        if(propertyProvider instanceof FreezedPropertyProvider){
+            return propertyProvider;
+        }
+        return new FreezedPropertyProvider(metaInfo, propertyProvider);
+    }
+
+    @Override
+    public ConfigChangeSet load(){
+        return ConfigChangeSet.emptyChangeSet(this);
+    }
+
+    public int size(){
+        return properties.size();
+    }
+
+    public boolean isEmpty(){
+        return properties.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(String key){
+        return properties.containsKey(key);
+    }
+
+    @Override
+    public Map<String,String> toMap(){
+        return Collections.unmodifiableMap(this.properties);
+    }
+
+    @Override
+    public MetaInfo getMetaInfo(){
+        return this.metaInfo;
+    }
+
+    @Override
+    public Optional<String> get(String key){
+        return Optional.ofNullable(properties.get(key));
+    }
+
+    @Override
+    public Set<String> keySet(){
+        return properties.keySet();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/IntersectingPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/IntersectingPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/IntersectingPropertyProvider.java
new file mode 100644
index 0000000..0414644
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/IntersectingPropertyProvider.java
@@ -0,0 +1,71 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.*;
+import org.apache.tamaya.core.properties.AbstractPropertyProvider;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Provider implementation that combines multiple other config by intersecting
+ * the key/values common to all config, conflicting keys are resolved using an
+ * {@link org.apache.tamaya.AggregationPolicy}.
+ */
+class IntersectingPropertyProvider extends AbstractPropertyProvider {
+
+    private List<PropertyProvider> providers;
+    private PropertyProvider aggregatedDelegate;
+
+    public IntersectingPropertyProvider(MetaInfo metaInfo, AggregationPolicy policy, List<PropertyProvider> providers) {
+        super(MetaInfoBuilder.of(metaInfo).setType("intersection").build());
+        this.providers = new ArrayList<>(providers);
+        aggregatedDelegate = PropertyProviderBuilder.create(getMetaInfo()).withAggregationPolicy(policy)
+                .addProviders(this.providers).build();
+    }
+
+    @Override
+    public Optional<String> get(String key) {
+        if (containsKey(key))
+            return aggregatedDelegate.get(key);
+        return Optional.empty();
+    }
+
+    private boolean filter(Map.Entry<String, String> entry) {
+        return containsKey(entry.getKey());
+    }
+
+    @Override
+    public boolean containsKey(String key) {
+        for (PropertyProvider prov : this.providers) {
+            if (!prov.containsKey(key)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Map<String, String> toMap() {
+        return aggregatedDelegate.toMap().entrySet().stream().filter(en -> containsKey(en.getKey())).collect(
+                Collectors.toConcurrentMap(en -> en.getKey(), en -> en.getValue()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/MapBasedPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/MapBasedPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/MapBasedPropertyProvider.java
new file mode 100644
index 0000000..bed43a8
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/MapBasedPropertyProvider.java
@@ -0,0 +1,107 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.ConfigChangeSet;
+import org.apache.tamaya.MetaInfo;
+import org.apache.tamaya.core.properties.AbstractPropertyProvider;
+
+import java.beans.PropertyChangeEvent;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+/**
+ * Models a {@link org.apache.tamaya.PropertyProvider} that can be build using a builder pattern.
+ */
+class MapBasedPropertyProvider extends AbstractPropertyProvider {
+
+    private static final long serialVersionUID = 7601389831472839249L;
+
+    private static final Logger LOG = Logger.getLogger(MapBasedPropertyProvider.class.getName());
+    /**
+     * The unit's entries.
+     */
+    private Map<String,String> entries = new ConcurrentHashMap<>();
+
+    /**
+     * Constructor.
+     *
+     * @param entries the config entries, not null.
+     */
+    MapBasedPropertyProvider(MetaInfo metaInfo, Map<String,String> entries){
+        super(metaInfo);
+        Objects.requireNonNull(entries, "entries required.");
+        this.entries.putAll(entries);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * @param entries the entries
+     * @param sources the sources
+     * @param errors  the errors
+     */
+    MapBasedPropertyProvider(MetaInfo metaInfo, Map<String,String> entries, Set<String> sources,
+                             Collection<Throwable> errors){
+        super(metaInfo);
+        Objects.requireNonNull(entries, "entries required.");
+        this.entries.putAll(entries);
+        addSources(sources);
+    }
+
+    MapBasedPropertyProvider(MetaInfo metaInfo, Set<String> sources){
+        super(metaInfo);
+        addSources(sources);
+    }
+
+    @Override
+    public Map<String, String> toMap() {
+        return new HashMap<>(this.entries);
+    }
+
+    @Override
+    public ConfigChangeSet load(){
+        // Can not reload...
+        return ConfigChangeSet.emptyChangeSet(this);
+    }
+
+    /**
+     * Apply a config change to this item. Hereby the change must be related to the same instance.
+     * @param change the config change
+     * @throws org.apache.tamaya.ConfigException if an unrelated change was passed.
+     * @throws UnsupportedOperationException when the configuration is not writable.
+     */
+    @Override
+    public void apply(ConfigChangeSet change){
+        change.getEvents().forEach(this::applyChange);
+    }
+
+    private void applyChange(PropertyChangeEvent propertyChangeEvent) {
+        LOG.finest(() -> "Applying change to map provider: " + propertyChangeEvent);
+        if(propertyChangeEvent.getNewValue()==null){
+            this.entries.remove(propertyChangeEvent.getPropertyName());
+        }
+        else{
+            this.entries.put(propertyChangeEvent.getPropertyName(), propertyChangeEvent.getNewValue().toString());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/PathBasedPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/PathBasedPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/PathBasedPropertyProvider.java
new file mode 100644
index 0000000..9faa467
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/PathBasedPropertyProvider.java
@@ -0,0 +1,85 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.*;
+import org.apache.tamaya.core.config.ConfigurationFormats;
+import org.apache.tamaya.core.properties.AbstractPropertyProvider;
+import org.apache.tamaya.core.resource.Resource;
+import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+import org.apache.tamaya.core.resource.ResourceLoader;
+
+import java.util.*;
+
+/**
+ * Created by Anatole on 16.10.2014.
+ */
+final class PathBasedPropertyProvider extends AbstractPropertyProvider {
+
+    private List<String> paths = new ArrayList<>();
+    private Map<String, String> properties = new HashMap<>();
+    private AggregationPolicy aggregationPolicy;
+
+    public PathBasedPropertyProvider(MetaInfo metaInfo, Collection<String> paths, AggregationPolicy aggregationPolicy) {
+        super(metaInfo);
+        this.paths.addAll(Objects.requireNonNull(paths));
+        this.aggregationPolicy = Objects.requireNonNull(aggregationPolicy);
+        init();
+    }
+
+    @Override
+    public Map<String, String> toMap() {
+        return this.properties;
+    }
+
+    private void init() {
+        List<String> sources = new ArrayList<>();
+        List<String> effectivePaths = new ArrayList<>();
+        paths.forEach((path) -> {
+            effectivePaths.add(path);
+            for (Resource res : Bootstrap.getService(ResourceLoader.class).getResources(path)) {
+                ConfigurationFormat format = ConfigurationFormats.getFormat(res);
+                if (format != null) {
+                    try {
+                        Map<String, String> read = format.readConfiguration(res);
+                        sources.add(res.toString());
+                        read.forEach((k, v) -> {
+                            String valueToAdd = aggregationPolicy.aggregate(k,properties.get(k),v);
+                            if(valueToAdd==null) {
+                                properties.remove(k);
+                            }
+                            else{
+                                properties.put(k, valueToAdd);
+                            }
+                        });
+                    }
+                    catch(ConfigException e){
+                        throw e;
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        });
+        metaInfo = MetaInfoBuilder.of(getMetaInfo())
+                .setSourceExpressions(new String[effectivePaths.size()])
+                .set("sources", sources.toString()).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/ReplacingPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/ReplacingPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/ReplacingPropertyProvider.java
new file mode 100644
index 0000000..aab6d6e
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/ReplacingPropertyProvider.java
@@ -0,0 +1,115 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.ConfigChangeSet;
+import org.apache.tamaya.MetaInfo;
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.PropertyProvider;
+
+import java.util.*;
+
+/**
+ * Implementation for a {@link org.apache.tamaya.PropertyProvider} that is an aggregate current
+ * multiple child instances, where all existing key/values in a replacementMap will
+ * replace values in a main map, if present there.
+ */
+class ReplacingPropertyProvider implements PropertyProvider{
+
+    private static final long serialVersionUID = -1419376385695224799L;
+    private PropertyProvider mainMap;
+    private Map<String,String> replacingMap;
+    private MetaInfo metaInfo;
+
+    /**
+     * Creates a mew instance, with aggregation polilcy
+     * {@code AggregationPolicy.OVERRIDE}.
+     *
+     * @param mainMap      The main ConfigMap.
+     * @param replacingMap The replacing ConfigMap.
+     */
+    public ReplacingPropertyProvider(MetaInfo metaInfo, PropertyProvider mainMap, Map<String,String> replacingMap){
+        this.replacingMap = Objects.requireNonNull(replacingMap);
+        this.mainMap = Objects.requireNonNull(mainMap);
+        if(metaInfo==null) {
+            this.metaInfo = MetaInfoBuilder.of().setType("replacing").set("mainProvider", mainMap.toString())
+                    .set("replacing", replacingMap.toString()).build();
+        }
+        else{
+            this.metaInfo = MetaInfoBuilder.of(metaInfo).setType("replacing").set("mainProvider", mainMap.toString())
+                    .set("replacing", replacingMap.toString()).build();
+        }
+    }
+
+    @Override
+    public ConfigChangeSet load(){
+        return mainMap.load();
+    }
+
+    @Override
+    public boolean containsKey(String key){
+        return mainMap.containsKey(key);
+    }
+
+    @Override
+    public Map<String,String> toMap(){
+        Map<String,String> result = new HashMap<>(replacingMap);
+        for(Map.Entry<String,String> en : mainMap.toMap().entrySet()){
+            if(!replacingMap.containsKey(en.getKey())){
+                result.put(en.getKey(), en.getValue());
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public MetaInfo getMetaInfo(){
+        return this.metaInfo;
+    }
+
+    @Override
+    public Optional<String> get(String key){
+        String val = replacingMap.get(key);
+        if(val == null){
+            return mainMap.get(key);
+        }
+        return Optional.ofNullable(val);
+    }
+
+    @Override
+    public Set<String> keySet(){
+        return mainMap.keySet();
+    }
+
+    /**
+     * Apply a config change to this item. Hereby the change must be related to the same instance.
+     * @param change the config change
+     * @throws org.apache.tamaya.ConfigException if an unrelated change was passed.
+     * @throws UnsupportedOperationException when the configuration is not writable.
+     */
+    @Override
+    public void apply(ConfigChangeSet change){
+        this.mainMap.apply(change);
+    }
+
+    @Override
+    public String toString(){
+        return super.toString() + "(mainMap=" + mainMap + ", replacingMap=" + replacingMap + ")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/SubtractingPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/SubtractingPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/SubtractingPropertyProvider.java
new file mode 100644
index 0000000..71faaf5
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/SubtractingPropertyProvider.java
@@ -0,0 +1,78 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.ConfigChangeSet;
+import org.apache.tamaya.MetaInfo;
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.PropertyProvider;
+import org.apache.tamaya.core.properties.AbstractPropertyProvider;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+class SubtractingPropertyProvider extends AbstractPropertyProvider {
+
+    private static final long serialVersionUID = 4301042530074932562L;
+    private PropertyProvider unit;
+    private List<PropertyProvider> subtrahends;
+
+    public SubtractingPropertyProvider(MetaInfo metaInfo, PropertyProvider configuration, List<PropertyProvider> subtrahends){
+        super(metaInfo==null?MetaInfoBuilder.of(configuration.getMetaInfo()).setType("subtracted").build():
+                MetaInfoBuilder.of(metaInfo).setType("subtracted").build());
+        Objects.requireNonNull(configuration);
+        this.unit = configuration;
+        this.subtrahends = new ArrayList<>(subtrahends);
+    }
+
+    private boolean filter(Map.Entry<String,String> entry){
+        for(PropertyProvider prov: subtrahends){
+            if(prov.containsKey(entry.getKey())){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Map<String,String> toMap(){
+        return this.unit.toMap().entrySet().stream().filter(this::filter).collect(Collectors.toMap(
+                (en) -> en.getKey(),
+                (en) -> en.getValue()
+        ));
+    }
+
+    @Override
+    public ConfigChangeSet load(){
+        unit.load();
+        return super.load();
+    }
+
+    /**
+     * Apply a config change to this item. Hereby the change must be related to the same instance.
+     * @param change the config change
+     * @throws org.apache.tamaya.ConfigException if an unrelated change was passed.
+     * @throws UnsupportedOperationException when the configuration is not writable.
+     */
+    @Override
+    public void apply(ConfigChangeSet change){
+        this.unit.apply(change);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/SystemPropertiesPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/SystemPropertiesPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/SystemPropertiesPropertyProvider.java
new file mode 100644
index 0000000..f3fe1da
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/SystemPropertiesPropertyProvider.java
@@ -0,0 +1,53 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.core.env.ConfiguredSystemProperties;
+import org.apache.tamaya.core.properties.AbstractPropertyProvider;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+class SystemPropertiesPropertyProvider extends AbstractPropertyProvider {
+
+
+    private static final long serialVersionUID = -5935940312707001199L;
+
+    public SystemPropertiesPropertyProvider(){
+        super(MetaInfoBuilder.of().setType("sys-properties").build());
+    }
+
+    @Override
+    public Map<String,String> toMap(){
+        Properties sysProps = System.getProperties();
+        if(sysProps instanceof ConfiguredSystemProperties){
+            sysProps = ((ConfiguredSystemProperties)sysProps).getInitialProperties();
+        }
+        Map<String,String> props = new HashMap<>();
+        for (Map.Entry<Object,Object> en : sysProps.entrySet()) {
+            props.put(en.getKey().toString(), en.getValue().toString());
+        }
+        return Collections.unmodifiableMap(props);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/properties/URLBasedPropertyProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/properties/URLBasedPropertyProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/properties/URLBasedPropertyProvider.java
new file mode 100644
index 0000000..72f51e8
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/properties/URLBasedPropertyProvider.java
@@ -0,0 +1,90 @@
+/*
+ * 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.core.internal.properties;
+
+import org.apache.tamaya.AggregationPolicy;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.MetaInfo;
+import org.apache.tamaya.MetaInfoBuilder;
+import org.apache.tamaya.core.config.ConfigurationFormats;
+import org.apache.tamaya.core.internal.resources.io.InputStreamResource;
+import org.apache.tamaya.core.internal.resources.io.UrlResource;
+import org.apache.tamaya.core.properties.AbstractPropertyProvider;
+import org.apache.tamaya.core.resource.InputStreamSource;
+import org.apache.tamaya.core.resource.Resource;
+import org.apache.tamaya.core.spi.ConfigurationFormat;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+import java.util.function.Supplier;
+
+/**
+ * Created by Anatole on 16.10.2014.
+ */
+final class URLBasedPropertyProvider extends AbstractPropertyProvider {
+
+    private List<URL> resources = new ArrayList<>();
+    private Map<String,String> properties = new HashMap<>();
+    private AggregationPolicy aggregationPolicy;
+
+    public URLBasedPropertyProvider(MetaInfo metaInfo, List<URL> resources, AggregationPolicy aggregationPolicy) {
+        super(metaInfo);
+        this.resources.addAll(Objects.requireNonNull(resources));
+        this.aggregationPolicy = Objects.requireNonNull(aggregationPolicy);
+        init();
+    }
+
+    private void init(){
+        List<String> sources = new ArrayList<>();
+        for(URL url : resources){
+            Resource res = new UrlResource(url);
+            ConfigurationFormat format = ConfigurationFormats.getFormat(res);
+            if(format != null){
+                try{
+                    Map<String, String> read = format.readConfiguration(res);
+                    sources.add(res.toString());
+                    read.forEach((k, v) -> {
+                        String newValue = aggregationPolicy.aggregate(k, properties.get(k), v);
+                        if(newValue==null) {
+                            properties.remove(k);
+                        }
+                        else {
+                            properties.put(k, newValue);
+                        }
+                    });
+                }
+                catch(ConfigException e){
+                    throw e;
+                }
+                catch(Exception e){
+                    e.printStackTrace();
+                }
+            }
+        }
+        MetaInfoBuilder metaInfoBuilder = MetaInfoBuilder.of(getMetaInfo());
+        metaInfo = metaInfoBuilder
+                .setSources(sources.toString()).build();
+    }
+
+    @Override
+    public Map<String, String> toMap() {
+        return properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.java
index 8ba662c..5ca68eb 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathResolver.java
@@ -19,17 +19,17 @@
 package org.apache.tamaya.core.internal.resources;
 
 import org.apache.tamaya.core.internal.resources.io.PathMatchingResourcePatternResolver;
-import org.apache.tamaya.core.internal.resources.io.Resource;
+import org.apache.tamaya.core.spi.PathResolver;
+import org.apache.tamaya.core.resource.Resource;
 
 import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
 import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
-public class AntPathClasspathResolver implements PathResolver{
+public class AntPathClasspathResolver implements PathResolver {
+
+    private static final Logger LOG = Logger.getLogger(AntPathClasspathResolver.class.getName());
 
     @Override
     public String getResolverId(){
@@ -37,39 +37,24 @@ public class AntPathClasspathResolver implements PathResolver{
     }
 
     @Override
-    public Collection<URI> resolve(ClassLoader classLoader, Collection<String> expressions){
+    public Collection<Resource> resolve(ClassLoader classLoader, Collection<String> expressions){
         PathMatchingResourcePatternResolver resolver = PathMatchingResourcePatternResolver.of(classLoader);
-        List<URI> result = new ArrayList<>();
+        List<Resource> result = new ArrayList<>();
         expressions.forEach((expression) -> {
             try {
                 Resource[] resources = resolver.getResources(expression);
                 for (Resource res : resources) {
                     try {
-                        result.add(res.getURI());
+                        result.add(res);
                     } catch (Exception e) {
-                        // TODO Auto-generated catch block
-                        e.printStackTrace();
+                        LOG.log(Level.FINEST, "URI could not be extracted from Resource: " + res.toString(), e);
                     }
                 }
             }
             catch(IOException e){
-                // TODO log
+                LOG.log(Level.FINE, "Failed to load resource expression: " + expression.toString(), e);
             }
         });
-//            if(expression.startsWith("classpath:")){
-//                String exp = expression.substring("classpath:".length());
-//                URL url = classLoader.getResource(exp);
-//                if(url != null){
-//                    try{
-//                        result.add(url.toURI());
-//                    }
-//                    catch(URISyntaxException e){
-//                        // TODO Auto-generated catch block
-//                        e.printStackTrace();
-//                    }
-//                }
-//            }
-//        });
         return result;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java
index 37852f4..6af3b42 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathClasspathsResolver.java
@@ -1,85 +1,56 @@
-/*
- * 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.core.internal.resources;
-
-import org.apache.tamaya.core.internal.resources.io.PathMatchingResourcePatternResolver;
-import org.apache.tamaya.core.internal.resources.io.Resource;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.*;
-import java.util.stream.Stream;
-
-public class AntPathClasspathsResolver implements PathResolver{
-
-    @Override
-    public String getResolverId(){
-        return "classpath*";
-    }
-
-    @Override
-    public Collection<URI> resolve(ClassLoader classLoader, Collection<String> expressions){
-        PathMatchingResourcePatternResolver resolver = PathMatchingResourcePatternResolver.of(classLoader);
-        List<URI> result = new ArrayList<>();
-        expressions.forEach((expression) -> {
-            try {
-                Resource[] resources = resolver.getResources(expression);
-                for (Resource res : resources) {
-                    try {
-                        result.add(res.getURI());
-                    } catch (Exception e) {
-                        // TODO Auto-generated catch block
-                        e.printStackTrace();
-                    }
-                }
-            }
-            catch(IOException e){
-                // TODO log
-            }
-        });
-//        List<URI> result = new ArrayList<>();
-//        Objects.requireNonNull(classLoader);
+///*
+// * 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.core.internal.resources;
+//
+//import org.apache.tamaya.core.internal.resources.io.PathMatchingResourcePatternResolver;
+//import org.apache.tamaya.core.spi.PathResolver;
+//import org.apache.tamaya.core.resource.Resource;
+//
+//import java.io.IOException;
+//import java.util.*;
+//import java.util.logging.Level;
+//import java.util.logging.Logger;
+//
+//public class AntPathClasspathsResolver implements PathResolver {
+//
+//    private static final Logger LOG = Logger.getLogger(AntPathClasspathResolver.class.getName());
+//
+//    @Override
+//    public String getResolverId(){
+//        return "classpath*";
+//    }
+//
+//    @Override
+//    public Collection<Resource> resolve(ClassLoader classLoader, Collection<String> expressions){
+//        PathMatchingResourcePatternResolver resolver = PathMatchingResourcePatternResolver.of(classLoader);
+//        List<Resource> result = new ArrayList<>();
 //        expressions.forEach((expression) -> {
-//            if(expression.startsWith("classpath*:")){
-//                String exp = expression.substring("classpath*:".length());
-//                Enumeration<URL> urls;
-//                try{
-//                    urls = classLoader.getResources(exp);
-//                    while(urls.hasMoreElements()){
-//                        URL url = (URL) urls.nextElement();
-//                        try{
-//                            result.add(url.toURI());
-//                        }
-//                        catch(URISyntaxException e){
-//                            // TODO Auto-generated catch block
-//                            e.printStackTrace();
-//                        }
-//                    }
-//                }
-//                catch(IOException e1){
-//                    // TODO Auto-generated catch block
-//                    e1.printStackTrace();
+//            try {
+//                Resource[] resources = resolver.getResources(expression);
+//                for (Resource res : resources) {
+//                    result.add(res);
 //                }
 //            }
+//            catch(IOException e){
+//                LOG.log(Level.FINE, "Failed to load resource expression: " + expression, e);
+//            }
 //        });
-        return result;
-    }
-}
+//        return result;
+//    }
+//}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFileResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFileResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFileResolver.java
index 532a92f..477bc85 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFileResolver.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFileResolver.java
@@ -19,16 +19,18 @@
 package org.apache.tamaya.core.internal.resources;
 
 import org.apache.tamaya.core.internal.resources.io.PathMatchingResourcePatternResolver;
-import org.apache.tamaya.core.internal.resources.io.Resource;
+import org.apache.tamaya.core.spi.PathResolver;
+import org.apache.tamaya.core.resource.Resource;
 
-import java.io.File;
 import java.io.IOException;
-import java.net.URI;
 import java.util.*;
-import java.util.stream.Stream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 
-public class AntPathFileResolver implements PathResolver{
+public class AntPathFileResolver implements PathResolver {
+
+    private static final Logger LOG = Logger.getLogger(AntPathFileResolver.class.getName());
 
     @Override
     public String getResolverId(){
@@ -36,23 +38,22 @@ public class AntPathFileResolver implements PathResolver{
     }
 
     @Override
-    public Collection<URI> resolve(ClassLoader classLoader, Collection<String> expressions){
+    public Collection<Resource> resolve(ClassLoader classLoader, Collection<String> expressions){
         PathMatchingResourcePatternResolver resolver = PathMatchingResourcePatternResolver.of(classLoader);
-        List<URI> result = new ArrayList<>();
+        List<Resource> result = new ArrayList<>();
         expressions.forEach((expression) -> {
             try {
                 Resource[] resources = resolver.getResources(expression);
                 for (Resource res : resources) {
                     try {
-                        result.add(res.getURI());
+                        result.add(res);
                     } catch (Exception e) {
-                        // TODO Auto-generated catch block
-                        e.printStackTrace();
+                        LOG.log(Level.FINE, "URI could not be extracted from Resource: " + res.toString(), e);
                     }
                 }
             }
             catch(IOException e){
-                // TODO log
+                LOG.log(Level.FINE, "Failed to load resource expression: " + expression.toString(), e);
             }
         });
         return result;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFilesResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFilesResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFilesResolver.java
index 03f39ae..c0b16c1 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFilesResolver.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/AntPathFilesResolver.java
@@ -1,59 +1,62 @@
-/*
- * 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.core.internal.resources;
-
-import org.apache.tamaya.core.internal.resources.io.PathMatchingResourcePatternResolver;
-import org.apache.tamaya.core.internal.resources.io.Resource;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.util.*;
-import java.util.stream.Stream;
-
-public class AntPathFilesResolver implements PathResolver{
-
-    @Override
-    public String getResolverId(){
-        return "file*";
-    }
-
-    @Override
-    public Collection<URI> resolve(ClassLoader classLoader, Collection<String> expressions){
-        PathMatchingResourcePatternResolver resolver = PathMatchingResourcePatternResolver.of(classLoader);
-        List<URI> result = new ArrayList<>();
-        expressions.forEach((expression) -> {
-            try {
-                Resource[] resources = resolver.getResources(expression);
-                for (Resource res : resources) {
-                    try {
-                        result.add(res.getURI());
-                    } catch (Exception e) {
-                        // TODO Auto-generated catch block
-                        e.printStackTrace();
-                    }
-                }
-            }
-            catch(IOException e){
-                // TODO log
-            }
-        });
-        return result;
-    }
-}
+///*
+// * 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.core.internal.resources;
+//
+//import org.apache.tamaya.core.internal.resources.io.PathMatchingResourcePatternResolver;
+//import org.apache.tamaya.core.spi.PathResolver;
+//import org.apache.tamaya.core.resource.Resource;
+//
+//import java.io.IOException;
+//import java.util.*;
+//import java.util.logging.Level;
+//import java.util.logging.Logger;
+//
+//public class AntPathFilesResolver implements PathResolver {
+//
+//    private static final Logger LOG = Logger.getLogger(AntPathFileResolver.class.getName());
+//
+//    @Override
+//    public String getResolverId(){
+//        return "file*";
+//    }
+//
+//    @Override
+//    public Collection<Resource> resolve(ClassLoader classLoader, Collection<String> expressions){
+//        PathMatchingResourcePatternResolver resolver = PathMatchingResourcePatternResolver.of(classLoader);
+//        List<Resource> result = new ArrayList<>();
+//        expressions.forEach((expression) -> {
+//            try {
+//                Resource[] resources = resolver.getResources(expression);
+//                for (Resource res : resources) {
+//                    try {
+//                        if(res.exists()) {
+//                            result.add(res);
+//                        }
+//                    } catch (Exception e) {
+//                        LOG.log(Level.FINE, "URI could not be extracted from Resource: " + res.toString(), e);
+//                    }
+//                }
+//            }
+//            catch(IOException e){
+//                LOG.log(Level.FINE, "Failed to load resource expression: " + expression.toString(), e);
+//            }
+//        });
+//        return result;
+//    }
+//}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/DefaultPathResourceLoader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/DefaultPathResourceLoader.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/DefaultPathResourceLoader.java
index 0a82f77..ad7dc1d 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/DefaultPathResourceLoader.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/DefaultPathResourceLoader.java
@@ -18,15 +18,15 @@
  */
 package org.apache.tamaya.core.internal.resources;
 
-import org.apache.tamaya.core.spi.ResourceLoader;
+import org.apache.tamaya.core.spi.PathResolver;
+import org.apache.tamaya.core.resource.Resource;
+import org.apache.tamaya.core.resource.ResourceLoader;
 
 import org.apache.tamaya.spi.Bootstrap;
 
-import java.net.URI;
 import java.util.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.stream.Stream;
 
 /**
  * Singleton accessor to access registered reader mechanism.
@@ -45,16 +45,16 @@ public class DefaultPathResourceLoader implements ResourceLoader{
     }
 
     @Override
-    public List<URI> getResources(String... expressions){
+    public List<Resource> getResources(String... expressions){
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
         if(cl==null){
             cl = getClass().getClassLoader();
         }
-        return getResources(cl, expressions);
+        return getResources(cl, Arrays.asList(expressions));
     }
 
     @Override
-    public List<URI> getResources(Collection<String> expressions){
+    public List<Resource> getResources(Collection<String> expressions){
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
         if(cl==null){
             cl = getClass().getClassLoader();
@@ -63,30 +63,21 @@ public class DefaultPathResourceLoader implements ResourceLoader{
     }
 
     @Override
-    public List<URI> getResources(ClassLoader classLoader, String... expressions){
-        List<URI> uris = new ArrayList<>();
-        for(PathResolver resolver : Bootstrap.getServices(PathResolver.class)){
-            try {
-                uris.addAll(resolver.resolve(classLoader, Arrays.asList(expressions)));
-            }
-            catch(Exception e){
-                LOG.log(Level.FINEST, e, () -> "Resource not found: " + Arrays.toString(expressions));
-            }
-        }
-        return uris;
+    public List<Resource> getResources(ClassLoader classLoader, String... expressions) {
+        return getResources(classLoader, Arrays.asList(expressions));
     }
 
     @Override
-    public List<URI> getResources(ClassLoader classLoader, Collection<String> expressions){
-        List<URI> uris = new ArrayList<>();
+    public List<Resource> getResources(ClassLoader classLoader, Collection<String> expressions){
+        List<Resource> resources = new ArrayList<>();
         for(PathResolver resolver : Bootstrap.getServices(PathResolver.class)){
             try{
-                uris.addAll(resolver.resolve(classLoader, expressions));
+                resources.addAll(resolver.resolve(classLoader, expressions));
             }
             catch(Exception e){
                 LOG.log(Level.FINEST, e, () -> "Resource not found: " + expressions.toString());
             }
         }
-        return uris;
+        return resources;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/PathResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/PathResolver.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/PathResolver.java
deleted file mode 100644
index faaef3b..0000000
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/PathResolver.java
+++ /dev/null
@@ -1,45 +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.core.internal.resources;
-
-import java.net.URI;
-import java.util.Collection;
-import java.util.stream.Stream;
-
-/**
- * Created by Anatole on 16.06.2014.
- */
-public interface PathResolver{
-
-    /**
-     * Get the (unique) resolver prefix.
-     *
-     * @return the resolver prefix, never null.
-     */
-    public String getResolverId();
-
-    /**
-     * Resolve the given expression.
-     *
-     * @param expressions expressions, never null.
-     * @return the resolved URIs, never null.
-     */
-    public Collection<URI> resolve(ClassLoader classLoader, Collection<String> expressions);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractFileResolvingResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractFileResolvingResource.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractFileResolvingResource.java
index 391c683..ff35687 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractFileResolvingResource.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractFileResolvingResource.java
@@ -16,6 +16,8 @@
 
 package org.apache.tamaya.core.internal.resources.io;
 
+import org.apache.tamaya.core.resource.Resource;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractResource.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractResource.java
index d218447..a8a3ba3 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractResource.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/AbstractResource.java
@@ -15,6 +15,8 @@
  */
 package org.apache.tamaya.core.internal.resources.io;
 
+import org.apache.tamaya.core.resource.Resource;
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -26,7 +28,7 @@ import java.util.Objects;
 
 
 /**
- * Convenience base class for {@link Resource} implementations,
+ * Convenience base class for {@link org.apache.tamaya.core.resource.Resource} implementations,
  * pre-implementing typical behavior.
  *
  * <p>The "exists" method will check whether a File or InputStream can
@@ -115,7 +117,7 @@ public abstract class AbstractResource implements Resource {
 	 * This implementation reads the entire InputStream to calculate the
 	 * content length. Subclasses will almost always be able to provide
 	 * a more optimal version current this, e.g. checking a File length.
-	 * @throws IllegalStateException if {@code #getInputStream()} returns null.
+	 * @throws IllegalStateException if {@code #getInputStreamSupplier()} returns null.
 	 */
 	@Override
 	public long contentLength() throws IOException {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ClassPathResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ClassPathResource.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ClassPathResource.java
index fe08e9d..65c30aa 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ClassPathResource.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/ClassPathResource.java
@@ -15,6 +15,8 @@
  */
 package org.apache.tamaya.core.internal.resources.io;
 
+import org.apache.tamaya.core.resource.Resource;
+
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -22,7 +24,7 @@ import java.net.URL;
 import java.util.Objects;
 
 /**
- * {@link Resource} implementation for class path resources.
+ * {@link org.apache.tamaya.core.resource.Resource} implementation for class path resources.
  * Uses either a given ClassLoader or a given Class for loading resources.
  *
  * <p>Supports resolution as {@code java.io.File} if the class path

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java
index 1a7ff07..9ae49e7 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/DefaultResourceLoader.java
@@ -16,6 +16,8 @@
 
 package org.apache.tamaya.core.internal.resources.io;
 
+import org.apache.tamaya.core.resource.Resource;
+
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Objects;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java
index 32991bf..d1a401d 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/FileSystemResource.java
@@ -16,6 +16,8 @@
 
 package org.apache.tamaya.core.internal.resources.io;
 
+import org.apache.tamaya.core.resource.Resource;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -27,7 +29,7 @@ import java.net.URL;
 import java.util.Objects;
 
 /**
- * {@link Resource} implementation for {@code java.io.File} handles.
+ * {@link org.apache.tamaya.core.resource.Resource} implementation for {@code java.io.File} handles.
  * Obviously supports resolution as File, and also as URL.
  *
  * @author Juergen Hoeller

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/0eef8f37/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java
index 1229175..4fe958e 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/resources/io/InputStreamResource.java
@@ -18,9 +18,11 @@ package org.apache.tamaya.core.internal.resources.io;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Objects;
+import java.util.function.Supplier;
 
 /**
- * {@link Resource} implementation for a given InputStream. Should only
+ * {@link org.apache.tamaya.core.resource.Resource} implementation for a given InputStream. Should only
  * be used if no specific Resource implementation is applicable.
  * In particular, prefer {@code ByteArrayResource} or any current the
  * file-based Resource implementations where possible.
@@ -56,10 +58,7 @@ public class InputStreamResource extends AbstractResource {
 	 * @param description where the InputStream comes from
 	 */
 	public InputStreamResource(InputStream inputStream, String description) {
-		if (inputStream == null) {
-			throw new IllegalArgumentException("InputStream must not be null");
-		}
-		this.inputStream = inputStream;
+		this.inputStream = Objects.requireNonNull(inputStream);
 		this.description = (description != null ? description : "");
 	}