You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by st...@apache.org on 2014/12/27 14:57:54 UTC

[10/34] incubator-tamaya git commit: first step: move all sources to a 'dormant' directory

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/ContextualPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/ContextualPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ContextualPropertySource.java
new file mode 100644
index 0000000..6290706
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ContextualPropertySource.java
@@ -0,0 +1,142 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.*;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Supplier;
+
+/**
+ * Created by Anatole on 12.04.2014.
+ */
+class ContextualPropertySource implements PropertySource {
+
+    private volatile Map<String,PropertySource> cachedMaps = new ConcurrentHashMap<>();
+
+    private Supplier<PropertySource> mapSupplier;
+    private Supplier<String> isolationKeySupplier;
+    private String name;
+
+
+    /**
+     * Creates a new contextual PropertyMap. Contextual maps delegate to different instances current PropertyMap depending
+     * on the keys returned fromMap the isolationP
+     *
+     * @param mapSupplier
+     * @param isolationKeySupplier
+     */
+    public ContextualPropertySource(String name, Supplier<PropertySource> mapSupplier, Supplier<String> isolationKeySupplier){
+        this.name = Optional.ofNullable(name).orElse("<noname>");
+        Objects.requireNonNull(mapSupplier);
+        Objects.requireNonNull(isolationKeySupplier);
+        this.mapSupplier = mapSupplier;
+        this.isolationKeySupplier = isolationKeySupplier;
+    }
+
+    /**
+     * This method provides the contextual Map for the current environment. Hereby, ba default, for each different
+     * key returned by the #isolationKeySupplier a separate PropertyMap instance is acquired fromMap the #mapSupplier.
+     * If the map supplier returns an instance it is cached in the local #cachedMaps.
+     *
+     * @return the current contextual PropertyMap.
+     */
+    protected PropertySource getContextualMap(){
+        String environmentKey = this.isolationKeySupplier.get();
+        if(environmentKey == null){
+            return PropertySource.EMPTY_PROPERTYSOURCE;
+        }
+        PropertySource map = this.cachedMaps.get(environmentKey);
+        if(map == null){
+            synchronized(cachedMaps){
+                map = this.cachedMaps.get(environmentKey);
+                if(map == null){
+                    map = this.mapSupplier.get();
+                    if(map == null){
+                        return PropertySource.EMPTY_PROPERTYSOURCE;
+                    }
+                    this.cachedMaps.put(environmentKey, map);
+                }
+            }
+        }
+        return map;
+    }
+
+    @Override
+    public Map<String,String> getProperties(){
+        return getContextualMap().getProperties();
+    }
+
+    @Override
+    public String getName(){
+        return this.name;
+    }
+
+    @Override
+    public Optional<String> get(String key){
+        return getContextualMap().get(key);
+    }
+
+    /**
+     * Access a cached PropertyMap.
+     *
+     * @param key the target environment key as returned by the environment key supplier, not null.
+     * @return the corresponding PropertyMap, or null.
+     */
+    public PropertySource getCachedMap(String key){
+        return this.cachedMaps.get(key);
+    }
+
+    /**
+     * Access the set current currently loaded/cached maps.
+     *
+     * @return the set current cached map keys, never null.
+     */
+    public Set<String> getCachedMapKeys(){
+        return this.cachedMaps.keySet();
+    }
+
+    /**
+     * Access the supplier for environment key, determining map isolation.
+     *
+     * @return the environment key supplier instance, not null.
+     */
+    public Supplier<String> getIsolationKeySupplier(){
+        return this.isolationKeySupplier;
+    }
+
+    /**
+     * Access the supplier for new PropertyMap instances.
+     *
+     * @return the PropertyMap supplier instance, not null.
+     */
+    public Supplier<PropertySource> getMapSupplier(){
+        return this.mapSupplier;
+    }
+
+    @Override
+    public String toString(){
+        return "ContextualMap{" +
+                "cachedMaps(key)=" + cachedMaps.keySet() +
+                ", mapSupplier=" + mapSupplier +
+                ", isolationKeySupplier=" + isolationKeySupplier +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/DelegatingPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/DelegatingPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/DelegatingPropertySource.java
new file mode 100644
index 0000000..c4bfc92
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/DelegatingPropertySource.java
@@ -0,0 +1,79 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.*;
+
+/**
+ * Implementation for a {@link org.apache.tamaya.PropertySource} 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 DelegatingPropertySource implements PropertySource {
+
+    private PropertySource mainMap;
+    private Map<String,String> parentMap;
+    private String name;
+
+
+    /**
+     * Creates a mew instance, with aggregation polilcy
+     * {@code AggregationPolicy.OVERRIDE}.
+     *
+     * @param mainMap   The main ConfigMap.
+     * @param parentMap The delegated parent ConfigMap.
+     */
+    public DelegatingPropertySource(String name, PropertySource mainMap, Map<String, String> parentMap){
+        this.name = Optional.of(name).orElse("<noname>");
+        this.parentMap = Objects.requireNonNull(parentMap);
+        this.parentMap = Objects.requireNonNull(parentMap);
+    }
+
+    @Override
+    public Map<String,String> getProperties(){
+        return null;
+    }
+
+    @Override
+    public String getName(){
+        return this.name;
+    }
+
+    @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 String toString(){
+        return super.toString() + "(mainMap=" + mainMap + ", delegate=" + parentMap + ")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/EnvironmentPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/EnvironmentPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/EnvironmentPropertySource.java
new file mode 100644
index 0000000..d0b2172
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/EnvironmentPropertySource.java
@@ -0,0 +1,40 @@
+/*
+ * 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.properties;
+
+import java.util.Map;
+
+class EnvironmentPropertySource extends AbstractPropertySource {
+
+    private static final long serialVersionUID = 4753258482658331010L;
+
+    public Map<String,String> getProperties(){
+        return System.getenv();
+    }
+
+    public EnvironmentPropertySource(){
+        super("<System.getenv()>");
+    }
+
+    @Override
+    public String toString(){
+        return "EnvironmentPropertyProvider[" + System.getenv().size() + " environment properties]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/FileSystemPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/FileSystemPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FileSystemPropertySource.java
new file mode 100644
index 0000000..b3aca71
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FileSystemPropertySource.java
@@ -0,0 +1,97 @@
+/*
+ * 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.properties;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class FileSystemPropertySource extends AbstractClasspathAwarePropertySource {
+
+	private static final Logger LOG = Logger.getLogger(FileSystemPropertySource.class.getName());
+    private static final long serialVersionUID = -2016119697552480056L;
+	private Map<String, Map<String, String>> propMetaInfo = new HashMap<>();
+
+	public FileSystemPropertySource(String resourcePath, ClassLoader classLoader,
+                                    AbstractClasspathAwarePropertySource parentConfig) {
+		super(classLoader, parentConfig, resourcePath);
+	}
+
+	public FileSystemPropertySource(String resourcePath, AbstractClasspathAwarePropertySource parentConfig) {
+		super(getCurrentClassLoader(), parentConfig, resourcePath);
+	}
+
+	public FileSystemPropertySource(String resourcePath) {
+		super(getCurrentClassLoader(), null, resourcePath);
+	}
+
+
+	@Override
+	protected void readSource(Map<String, String> targetMap, String src) {
+		try (InputStream is = getClassLoader().getResource(
+				src).openStream()) {
+			Properties props = new Properties();
+			URL resource = getClassLoader().getResource(
+					src);
+//			if (isSourceRead(resource.toString())) {
+//				// continue;
+//				return;
+//			}
+			addSource(resource.toString());
+			Map<String, String> mi = new HashMap<>();
+			mi.put("source", resource.toString());
+			if (Thread.currentThread().getContextClassLoader() != null) {
+				mi.put("classloader", Thread.currentThread()
+						.getContextClassLoader().toString());
+			}
+			props.load(is);
+			for (Map.Entry<Object, Object> en : props.entrySet()) {
+                targetMap.put(en.getKey().toString(),
+						en.getValue().toString());
+				propMetaInfo.put(en.getKey().toString(),
+						mi);
+			}
+		} catch (IOException e) {
+			LOG.log(Level.SEVERE, "Error loading config unit.", e);
+		}
+	}
+
+	protected Map<String, String> getMetaInfo(String key, String value) {
+		Map<String, String> mi = propMetaInfo.get(key);
+		if (mi != null) {
+			return mi;
+		}
+		return Collections.emptyMap();
+	}
+
+	private static ClassLoader getCurrentClassLoader() {
+		ClassLoader cl = Thread.currentThread().getContextClassLoader();
+		if (cl == null) {
+			return FileSystemPropertySource.class.getClassLoader();
+		}
+		return cl;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/FilteredPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/FilteredPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FilteredPropertySource.java
new file mode 100644
index 0000000..a0c1a53
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FilteredPropertySource.java
@@ -0,0 +1,51 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+class FilteredPropertySource extends AbstractPropertySource {
+
+    private static final long serialVersionUID = 4301042530074932562L;
+    private PropertySource unit;
+    private Predicate<String> filter;
+
+    public FilteredPropertySource(String name, PropertySource configuration, Predicate<String> filter){
+        super(name==null?Objects.requireNonNull(configuration).getName():name);
+        this.unit = configuration;
+        this.filter = filter;
+    }
+
+    @Override
+    public Map<String,String> getProperties(){
+        final Map<String,String> result = new HashMap<>();
+        this.unit.getProperties().entrySet().forEach(e -> {
+            if(filter.test(e.getKey())){
+                result.put(e.getKey(), e.getValue());
+            }
+        });
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/FreezedPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/FreezedPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FreezedPropertySource.java
new file mode 100644
index 0000000..f0e5eec
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/FreezedPropertySource.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.properties;
+
+import java.io.Serializable;
+import java.util.*;
+
+import org.apache.tamaya.PropertySource;
+
+/**
+ * This class models a freezed instance current an {@link org.apache.tamaya.PropertySource}.
+ * Created by Anatole on 28.03.14.
+ */
+final class FreezedPropertySource implements PropertySource, Serializable{
+
+    private static final long serialVersionUID = 3365413090311267088L;
+    private String name;
+    private Map<String,String> properties = new HashMap<>();
+
+    private FreezedPropertySource(String name, PropertySource propertyMap) {
+        Map<String, String> map = propertyMap.getProperties();
+        this.properties.putAll(map);
+        this.properties = Collections.unmodifiableMap(this.properties);
+        this.name = Optional.ofNullable(name).orElse(propertyMap.getName()+"(freezed)");
+    }
+
+    public static PropertySource of(String name, PropertySource propertyProvider){
+        if(propertyProvider instanceof FreezedPropertySource){
+            return propertyProvider;
+        }
+        return new FreezedPropertySource(name, propertyProvider);
+    }
+
+    public int size(){
+        return properties.size();
+    }
+
+    public boolean isEmpty(){
+        return properties.isEmpty();
+    }
+
+    @Override
+    public Map<String,String> getProperties(){
+        return Collections.unmodifiableMap(this.properties);
+    }
+
+    @Override
+    public String getName(){
+        return this.name;
+    }
+
+    @Override
+    public Optional<String> get(String key){
+        return Optional.ofNullable(properties.get(key));
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/IntersectingPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/IntersectingPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/IntersectingPropertySource.java
new file mode 100644
index 0000000..d7c46d2
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/IntersectingPropertySource.java
@@ -0,0 +1,55 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.*;
+
+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 IntersectingPropertySource extends AbstractPropertySource {
+
+	private static final long serialVersionUID = -1492990130201110889L;
+	private List<PropertySource> providers;
+    private PropertySource aggregatedDelegate;
+
+    public IntersectingPropertySource(String name, AggregationPolicy policy, List<PropertySource> providers) {
+        super(name);
+        this.providers = new ArrayList<>(providers);
+        aggregatedDelegate = PropertySourceBuilder.of(name).withAggregationPolicy(policy)
+                .addProviders(this.providers).build();
+    }
+
+    @Override
+    public Optional<String> get(String key) {
+        return aggregatedDelegate.get(key);
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return aggregatedDelegate.getProperties().entrySet().stream().filter(en -> get(en.getKey()).isPresent()).collect(
+                Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/MapBasedPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/MapBasedPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/MapBasedPropertySource.java
new file mode 100644
index 0000000..41b730e
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/MapBasedPropertySource.java
@@ -0,0 +1,75 @@
+/*
+ * 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.properties;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+/**
+ * Models a {@link org.apache.tamaya.PropertySource} that can be build using a builder pattern.
+ */
+class MapBasedPropertySource extends AbstractPropertySource {
+
+    private static final long serialVersionUID = 7601389831472839249L;
+
+    private static final Logger LOG = Logger.getLogger(MapBasedPropertySource.class.getName());
+    /**
+     * The unit's entries.
+     */
+    private Map<String,String> entries = new ConcurrentHashMap<>();
+
+    /**
+     * Constructor.
+     *
+     * @param entries the config entries, not null.
+     */
+    MapBasedPropertySource(String name, Map<String, String> entries){
+        super(name);
+        Objects.requireNonNull(entries, "entries required.");
+        this.entries.putAll(entries);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * @param entries the entries
+     * @param sources the sources
+     * @param errors  the errors
+     */
+    MapBasedPropertySource(String name, Map<String, String> entries, Set<String> sources,
+                           Collection<Throwable> errors){
+        super(name);
+        Objects.requireNonNull(entries, "entries required.");
+        this.entries.putAll(entries);
+        addSources(sources);
+    }
+
+    MapBasedPropertySource(String name, Set<String> sources){
+        super(name);
+        addSources(sources);
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return new HashMap<>(this.entries);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/PathBasedPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/PathBasedPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PathBasedPropertySource.java
new file mode 100644
index 0000000..80184d1
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PathBasedPropertySource.java
@@ -0,0 +1,83 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.*;
+import org.apache.tamaya.core.resource.Resource;
+import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.core.resource.ResourceLoader;
+
+import java.util.*;
+
+/**
+ * Implementation of a PropertySource that reads configuration from some given resource paths.
+ */
+final class PathBasedPropertySource extends AbstractPropertySource {
+
+	private static final long serialVersionUID = 5147019699905042582L;
+	private List<String> paths = new ArrayList<>();
+    private Map<String, String> properties = new HashMap<>();
+    private AggregationPolicy aggregationPolicy;
+
+    public PathBasedPropertySource(String name, Collection<String> paths, AggregationPolicy aggregationPolicy) {
+        super(name);
+        this.paths.addAll(Objects.requireNonNull(paths));
+        this.aggregationPolicy = Objects.requireNonNull(aggregationPolicy);
+        init();
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        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 : ServiceContext.getInstance().getSingleton(ResourceLoader.class).getResources(path)) {
+                ConfigurationFormat format = ConfigurationFormat.from(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/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceBuilder.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceBuilder.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceBuilder.java
new file mode 100644
index 0000000..b099230
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceBuilder.java
@@ -0,0 +1,477 @@
+/*
+* 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.properties;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import org.apache.tamaya.PropertySource;
+
+/**
+* Builder for assembling non trivial property providers.
+*/
+public final class PropertySourceBuilder {
+
+    /**
+     * Name used for the final result.
+     */
+    private String name;
+
+    /**
+     * Name used for the next operation.
+     */
+    private String currentName;
+
+    /**
+     * the current property provider, or null.
+     */
+    private PropertySource current;
+    /**
+     * The current aggregation policy used, when aggregating providers.
+     */
+    private AggregationPolicy aggregationPolicy = AggregationPolicy.OVERRIDE;
+
+    /**
+     * Private singleton constructor.
+     */
+    private PropertySourceBuilder(String name) {
+        this.name = Objects.requireNonNull(name);
+    }
+
+    /**
+     * Private singleton constructor.
+     */
+    private PropertySourceBuilder(String name, PropertySource propertySource) {
+        this.name = Objects.requireNonNull(name);
+        this.current = propertySource;
+    }
+
+    /**
+     * Creates a new builder instance.
+     *
+     * @param name the provider name, not null.
+     * @param provider the base provider to be used, not null.
+     * @return a new builder instance, never null.
+     */
+    public static PropertySourceBuilder of(String name, PropertySource provider) {
+        return new PropertySourceBuilder(name, provider);
+    }
+
+    /**
+     * Creates a new builder instance.
+     *
+     * @param provider the base provider to be used, not null.
+     * @return a new builder instance, never null.
+     */
+    public static PropertySourceBuilder of(PropertySource provider) {
+        return new PropertySourceBuilder(provider.getName(), provider);
+    }
+
+
+    /**
+     * Creates a new builder instance.
+     *
+     * @param name the provider name, not null.
+     * @return a new builder instance, never null.
+     */
+    public static PropertySourceBuilder of(String name) {
+        return new PropertySourceBuilder(Objects.requireNonNull(name));
+    }
+
+    /**
+     * Creates a new builder instance.
+     *
+     * @return a new builder instance, never null.
+     */
+    public static PropertySourceBuilder of() {
+        return new PropertySourceBuilder("<noname>");
+    }
+
+
+
+
+    /**
+     * Sets the aggregation policy to be used, when adding additional property sets. The policy will
+     * be active a slong as the builder is used or it is reset to another keys.
+     *
+     * @param aggregationPolicy the aggregation policy, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder withAggregationPolicy(AggregationPolicy aggregationPolicy) {
+        this.aggregationPolicy = Objects.requireNonNull(aggregationPolicy);
+        return this;
+    }
+
+    /**
+     * Adds the given providers with the current active {@link AggregationPolicy}. By
+     * default {@link AggregationPolicy#OVERRIDE} is used.
+     * @see #withAggregationPolicy(AggregationPolicy)
+     * @param providers providers to be added, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addProviders(PropertySource... providers) {
+        if(providers.length==0){
+            return this;
+        }
+        return addProviders(Arrays.asList(providers));
+    }
+
+    /**
+     * Adds the given providers with the current active {@link AggregationPolicy}. By
+     * default {@link AggregationPolicy#OVERRIDE} is used.
+     * @see #withAggregationPolicy(AggregationPolicy)
+     * @param providers providers to be added, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addProviders(List<PropertySource> providers) {
+        if(providers.isEmpty()){
+            return this;
+        }
+        List<PropertySource> allProviders = new ArrayList<>(providers);
+        if (this.current != null) {
+            allProviders.add(0, this.current);
+        }
+        StringBuilder b = new StringBuilder();
+        providers.forEach(p -> b.append(p.getName()).append(','));
+        b.setLength(b.length()-1);
+        String source = b.toString();
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<aggregate> -> source=" + source;
+        }
+        this.current = PropertySourceFactory.aggregate(name, this.aggregationPolicy, allProviders);
+        this.currentName = null;
+        return this;
+    }
+
+    /**
+     * Creates a new {@link PropertySource} using the given command line arguments and adds it
+     * using the current aggregation policy in place.
+     *
+     * @param args the command line arguments, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addArgs(String... args) {
+        if(args.length==0){
+            return this;
+        }
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<CLI-args>";
+        }
+        PropertySource argProvider = PropertySourceFactory.fromArgs(name, args);
+        return addProviders(argProvider);
+    }
+
+    /**
+     * Creates a new read-only {@link PropertySource} by reading the according path resources. The effective resources read
+     * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addPaths(String... paths) {
+        if(paths.length==0){
+            return this;
+        }
+        return addPaths(Arrays.asList(paths));
+    }
+
+
+    /**
+     * Creates a new read-only {@link PropertySource} by reading the according path resources. The effective resources read
+     * hereby are determined by the {@code PathResolverService} configured into the {@code Bootstrap} SPI.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param paths the paths to be resolved by the {@code PathResolverService} , not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addPaths(List<String> paths) {
+        if(paths.isEmpty()){
+            return this;
+        }
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<aggregate> -> paths=" + paths.toString();
+        }
+        return addProviders(PropertySourceFactory.fromPaths(name, aggregationPolicy, paths));
+    }
+
+    /**
+     * Creates a new read-only {@link PropertySource} by reading the according URL resources.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param urls the urls to be read, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addURLs(URL... urls) {
+        if(urls.length==0){
+            return this;
+        }
+        return addURLs(Arrays.asList(urls));
+    }
+
+    /**
+     * Creates a new read-only {@link PropertySource} by reading the according URL resources.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param urls the urls to be read, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addURLs(List<URL> urls) {
+        if(urls.isEmpty()){
+            return this;
+        }
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<aggregate> -> urls=" + urls;
+        }
+        return addProviders(PropertySourceFactory.fromURLs(name, this.aggregationPolicy, urls));
+    }
+
+
+    /**
+     * Creates a new read-only {@link PropertySource} based on the given map.
+     * Properties read are aggregated using the current aggregation policy active.
+     *
+     * @param map the map to be added, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addMap(Map<String, String> map) {
+        if(map.isEmpty()){
+            return this;
+        }
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<Map> -> map=" + map;
+        }
+        return addProviders(PropertySourceFactory.fromMap(name, map));
+    }
+
+
+    /**
+     * Add the current environment properties. Aggregation is based on the current {@link AggregationPolicy} acvtive.
+     *
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addEnvironmentProperties() {
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<System.getenv()>";
+        }
+        return addProviders(PropertySourceFactory.fromEnvironmentProperties());
+    }
+
+    /**
+     * Add the current system properties. Aggregation is based on the current {@link AggregationPolicy} acvtive.
+     *
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder addSystemProperties() {
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<System.getProperties()>";
+        }
+        return addProviders(PropertySourceFactory.fromSystemProperties());
+    }
+
+    /**
+     * Add the name used for the next aggregation/adding operation on this builder.
+     * @param name the name to be used, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder withName(String name) {
+        this. currentName = Objects.requireNonNull(name);
+        return this;
+    }
+
+    /**
+     * Adds the given {@link org.apache.tamaya.PropertySource} instances using the current {@link AggregationPolicy}
+     * active.
+     *
+     * @param providers the maps to be included, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder aggregate(PropertySource... providers) {
+        if(providers.length==0){
+            return this;
+        }
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<aggregate> -> " + Arrays.toString(providers);
+        }
+        return addProviders(PropertySourceFactory.aggregate(name, aggregationPolicy, Arrays.asList(providers)));
+    }
+
+
+    /**
+     * Adds the given {@link org.apache.tamaya.PropertySource} instances using the current {@link AggregationPolicy}
+     * active.
+     *
+     * @param providers the maps to be included, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder aggregate(List<PropertySource> providers) {
+        if(providers.isEmpty()){
+            return this;
+        }
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<aggregate> -> " + providers;
+        }
+        return addProviders(PropertySourceFactory.aggregate(name, aggregationPolicy, providers));
+    }
+
+
+    /**
+     * Filters the current {@link org.apache.tamaya.PropertySource} with the given valueFilter.
+     * @param valueFilter the value filter, not null.
+     * @return the (dynamically) filtered source instance, never null.
+     */
+    public PropertySourceBuilder filterValues(BiFunction<String, String, String> valueFilter){
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<filteredValues> -> " + valueFilter;
+        }
+        this.current = PropertySourceFactory.filterValues(name, valueFilter, this.current);
+        return this;
+    }
+
+
+    /**
+     * Intersetcs the current properties with the given {@link org.apache.tamaya.PropertySource} instance.
+     *
+     * @param providers the maps to be intersected, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder intersect(PropertySource... providers) {
+        if(providers.length==0){
+            return this;
+        }
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<intersection> -> " + Arrays.toString(providers);
+        }
+        return addProviders(PropertySourceFactory.intersected(name, aggregationPolicy, Arrays.asList(providers)));
+    }
+
+
+    /**
+     * Subtracts with the given {@link org.apache.tamaya.PropertySource} instance from the current properties.
+     *
+     * @param providers the maps to be subtracted, not null.
+     * @return the builder for chaining.
+     */
+    public PropertySourceBuilder subtract(PropertySource... providers) {
+        if(providers.length==0){
+            return this;
+        }
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<subtraction> -> " + Arrays.toString(providers);
+        }
+        current = PropertySourceFactory.subtracted(name, current, Arrays.asList(providers));
+        return this;
+    }
+
+
+    /**
+     * Filters the current properties based on the given predicate..
+     *
+     * @param filter the filter to be applied, not null.
+     * @return the new filtering instance.
+     */
+    public PropertySourceBuilder filter(Predicate<String> filter) {
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<filtered> -> " + filter;
+        }
+        current = PropertySourceFactory.filtered(name, filter, current);
+        this.currentName = null;
+        return this;
+    }
+
+    /**
+     * Creates a new contextual {@link org.apache.tamaya.PropertySource}. 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 PropertySourceBuilder addContextual(Supplier<PropertySource> mapSupplier,
+                                                 Supplier<String> isolationKeySupplier) {
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<contextual> -> map="+mapSupplier+",isolationKeySupplier="+isolationKeySupplier;
+        }
+        return addProviders(PropertySourceFactory.contextual(name, mapSupplier, isolationKeySupplier));
+    }
+
+    /**
+     * Replaces all keys in the current provider by the given map.
+     *
+     * @param replacementMap the map instance, that will replace all corresponding entries in {@code mainMap}, not null.
+     * @return the new delegating instance.
+     */
+    public PropertySourceBuilder replace(Map<String, String> replacementMap) {
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<replacement> -> current="+current.getName()+" with ="+replacementMap;
+        }
+        current = PropertySourceFactory.replacing(name, current, replacementMap);
+        this.currentName = null;
+        return this;
+    }
+
+    /**
+     * Build a new property provider based on the input.
+     * @return a new property provider, or null.
+     */
+    public PropertySource build(){
+        if (current != null) {
+            return PropertySourceFactory.build(name, current);
+        }
+        return PropertySourceFactory.empty(name);
+    }
+
+    /**
+     * Creates a {@link PropertySource} instance that is serializable and immutable,
+     * so it can be sent over a network connection.
+     *
+     * @return the freezed instance, never null.
+     */
+    public PropertySource buildFrozen() {
+        String name = this.currentName;
+        if (currentName == null) {
+            name = "<freezed> -> source="+current.getName();
+        }
+        PropertySource prov = PropertySourceFactory.freezed(name, current);
+        this.currentName = null;
+        return prov;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceFactory.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceFactory.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceFactory.java
new file mode 100644
index 0000000..3f8a0b1
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/PropertySourceFactory.java
@@ -0,0 +1,287 @@
+/*
+ * 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.properties;
+
+import java.net.URL;
+import java.time.Instant;
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import org.apache.tamaya.PropertySource;
+
+/**
+ * Default implementation current the singleton backing bean for the {@link org.apache.tamaya.core.properties.PropertySourceBuilder}.
+ */
+public final class PropertySourceFactory {
+
+    private static final PropertySource EMPTY_PROPERTYSOURCE = fromMap("<empty>", Collections.emptyMap());
+    private static final PropertySource ENV_PROPERTYSOURCE = new EnvironmentPropertySource();
+
+
+    /**
+     * Singleton constructor.
+     */
+    private PropertySourceFactory(){}
+
+    public static PropertySource fromArgs(String name, String... args) {
+        if(name==null){
+            name ="<CLI> " + Arrays.toString(args);
+        }
+        // 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(name, properties);
+    }
+
+    public static PropertySource fromPaths(String name, AggregationPolicy aggregationPolicy, List<String> paths) {
+        if(name==null){
+            name ="<Paths> " + paths.toString();
+        }
+        return new PathBasedPropertySource(name, paths, aggregationPolicy);
+    }
+
+    public static PropertySource fromURLs(String name, AggregationPolicy aggregationPolicy, List<URL> urls) {
+        if(name==null){
+            name ="<URLs> " + urls.toString();
+        }
+        return new URLBasedPropertySource(name, urls, aggregationPolicy);
+    }
+
+    public static PropertySource fromMap(String name, Map<String, String> map) {
+        if(name==null){
+            name ="<Map> " + map.toString();
+        }
+        return new MapBasedPropertySource(name, map);
+    }
+
+    public static PropertySource empty(String name) {
+        if(name==null) {
+            return EMPTY_PROPERTYSOURCE;
+        }
+        return fromMap(name, Collections.emptyMap());
+    }
+
+    /**
+     * Returns a read-only {@link org.apache.tamaya.PropertySource} reflecting the current runtime environment properties.
+     *
+     * @return a new read-only {@link org.apache.tamaya.PropertySource} instance based on the current runtime environment properties.
+     */
+    public static PropertySource fromEnvironmentProperties() {
+        return ENV_PROPERTYSOURCE;
+    }
+
+    /**
+     * Creates a new read-only {@link org.apache.tamaya.PropertySource} reflecting the current system properties.
+     *
+     * @return a new read-only {@link org.apache.tamaya.PropertySource} instance based on the current system properties.
+     */
+    public static PropertySource fromSystemProperties() {
+        return new SystemPropertiesPropertySource();
+    }
+
+    public static PropertySource freezed(String name, PropertySource source) {
+        if(name==null){
+            name ="<Freezed> source=" + source.toString()+", at="+Instant.now().toString();
+        }
+        return FreezedPropertySource.of(name, source);
+    }
+
+    /**
+     * Creates a new {@link org.apache.tamaya.PropertySource} 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.
+     */
+    public static PropertySource aggregate(String name, AggregationPolicy policy, List<PropertySource> providers) {
+        if(name==null){
+            name ="<Aggregate> policy=" + policy.toString()+", providers="+providers.toString();
+        }
+        return new AggregatedPropertySource(name, null, policy, providers);
+    }
+
+    /**
+     * Creates a new {@link org.apache.tamaya.PropertySource} 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 PropertySource mutable(String name, PropertySource provider) {
+        if(name==null){
+            name ="<Mutable> provider="+provider.getName();
+        }
+        PropertySource mutableProvider = fromMap(name,new HashMap<>());
+        List<PropertySource> providers = new ArrayList<>(2);
+        providers.add(provider);
+        providers.add(mutableProvider);
+        return new AggregatedPropertySource(name, mutableProvider, AggregationPolicy.OVERRIDE, providers);
+    }
+
+    /**
+     * Creates a new {@link org.apache.tamaya.PropertySource} 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.
+     */
+    public static PropertySource intersected(String name, AggregationPolicy aggregationPolicy, List<PropertySource> providers) {
+        return new IntersectingPropertySource(name, aggregationPolicy, providers);
+    }
+
+    /**
+     * Creates a new {@link org.apache.tamaya.PropertySource} 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.
+     */
+    public static PropertySource subtracted(String name, PropertySource target, List<PropertySource> subtrahendSets) {
+        return new SubtractingPropertySource(name, target,subtrahendSets);
+    }
+
+
+    /**
+     * Creates a filtered {@link org.apache.tamaya.PropertySource} (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 name the base map instance, not null.
+     * @param filter      the filtger to be applied, not null.
+     * @return the new filtering instance.
+     */
+    public static PropertySource filtered(String name, Predicate<String> filter, PropertySource source) {
+        if(name==null){
+            name ="<Filtered> filter="+filter+", source="+source.getName();
+        }
+        return new FilteredPropertySource(name, source, filter);
+    }
+
+    /**
+     * Creates a new contextual {@link org.apache.tamaya.PropertySource}. Contextual maps delegate to different instances current PropertyMap depending
+     * on the keys returned fromMap the isolationP
+     *
+     * @param name the base name instance, not null.
+     * @param mapSupplier          the supplier creating new provider instances
+     * @param isolationKeySupplier the supplier providing contextual keys based on the current environment.
+     */
+    public static PropertySource contextual(String name, Supplier<PropertySource> mapSupplier,
+                                              Supplier<String> isolationKeySupplier) {
+        if(name==null){
+            name ="<Contextual> mapSupplier="+mapSupplier+", isolationKeyProvider="+isolationKeySupplier;
+        }
+        return new ContextualPropertySource(name, mapSupplier, isolationKeySupplier);
+    }
+
+
+    /**
+     * Creates a filtered {@link org.apache.tamaya.PropertySource} (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 name the base name instance, not null.
+     * @param source   the main map instance, not null.
+     * @param parentMap the delegated parent map instance, not null.
+     * @return the new delegating instance.
+     */
+    public static PropertySource delegating(String name, PropertySource source, Map<String, String> parentMap) {
+        if(name==null){
+            name ="<Delegating> source="+source+", delegates="+parentMap;
+        }
+        return new DelegatingPropertySource(name, source, parentMap);
+    }
+
+    /**
+     * Creates a {@link org.apache.tamaya.PropertySource} where all keys current a current map,
+     * existing in another map are replaced
+     * with the ones fromMap the other {@link org.apache.tamaya.PropertySource}. 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 name the base name instance, not null.
+     * @param source the main source 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 PropertySource replacing(String name, PropertySource source, Map<String, String> replacementMap) {
+        if(name==null){
+            name ="<Replacement> source="+source+", replacements="+replacementMap;
+        }
+        return new ReplacingPropertySource(name, source, replacementMap);
+    }
+
+    /**
+     * Creates a new {@link org.apache.tamaya.PropertySource} given an existing one, and an alternate
+     * meta-info.
+     * @param name the new meta-information, not null.
+     * @param baseProvider the property source, not null.
+     * @return the new property source.never null.
+     */
+    public static PropertySource build(String name, PropertySource baseProvider) {
+        return new BuildablePropertySource(name, baseProvider);
+    }
+
+    /**
+     * Creates a new filtered {@link org.apache.tamaya.PropertySource} using the given filter.
+     * @param name the base name instance, not null.
+     * @param valueFilter the value filter function, null result will remove the given entries.
+     * @param current the source to be filtered
+     */
+    public static PropertySource filterValues(String name, BiFunction<String, String, String> valueFilter, PropertySource current) {
+        return new ValueFilteredPropertySource(name, valueFilter, current);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/ReplacingPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/ReplacingPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ReplacingPropertySource.java
new file mode 100644
index 0000000..85100e3
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ReplacingPropertySource.java
@@ -0,0 +1,75 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.*;
+
+/**
+ * Implementation for a {@link org.apache.tamaya.PropertySource} 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 ReplacingPropertySource implements PropertySource {
+
+    private PropertySource mainMap;
+    private Map<String,String> replacingMap;
+    private String name;
+
+    /**
+     * Creates a mew instance, with aggregation polilcy
+     * {@code AggregationPolicy.OVERRIDE}.
+     *
+     * @param mainMap      The main ConfigMap.
+     * @param replacingMap The replacing ConfigMap.
+     */
+    public ReplacingPropertySource(String name, PropertySource mainMap, Map<String, String> replacingMap){
+        this.replacingMap = Objects.requireNonNull(replacingMap);
+        this.mainMap = Objects.requireNonNull(mainMap);
+        this.name = Objects.requireNonNull(name);
+    }
+
+    @Override
+    public Map<String,String> getProperties(){
+        Map<String,String> result = new HashMap<>(replacingMap);
+        mainMap.getProperties().entrySet().stream().filter(en -> !replacingMap.containsKey(en.getKey())).forEach(en ->
+                result.put(en.getKey(), en.getValue()));
+        return result;
+    }
+
+    @Override
+    public String getName(){
+        return this.name;
+    }
+
+    @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 String toString(){
+        return super.toString() + "(mainMap=" + mainMap + ", replacingMap=" + replacingMap + ")";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/SubtractingPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/SubtractingPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/SubtractingPropertySource.java
new file mode 100644
index 0000000..f78ceb9
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/SubtractingPropertySource.java
@@ -0,0 +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.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+class SubtractingPropertySource extends AbstractPropertySource {
+
+    private static final long serialVersionUID = 4301042530074932562L;
+    private PropertySource unit;
+    private List<PropertySource> subtrahends;
+
+    public SubtractingPropertySource(String name, PropertySource configuration, List<PropertySource> subtrahends){
+        super(name);
+        Objects.requireNonNull(configuration);
+        this.unit = configuration;
+        this.subtrahends = new ArrayList<>(subtrahends);
+    }
+
+    private boolean filter(Map.Entry<String,String> entry){
+        for(PropertySource prov: subtrahends){
+            if(prov.get(entry.getKey()).isPresent()){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Map<String,String> getProperties(){
+        return this.unit.getProperties().entrySet().stream().filter(this::filter).collect(Collectors.toMap(
+                Map.Entry::getKey,
+                Map.Entry::getValue
+        ));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/SystemPropertiesPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/SystemPropertiesPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/SystemPropertiesPropertySource.java
new file mode 100644
index 0000000..f66c4f8
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/SystemPropertiesPropertySource.java
@@ -0,0 +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.properties;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+class SystemPropertiesPropertySource extends AbstractPropertySource {
+
+
+    private static final long serialVersionUID = -5935940312707001199L;
+
+    /**
+     * Constructor.
+     */
+    protected SystemPropertiesPropertySource() {
+        super("<System.getProperties()>");
+    }
+
+    @Override
+    public Map<String,String> getProperties(){
+        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);
+    }
+
+    @Override
+    public String toString(){
+        return "SystemPropertiesPropertyProvider[" + System.getProperties().size() + " system properties]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/URLBasedPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/URLBasedPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/URLBasedPropertySource.java
new file mode 100644
index 0000000..f690ef9
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/URLBasedPropertySource.java
@@ -0,0 +1,81 @@
+/*
+ * 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.properties;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.core.internal.resources.io.UrlResource;
+import org.apache.tamaya.core.resource.Resource;
+
+import java.net.URL;
+import java.util.*;
+
+/**
+ * Created by Anatole on 16.10.2014.
+ */
+final class URLBasedPropertySource extends AbstractPropertySource {
+
+	private static final long serialVersionUID = 648272283683183532L;
+	private List<URL> resources = new ArrayList<>();
+    private Map<String,String> properties = new HashMap<>();
+    private AggregationPolicy aggregationPolicy;
+
+    public URLBasedPropertySource(String name, List<URL> resources, AggregationPolicy aggregationPolicy) {
+        super(name);
+        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 = ConfigurationFormat.from(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> getProperties() {
+        return properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/properties/ValueFilteredPropertySource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/properties/ValueFilteredPropertySource.java b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ValueFilteredPropertySource.java
new file mode 100644
index 0000000..db17d21
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/properties/ValueFilteredPropertySource.java
@@ -0,0 +1,51 @@
+package org.apache.tamaya.core.properties;
+
+import org.apache.tamaya.PropertySource;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.BiFunction;
+
+/**
+ * Property source which filters any key/values dynamically.
+ */
+class ValueFilteredPropertySource implements PropertySource{
+
+    private String name;
+    private BiFunction<String, String, String> valueFilter;
+    private PropertySource source;
+
+    public ValueFilteredPropertySource(String name, BiFunction<String, String, String> valueFilter, PropertySource current) {
+        this.name = Optional.ofNullable(name).orElse("<valueFiltered> -> name="+current.getName()+", valueFilter="+valueFilter.toString());
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Optional<String> get(String key) {
+        String value = this.source.get(key).orElse(null);
+        value = valueFilter.apply(key, value);
+        return Optional.ofNullable(value);
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        Map<String, String> map = new HashMap<>(source.getProperties());
+        map.replaceAll(valueFilter);
+        return map;
+    }
+
+    @Override
+    public String toString() {
+        return "ValueFilteredPropertySource{" +
+                "source=" + source.getName() +
+                ", name='" + name + '\'' +
+                ", valueFilter=" + valueFilter +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/resource/InputStreamSource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/resource/InputStreamSource.java b/dormant/core/src/main/java/org/apache/tamaya/core/resource/InputStreamSource.java
new file mode 100644
index 0000000..102337d
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/resource/InputStreamSource.java
@@ -0,0 +1,55 @@
+/*
+* Copyright 2002-2012 the original author or authors.
+*
+* Licensed 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.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+* Simple interface for objects that are sources for an {@link InputStream}.
+*
+* <p>This is the base interface for Spring's more extensive {@link Resource} interface.
+*
+* <p>For single-use streams, {@link org.apache.tamaya.core.internal.resources.io.InputStreamResource} can be used for any
+* given {@code InputStream}. Spring's {@code ByteArrayResource} or any
+* file-based {@code Resource} implementation can be used as a concrete
+* instance, allowing one to read the underlying content stream multiple times.
+* This makes this interface useful as an abstract content source for mail
+* attachments, for example.
+*
+* @author Juergen Hoeller
+* @since 20.01.2004
+* @see java.io.InputStream
+* @see Resource
+* @see org.apache.tamaya.core.internal.resources.io.InputStreamResource
+*/
+@FunctionalInterface
+public interface InputStreamSource {
+
+	/**
+	 * Return an {@link InputStream}.
+	 * <p>It is expected that each call creates a <i>fresh</i> stream.
+	 * <p>This requirement is particularly important when you consider an API such
+	 * as JavaMail, which needs to be able to read the stream multiple times when
+	 * creating mail attachments. For such a use case, it is <i>required</i>
+	 * that each {@code getInputStreamSupplier()} call returns a fresh stream.
+	 * @return the input stream for the underlying resource (must not be {@code null})
+	 * @throws IOException if the stream could not be opened
+	 */
+	InputStream getInputStream() throws IOException;
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/resource/Resource.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/resource/Resource.java b/dormant/core/src/main/java/org/apache/tamaya/core/resource/Resource.java
new file mode 100644
index 0000000..ca76974
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/resource/Resource.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed 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.resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+
+/**
+ * Interface for a resource descriptor that abstracts from the actual
+ * type current underlying resource, such as a file or class path resource.
+ *
+ * <p>An InputStream can be opened for every resource if it exists in
+ * physical form, but a URL or File handle can just be returned for
+ * certain resources. The actual behavior is implementation-specific.
+ *
+ * @author Juergen Hoeller
+ * @since 28.12.2003
+ * @see #getInputStream()
+ * @see #getURL()
+ * @see #getURI()
+ * @see #getFile()
+ */
+public interface Resource extends InputStreamSource {
+
+	/**
+	 * Return whether this resource actually exists in physical form.
+	 * <p>This method performs a definitive existence check, whereas the
+	 * existence current a {@code Resource} handle only guarantees a
+	 * valid descriptor handle.
+	 */
+	boolean exists();
+
+	/**
+	 * Return whether the contents current this resource can be read,
+	 * e.g. via {@link #getInputStream()} or {@link #getFile()}.
+	 * <p>Will be {@code true} for typical resource descriptors;
+	 * note that actual content reading may still fail when attempted.
+	 * However, a keys current {@code false} is a definitive indication
+	 * that the resource content cannot be read.
+	 * @see #getInputStream()
+	 */
+	boolean isReadable();
+
+	/**
+	 * Return whether this resource represents a handle with an open
+	 * stream. If true, the InputStream cannot be read multiple times,
+	 * and must be read and closed to avoid resource leaks.
+	 * <p>Will be {@code false} for typical resource descriptors.
+	 */
+	boolean isOpen();
+
+	/**
+	 * Return a URL handle for this resource.
+	 * @throws IOException if the resource cannot be resolved as URL,
+	 * i.e. if the resource is not available as descriptor
+	 */
+	URL getURL() throws IOException;
+
+	/**
+	 * Return a URI handle for this resource.
+	 * @throws IOException if the resource cannot be resolved as URI,
+	 * i.e. if the resource is not available as descriptor
+	 */
+	URI getURI() throws IOException;
+
+	/**
+	 * Return a File handle for this resource.
+	 * @throws IOException if the resource cannot be resolved as absolute
+	 * file path, i.e. if the resource is not available in a file system
+	 */
+	File getFile() throws IOException;
+
+	/**
+	 * Determine the content length for this resource.
+	 * @throws IOException if the resource cannot be resolved
+	 * (in the file system or as some other known physical resource type)
+	 */
+	long contentLength() throws IOException;
+
+	/**
+	 * Determine the last-modified timestamp for this resource.
+	 * @throws IOException if the resource cannot be resolved
+	 * (in the file system or as some other known physical resource type)
+	 */
+	long lastModified() throws IOException;
+
+	/**
+	 * Create a resource relative to this resource.
+	 * @param relativePath the relative path (relative to this resource)
+	 * @return the resource handle for the relative resource
+	 * @throws IOException if the relative resource cannot be determined
+	 */
+	Resource createRelative(String relativePath) throws IOException;
+
+	/**
+	 * Determine a filename for this resource, i.e. typically the last
+	 * part current the path: for example, "myfile.txt".
+	 * <p>Returns {@code null} if this type current resource does not
+	 * have a filename.
+	 */
+	String getFilename();
+
+    /**
+     * Get a description of the resource.
+     * @return the description.
+     */
+    String getDescription();
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d9964c64/dormant/core/src/main/java/org/apache/tamaya/core/resource/ResourceLoader.java
----------------------------------------------------------------------
diff --git a/dormant/core/src/main/java/org/apache/tamaya/core/resource/ResourceLoader.java b/dormant/core/src/main/java/org/apache/tamaya/core/resource/ResourceLoader.java
new file mode 100644
index 0000000..1c55e55
--- /dev/null
+++ b/dormant/core/src/main/java/org/apache/tamaya/core/resource/ResourceLoader.java
@@ -0,0 +1,84 @@
+/*
+ * 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.resource;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Interface to be implemented by containers that decouples loading current classpath resources fromMap the effective
+ * classloader architecture current a runtime environment. Implementations current this class encapsulate the mechanism current
+ * determining the
+ * concrete resources available base on an expression defining the configuration
+ * locations. A an example the expression {@code cfg/global/*.xml} defines a
+ * location for reading global configuration in the classpath. A resources
+ * interprets this expression and evaluates the concrete resources to be read,
+ * e.g. {@code cfg/global/default.xml, cfg/global/myApp.xml}.
+ * Created by Anatole on 16.06.2014.
+ */
+public interface ResourceLoader{
+
+    /**
+     * Get the prefixes supportedby this loader.
+     *
+     * @return the supported prefixes, not empty.
+     */
+    Collection<String> getResolverIds();
+
+    /**
+     * Called, when a given expression has to be resolved.
+     *
+     * @param expressions the expressions to be resolved, not empty.
+     * @return the corresponding collection current {@link java.net.URI}s defining the
+     * concrete resources to be read by a {@link org.apache.tamaya.core.properties.ConfigurationFormat}
+     * .
+     */
+    List<Resource> getResources(String... expressions);
+
+    /**
+     * Called, when a given expression has to be resolved.
+     *
+     * @param expressions the expressions to be resolved, not empty.
+     * @return the corresponding collection current {@link java.net.URI}s defining the
+     * concrete resources to be read by a {@link org.apache.tamaya.core.properties.ConfigurationFormat}
+     * .
+     */
+    List<Resource> getResources(Collection<String> expressions);
+
+    /**
+     * Called, when a given expression has to be resolved.
+     *
+     * @param expressions the expressions to be resolved, not empty.
+     * @return the corresponding collection current {@link java.net.URI}s defining the
+     * concrete resources to be read by a {@link org.apache.tamaya.core.properties.ConfigurationFormat}
+     * .
+     */
+    List<Resource> getResources(ClassLoader classLoader, String... expressions);
+
+    /**
+     * Called, when a given expression has to be resolved.
+     *
+     * @param expressions the expressions to be resolved, not empty.
+     * @return the corresponding collection current {@link java.net.URI}s defining the
+     * concrete resources to be read by a {@link org.apache.tamaya.core.properties.ConfigurationFormat}
+     * .
+     */
+    List<Resource> getResources(ClassLoader classLoader, Collection<String> expressions);
+
+}