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 2017/12/17 08:00:29 UTC

[1/6] incubator-tamaya git commit: Reimplemented (also simjplified) Tamaya core completely based on latest JSR API. Moved prior Tamaya API into compat module.

Repository: incubator-tamaya
Updated Branches:
  refs/heads/configjsr d0e14ed70 -> 063f8adad


Reimplemented (also simjplified) Tamaya core completely based on latest JSR API. Moved prior Tamaya API into compat module.

Signed-off-by: Anatole Tresch <an...@apache.org>


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

Branch: refs/heads/configjsr
Commit: a31af0036a41c9dcf89e243b5649007a108cd2e3
Parents: d0e14ed
Author: Anatole Tresch <an...@apache.org>
Authored: Wed Dec 13 23:42:52 2017 +0100
Committer: Anatole Tresch <an...@apache.org>
Committed: Wed Dec 13 23:42:52 2017 +0100

----------------------------------------------------------------------
 code/base/pom.xml                               |  5 --
 .../apache/tamaya/core/OSGIServiceLoader.java   |  2 +-
 .../internal/converters/ClassConverterTest.java |  1 -
 .../internal/converters/URIConverterTest.java   |  1 -
 .../internal/converters/URLConverterTest.java   |  1 -
 .../apache/tamaya/examples/minimal/Main.java    | 31 +++++-----
 examples/02-custom-property-source/pom.xml      |  5 ++
 .../examples/custompropertysource/Main.java     | 43 ++++++-------
 .../SimpleConfigSource.java                     | 64 ++++++++++++++++++++
 .../SimplePropertySource.java                   | 64 --------------------
 .../SimplePropertySourceProvider.java           | 22 ++++---
 11 files changed, 116 insertions(+), 123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/code/base/pom.xml
----------------------------------------------------------------------
diff --git a/code/base/pom.xml b/code/base/pom.xml
index dc16016..603c41b 100644
--- a/code/base/pom.xml
+++ b/code/base/pom.xml
@@ -34,11 +34,6 @@ under the License.
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.tamaya</groupId>
-            <artifactId>tamaya-spisupport</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-annotation_1.2_spec</artifactId>
             <version>1.0-alpha-1</version>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceLoader.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceLoader.java b/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceLoader.java
index 90e74bc..96e3da9 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceLoader.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceLoader.java
@@ -26,7 +26,7 @@ import java.util.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.apache.tamaya.spisupport.PriorityServiceComparator;
+import org.apache.tamaya.base.PriorityServiceComparator;
 import org.osgi.framework.*;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ClassConverterTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ClassConverterTest.java b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ClassConverterTest.java
index 933d6ce..08a0cdb 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ClassConverterTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/ClassConverterTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.tamaya.core.internal.converters;
 
-import org.apache.tamaya.TypeLiteral;
 import org.apache.tamaya.core.converters.ClassConverter;
 import org.apache.tamaya.base.convert.ConversionContext;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URIConverterTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URIConverterTest.java b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URIConverterTest.java
index 2010b1d..deb4ada 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URIConverterTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URIConverterTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.tamaya.core.internal.converters;
 
-import org.apache.tamaya.TypeLiteral;
 import org.apache.tamaya.core.converters.URIConverter;
 import org.apache.tamaya.base.convert.ConversionContext;
 import org.junit.After;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URLConverterTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URLConverterTest.java b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URLConverterTest.java
index b12c114..196555c 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URLConverterTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/internal/converters/URLConverterTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.tamaya.core.internal.converters;
 
-import org.apache.tamaya.TypeLiteral;
 import org.apache.tamaya.core.converters.URLConverter;
 import org.apache.tamaya.base.convert.ConversionContext;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/Main.java
----------------------------------------------------------------------
diff --git a/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/Main.java b/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/Main.java
index aeb44ef..93db446 100644
--- a/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/Main.java
+++ b/examples/01-minimal/src/main/java/org/apache/tamaya/examples/minimal/Main.java
@@ -18,11 +18,11 @@
  */
 package org.apache.tamaya.examples.minimal;
 
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-
+import javax.config.Config;
+import javax.config.ConfigProvider;
 import java.io.PrintStream;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeMap;
 import java.util.logging.LogManager;
 import java.util.logging.Logger;
@@ -34,14 +34,11 @@ import static java.lang.String.format;
  *
  * <p>
  *  Without any additional configuration Tamaya allows you access via
- *  {@link ConfigurationProvider#getConfiguration} all configuration values.
+ *  {@link ConfigProvider#getConfig} all configuration values.
  *  Accessable are all system environment properties, all system properties,
  *  and all properties which are found in {@code /META-INF/javaconfiguration.properties}
  *  or {@code /META-INF/javaconfiguration.xml}.
  * </p>
- *
- * @see org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource
- * @see org.apache.tamaya.spisupport.propertysource.SystemPropertySource
  */
 public class Main {
     /*
@@ -57,28 +54,28 @@ public class Main {
     }
 
     public static void main(String[] args) {
-        Configuration cfg = ConfigurationProvider.getConfiguration();
+        Config cfg = ConfigProvider.getConfig();
 
         System.out.println("****************************************************");
         System.out.println("Minimal Example");
         System.out.println("****************************************************");
         System.out.println();
         System.out.println("Example Metadata:");
-        System.out.println("\tType        :  " + cfg.get("example.type"));
-        System.out.println("\tName        :  " + cfg.get("example.name"));
-        System.out.println("\tDescription :  " + cfg.get("example.description"));
-        System.out.println("\tVersion     :  " + cfg.get("example.version"));
-        System.out.println("\tAuthor      :  " + cfg.get("example.author"));
+        System.out.println("\tType        :  " + cfg.getValue("example.type", String.class));
+        System.out.println("\tName        :  " + cfg.getValue("example.name", String.class));
+        System.out.println("\tDescription :  " + cfg.getValue("example.description", String.class));
+        System.out.println("\tVersion     :  " + cfg.getValue("example.version", String.class));
+        System.out.println("\tAuthor      :  " + cfg.getValue("example.author", String.class));
         System.out.println();
 
-        dump(cfg.getProperties(), System.out);
+        dump(cfg.getPropertyNames(), System.out, cfg);
     }
 
-    private static void dump(Map<String, String> properties, PrintStream stream) {
+    private static void dump(Iterable<String> properties, PrintStream stream, Config config) {
         stream.println("FULL DUMP:\n\n");
 
-        for (Map.Entry<String, String> en : new TreeMap<>(properties).entrySet()) {
-            stream.println(format("\t%s = %s", en.getKey(), en.getValue()));
+        for (String key : properties) {
+            stream.println(format("\t%s = %s", key, config.getValue(key, String.class)));
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/examples/02-custom-property-source/pom.xml
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/pom.xml b/examples/02-custom-property-source/pom.xml
index 4fe43b4..05f85b8 100644
--- a/examples/02-custom-property-source/pom.xml
+++ b/examples/02-custom-property-source/pom.xml
@@ -54,6 +54,11 @@ under the License.
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-base</artifactId>
+            <version>0.4-incubating-SNAPSHOT</version>
+        </dependency>
     </dependencies>
     
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java
index dc254e8..1c285b2 100644
--- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java
+++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java
@@ -18,24 +18,21 @@
  */
 package org.apache.tamaya.examples.custompropertysource;
 
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-
+import javax.config.Config;
+import javax.config.ConfigProvider;
 import java.io.PrintStream;
-import java.util.Map;
-import java.util.TreeMap;
 import java.util.logging.LogManager;
 import java.util.logging.Logger;
 
 import static java.lang.String.format;
 
 /**
- * Small example demonstrating the usage of a self-written {@link org.apache.tamaya.spi.PropertySource}
- * and {@link org.apache.tamaya.spi.PropertySourceProvider}.
+ * Small example demonstrating the usage of a self-written {@link javax.config.spi.ConfigSource}
+ * and {@link javax.config.spi.ConfigSourceProvider}.
  *
  * <p>
- *  {@link SimplePropertySource} is a custom implementation of a
- *  {@link org.apache.tamaya.spi.PropertySource}. It reads its properties from a
+ *  {@link org.apache.tamaya.base.configsource.SimpleConfigSource} is a custom implementation of a
+ *  {@link javax.config.spi.ConfigSource}. It reads its properties from a
  *  flexibly configurable location. As it is an implementation
  *  of {@code PropertySource} and it is listed as service implementation
  *  in {@code META-INF/services/org.apache.tamaya.spi.PropertySource} Tamaya is able
@@ -44,8 +41,8 @@ import static java.lang.String.format;
  *
  * <p>
  *  The same applies to {@link SimplePropertySourceProvider} which is an implementation
- *  of {@link org.apache.tamaya.spi.PropertySourceProvider}. Tamaya finds implementations
- *  of a {@link org.apache.tamaya.spi.PropertySourceProvider} also through the
+ *  of {@link javax.config.spi.ConfigSourceProvider}. Tamaya finds implementations
+ *  of a {@link javax.config.spi.ConfigSourceProvider} also through the
  *  Service Provider Interface service of Java. Therefore it is listed in
  *  {@code META-INF/services/org.apache.tamaya.spi.PropertySourceProvider} file.
  * </p>
@@ -64,31 +61,31 @@ public class Main {
     }
 
     public static void main(String[] args) {
-        Configuration cfg = ConfigurationProvider.getConfiguration();
+        Config cfg = ConfigProvider.getConfig();
 
         System.out.println("*****************************************************");
         System.out.println("Simple Example (with a PropertySource and a Provider)");
         System.out.println("*****************************************************");
         System.out.println();
         System.out.println("Example Metadata:");
-        System.out.println("\tType        :  " + cfg.get("example.type"));
-        System.out.println("\tName        :  " + cfg.get("example.name"));
-        System.out.println("\tDescription :  " + cfg.get("example.description"));
-        System.out.println("\tVersion     :  " + cfg.get("example.version"));
-        System.out.println("\tAuthor      :  " + cfg.get("example.author"));
+        System.out.println("\tType        :  " + cfg.getValue("example.type", String.class));
+        System.out.println("\tName        :  " + cfg.getValue("example.name", String.class));
+        System.out.println("\tDescription :  " + cfg.getValue("example.description", String.class));
+        System.out.println("\tVersion     :  " + cfg.getValue("example.version", String.class));
+        System.out.println("\tAuthor      :  " + cfg.getValue("example.author", String.class));
         System.out.println();
-        System.out.println("\tPath        :  " + cfg.get("Path"));
-        System.out.println("\taProp       :  " + cfg.get("aProp"));
+        System.out.println("\tPath        :  " + cfg.getValue("Path", String.class));
+        System.out.println("\taProp       :  " + cfg.getValue("aProp", String.class));
         System.out.println();
 
-        dump(cfg.getProperties(), System.out);
+        dump(cfg.getPropertyNames(), System.out, cfg);
     }
 
-    private static void dump(Map<String, String> properties, PrintStream stream) {
+    private static void dump(Iterable<String> properties, PrintStream stream, Config config) {
         stream.println("FULL DUMP:\n\n");
 
-        for (Map.Entry<String, String> en : new TreeMap<>(properties).entrySet()) {
-            stream.println(format("\t%s = %s", en.getKey(), en.getValue()));
+        for (String en : properties) {
+            stream.println(format("\t%s = %s", en, config.getValue(en, String.class)));
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimpleConfigSource.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimpleConfigSource.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimpleConfigSource.java
new file mode 100644
index 0000000..5aede5f
--- /dev/null
+++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimpleConfigSource.java
@@ -0,0 +1,64 @@
+/*
+ * 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.examples.custompropertysource;
+
+import org.apache.tamaya.base.configsource.BaseConfigSource;
+
+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;
+
+public class SimpleConfigSource extends BaseConfigSource {
+
+    public static final String CONFIG_PROPERTIES_LOCATION = "META-INF/MyOtherConfigProperties.properties";
+    private Map<String,String> props = new HashMap<>();
+
+    public SimpleConfigSource() throws IOException {
+        this(ClassLoader.getSystemClassLoader().getResource(CONFIG_PROPERTIES_LOCATION));
+    }
+    public SimpleConfigSource(URL url) throws IOException {
+        Properties properties = new Properties();
+
+        try(InputStream is = url.openStream()){
+            properties.load(is);
+
+            for(Map.Entry en: properties.entrySet()){
+                props.put(en.getKey().toString(),
+                        en.getValue().toString());
+            }
+        }
+        finally{
+            props = Collections.unmodifiableMap(props);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return CONFIG_PROPERTIES_LOCATION;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return props;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java
deleted file mode 100644
index d21230e..0000000
--- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySource.java
+++ /dev/null
@@ -1,64 +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.examples.custompropertysource;
-
-import org.apache.tamaya.spisupport.propertysource.BasePropertySource;
-import org.apache.tamaya.spi.PropertyValue;
-
-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;
-
-public class SimplePropertySource extends BasePropertySource {
-
-    public static final String CONFIG_PROPERTIES_LOCATION = "META-INF/MyOtherConfigProperties.properties";
-    private Map<String,PropertyValue> props = new HashMap<>();
-
-    public SimplePropertySource() throws IOException {
-        URL url = ClassLoader.getSystemClassLoader().getResource(CONFIG_PROPERTIES_LOCATION);
-        Properties properties = new Properties();
-
-        try(InputStream is = url.openStream()){
-            properties.load(is);
-
-            for(Map.Entry en: properties.entrySet()){
-                props.put(en.getKey().toString(),
-                        PropertyValue.of(en.getKey().toString(), en.getValue().toString(),
-                                getName()));
-            }
-        }
-        finally{
-            props = Collections.unmodifiableMap(props);
-        }
-    }
-
-    @Override
-    public String getName() {
-        return CONFIG_PROPERTIES_LOCATION;
-    }
-
-    @Override
-    public Map<String, PropertyValue> getProperties() {
-        return props;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/a31af003/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java
index 0573fbd..26a1ac8 100644
--- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java
+++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java
@@ -18,30 +18,32 @@
  */
 package org.apache.tamaya.examples.custompropertysource;
 
-import org.apache.tamaya.spisupport.propertysource.SimplePropertySource;
-import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertySourceProvider;
-
+import javax.config.spi.ConfigSource;
+import javax.config.spi.ConfigSourceProvider;
+import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
-public class SimplePropertySourceProvider implements PropertySourceProvider {
+public class SimplePropertySourceProvider implements ConfigSourceProvider {
     private static final String[] RESOURCES = {
         "cfgOther/a.properties", "cfgOther/b.properties", "cfgOther/c.properties"
     };
 
     @Override
-    public Collection<PropertySource> getPropertySources() {
-        List<PropertySource> propertySources = new ArrayList<>();
+    public Collection<ConfigSource> getConfigSources(ClassLoader cl) {
+        List<ConfigSource> propertySources = new ArrayList<>();
 
         for (String res : RESOURCES) {
             URL url = ClassLoader.getSystemClassLoader().getResource(res);
-            propertySources.add(new SimplePropertySource(url));
+            try {
+                propertySources.add(new SimpleConfigSource(url));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
         }
 
-        return Collections.unmodifiableList(propertySources);
+        return propertySources;
     }
 }


[3/6] incubator-tamaya git commit: Added full JSR implementation.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/package-info.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/package-info.java b/code/base/src/main/java/org/apache/tamaya/spi/package-info.java
new file mode 100644
index 0000000..cc6feee
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Tamaya extended configuration SPI.
+ */
+package org.apache.tamaya.spi;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigBuilderTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigBuilderTest.java b/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigBuilderTest.java
new file mode 100644
index 0000000..84c1e70
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigBuilderTest.java
@@ -0,0 +1,198 @@
+/*
+ * 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.base;
+
+import org.apache.tamaya.spi.TamayaConfigBuilder;
+import org.apache.tamaya.spi.ConfigContext;
+import org.apache.tamaya.spi.ConfigValueCombinationPolicy;
+import org.apache.tamaya.spi.TypeLiteral;
+import org.apache.tamaya.spi.Filter;
+import org.apache.tamaya.base.DefaultConfigBuilder;
+import org.junit.Test;
+
+import javax.config.Config;
+import javax.config.ConfigProvider;
+import javax.config.spi.ConfigBuilder;
+import javax.config.spi.ConfigProviderResolver;
+import javax.config.spi.ConfigSource;
+import javax.config.spi.Converter;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link  DefaultConfigBuilder} by atsticks on 06.09.16.
+ */
+public class DefaultConfigBuilderTest {
+
+    private TestPropertySource testPropertySource = new TestPropertySource(){};
+
+
+    @Test
+    public void addPropertySources_Array() throws Exception {
+        ConfigSource testPS2 = new TestPropertySource("addPropertySources_Array_2");
+        TamayaConfigBuilder b = new DefaultConfigBuilder()
+                .withSources(testPropertySource, testPS2);
+        ConfigContext ctx = b.getConfigContext();
+        assertEquals(2, ctx.getSources().size());
+        assertTrue(ctx.getSources().contains(testPropertySource));
+        assertTrue(ctx.getSources().contains(testPS2));
+    }
+
+    @Test
+    public void removePropertySources_Array() throws Exception {
+        ConfigSource testPS2 = new TestPropertySource("addPropertySources_Array_2");
+        TamayaConfigBuilder b = new DefaultConfigBuilder()
+                .withSources(testPropertySource, testPS2);
+        ConfigContext ctx = b.getConfigContext();
+        assertEquals(2, ctx.getSources().size());
+        assertTrue(ctx.getSources().contains(testPropertySource));
+        assertTrue(ctx.getSources().contains(testPS2));
+        b = new DefaultConfigBuilder()
+                .withSources(testPropertySource, testPS2);
+        b.removeSources(testPropertySource);
+        ctx = b.getConfigContext();
+        assertEquals(1, ctx.getSources().size());
+        assertFalse(ctx.getSources().contains(testPropertySource));
+        assertTrue(ctx.getSources().contains(testPS2));
+    }
+
+    @Test
+    public void addPropertyFilters_Array() throws Exception {
+        Filter filter1 = (value) -> value;
+        Filter filter2 = (value) -> value;
+        DefaultConfigBuilder b = new DefaultConfigBuilder();
+        b.withFilters(filter1, filter2);
+        ConfigContext ctx = b.getConfigContext();
+        assertTrue(ctx.getFilters().contains(filter1));
+        assertTrue(ctx.getFilters().contains(filter2));
+        assertEquals(2, ctx.getFilters().size());
+        b = new DefaultConfigBuilder();
+        b.withFilters(filter1, filter2);
+        b.withFilters(filter1, filter2);
+        assertEquals(2, ctx.getFilters().size());
+    }
+
+    @Test
+    public void removePropertyFilters_Array() throws Exception {
+        Filter filter1 = (value) -> value;
+        Filter filter2 = (value) -> value;
+        TamayaConfigBuilder b = new DefaultConfigBuilder()
+                .withFilters(filter1, filter2);
+        ConfigContext ctx = b.getConfigContext();
+        assertTrue(ctx.getFilters().contains(filter1));
+        assertTrue(ctx.getFilters().contains(filter2));
+        assertEquals(2, ctx.getFilters().size());
+        b = new DefaultConfigBuilder()
+                .withFilters(filter1, filter2);
+        b.removeFilters(filter1);
+        ctx = b.getConfigContext();
+        assertEquals(1, ctx.getFilters().size());
+        assertFalse(ctx.getFilters().contains(filter1));
+        assertTrue(ctx.getFilters().contains(filter2));
+    }
+
+    @Test
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public void addPropertyConverter() throws Exception {
+		Converter converter = (value) -> value.toLowerCase();
+		TamayaConfigBuilder b = new DefaultConfigBuilder()
+                .withConverters(String.class, converter);
+        ConfigContext ctx = b.getConfigContext();
+        assertTrue(ctx.getConverters(String.class).contains(converter));
+        assertEquals(1, ctx.getConverters().size());
+        b = new DefaultConfigBuilder()
+                .withConverters(String.class, converter);
+        b.withConverters(String.class, converter);
+        assertEquals(1, ctx.getConverters().size());
+    }
+
+    @Test
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public void removePropertyConverters_Array() throws Exception {
+        Converter converter = (value) -> value.toLowerCase();
+        TamayaConfigBuilder b = new DefaultConfigBuilder()
+                .withConverters(String.class, converter);
+        ConfigContext ctx = b.getConfigContext();
+        assertTrue(ctx.getConverters(String.class).contains(converter));
+        assertEquals(1, ctx.getConverters().get(String.class).size());
+        b = new DefaultConfigBuilder()
+                .withConverters(String.class, converter);
+        b.removeConverters(String.class, converter);
+        ctx = b.getConfigContext();
+        assertFalse(ctx.getConverters(String.class).contains(converter));
+        assertTrue(ctx.getConverters(String.class).isEmpty());
+    }
+
+    @Test
+    public void setPropertyValueCombinationPolicy() throws Exception {
+        ConfigValueCombinationPolicy combPol = (currentValue, key, propertySource) -> currentValue;
+        TamayaConfigBuilder b = new DefaultConfigBuilder()
+                .withPropertyValueCombinationPolicy(combPol);
+        ConfigContext ctx = b.getConfigContext();
+        assertEquals(ctx.getConfigValueCombinationPolicy(), combPol);
+    }
+
+    @Test
+    public void build() throws Exception {
+        assertNotNull(new DefaultConfigBuilder().build());
+    }
+
+    @Test
+    public void addDiscoveredConverters() throws Exception {
+        ConfigBuilder builder = ConfigProviderResolver.instance().getBuilder();
+        builder.addDiscoveredConverters();
+    }
+
+    private static class TestPropertySource implements ConfigSource{
+
+        private String id;
+
+        public TestPropertySource(){
+            this(null);
+        }
+
+        public TestPropertySource(String id){
+            this.id = id;
+        }
+
+        @Override
+        public int getOrdinal() {
+            return 200;
+        }
+
+        @Override
+        public String getName() {
+            return id!=null?id:"TestPropertySource";
+        }
+
+        @Override
+        public String getValue(String key) {
+            return key + "Value";
+        }
+
+        @Override
+        public Map<String, String> getProperties() {
+            return Collections.emptyMap();
+        }
+
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigTest.java b/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigTest.java
new file mode 100644
index 0000000..587fe5a
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/DefaultConfigTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.base;
+
+import org.apache.tamaya.spi.TypeLiteral;
+import org.junit.Test;
+
+
+import static org.junit.Assert.assertNull;
+
+public class DefaultConfigTest {
+
+    /**
+     * Tests for get(String)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getDoesNotAcceptNull1() {
+        DefaultConfig c =  new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+        c.getValue("a", (Class)null);
+    }
+
+    /**
+     * Tests for get(String)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getDoesNotAcceptNull2() {
+        DefaultConfig c =  new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+        c.getValue(null, String.class);
+    }
+
+    /**
+     * Tests for get(String, Class)
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+	@Test(expected = NullPointerException.class)
+    public void getDoesNotAcceptNullForClassTargetType() {
+        DefaultConfig c = new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+        c.getValue("a", (Class) null);
+    }
+
+    /**
+     * Tests for get(String, TypeLiteral)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getDoesNotAcceptNullForTypeLiteralTargetType() {
+        DefaultConfig c =  new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+        c.getValue("a", (Class)null);
+    }
+
+    /**
+     * Tests for getOrDefault(String, Class, String)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsKeyForThreeParameterVariant() {
+        DefaultConfig c = new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+
+        c.getOptionalValue(null, String.class).orElse("ok");
+    }
+
+    @Test
+    public void getOrDefaultDoesAcceptNullAsDefaultValueForThreeParameterVariant() {
+        DefaultConfig c = new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+
+        assertNull(c.getOptionalValue("a", String.class).orElse(null));
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+	@Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesAcceptNullAsTargetTypeForThreeParameterVariant() {
+        DefaultConfig c = new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+        c.getOptionalValue("a", (Class)null).orElse("b");
+    }
+
+//    /**
+//     * Tests for getOrDefault(String, TypeLiteral, String)
+//     */
+//    @Test(expected = NullPointerException.class)
+//    public void getOrDefaultDoesNotAcceptNullAsKeyForThreeParameterVariantSecondIsTypeLiteral() {
+//        DefaultConfiguration c = new DefaultConfiguration(new ConfigurationContextBuilder().build());
+//
+//        c.getOptionalValue(null, TypeLiteral.of(String.class)).orElse("ok");
+//    }
+//
+//    @Test
+//    public void getOrDefaultDoesAcceptNullAsDefaultValueForThreeParameterVariantSecondIsTypeLiteral() {
+//        DefaultConfiguration c = new DefaultConfiguration(new ConfigurationContextBuilder().build());
+//
+//        assertNull(c.getOptionalValue("a", TypeLiteral.of(String.class)).orElse( null));
+//    }
+//
+//    @Test(expected = NullPointerException.class)
+//    public void getOrDefaultDoesNotAcceptNullAsTargetTypeForThreeParameterVariantSecondIsTypeLiteral() {
+//        DefaultConfiguration c = new DefaultConfiguration(new ConfigurationContextBuilder().build());
+//
+//        c.getOptionalValue("a", (TypeLiteral<String>) null).orElse( "b");
+//    }
+
+    /**
+     * Tests for getOrDefault(String, String)
+     */
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesNotAcceptNullAsKeyForTwoParameterVariantDefaultValueIsSecond() {
+        DefaultConfig c = new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+
+        c.getOptionalValue(null, String.class).orElse("ok");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getOrDefaultDoesAcceptNullAsDefaultValueForTwoParameterVariantDefaultValueIsSecond() {
+        DefaultConfig c = new DefaultConfig(new DefaultConfigBuilder().getConfigContext());
+       assertNull(c.getOptionalValue("a", null));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/DefaultServiceContextTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/DefaultServiceContextTest.java b/code/base/src/test/java/org/apache/tamaya/base/DefaultServiceContextTest.java
new file mode 100644
index 0000000..7758c3e
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/DefaultServiceContextTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.base;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.annotation.Priority;
+import javax.config.spi.ConfigProviderResolver;
+import java.util.Collection;
+import java.util.List;
+
+public class DefaultServiceContextTest {
+
+    /**
+     * context to test
+     */
+    private final DefaultServiceContext context = new DefaultServiceContext();
+
+
+    @Test
+    public void testGetService() {
+        ConfigProviderResolver providerSpi = context.getService(ConfigProviderResolver.class);
+        Assert.assertNotNull(providerSpi);
+        Assert.assertTrue(providerSpi instanceof TestConfigurationProvider);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testGetService_multipleServicesWithoutPriority_shouldThrowConfigException() {
+        context.getService(InvalidPriorityInterface.class);
+    }
+
+    @Test
+    public void testGetService_multipleService_shouldReturnServiceWithHighestPriority() {
+        MultiImplsInterface service = context.getService(MultiImplsInterface.class);
+
+        Assert.assertNotNull(service);
+        Assert.assertTrue(service instanceof MultiImpl2);
+    }
+
+    @Test
+    public void testGetService_noImpl_shouldReturnEmptyOpional() {
+        NoImplInterface service = context.getService(NoImplInterface.class);
+        Assert.assertNull(service);
+    }
+
+
+    @Test
+    public void testGetServices_shouldReturnServices() {
+        {
+            Collection<InvalidPriorityInterface> services = context.getServices(InvalidPriorityInterface.class);
+            Assert.assertNotNull(services);
+            Assert.assertEquals(2, services.size());
+
+            for (InvalidPriorityInterface service : services) {
+                Assert.assertTrue(service instanceof InvalidPriorityImpl1 || service instanceof InvalidPriorityImpl2);
+            }
+        }
+
+        {
+            List<MultiImplsInterface> services = context.getServices(MultiImplsInterface.class);
+            Assert.assertNotNull(services);
+            Assert.assertEquals(3, services.size());
+
+            Assert.assertTrue(services.get(0) instanceof MultiImpl2);
+            Assert.assertTrue(services.get(1) instanceof MultiImpl1);
+            Assert.assertTrue(services.get(2) instanceof MultiImpl3);
+        }
+    }
+
+    @Test
+    public void testGetServices_redundantAccessToServices() {
+        for(int i=0;i<10;i++){
+            Collection<InvalidPriorityInterface> services = context.getServices(InvalidPriorityInterface.class);
+            Assert.assertNotNull(services);
+            Assert.assertEquals(2, services.size());
+            for (InvalidPriorityInterface service : services) {
+                Assert.assertTrue(service instanceof InvalidPriorityImpl1 || service instanceof InvalidPriorityImpl2);
+            }
+        }
+    }
+
+    @Test
+    public void testGetServices_noImpl_shouldReturnEmptyList() {
+        Collection<NoImplInterface> services = context.getServices(NoImplInterface.class);
+        Assert.assertNotNull(services);
+        Assert.assertTrue(services.isEmpty());
+    }
+
+
+    // some test interfaces and classes
+
+    public interface InvalidPriorityInterface {
+    }
+
+    @Priority(value = 50)
+    public static class InvalidPriorityImpl1 implements InvalidPriorityInterface {
+    }
+
+    @Priority(value = 50)
+    public static class InvalidPriorityImpl2 implements InvalidPriorityInterface {
+    }
+
+
+    public interface MultiImplsInterface {
+    }
+
+    public static class MultiImpl1 implements MultiImplsInterface {
+    }
+
+    @Priority(value = 500)
+    public static class MultiImpl2 implements MultiImplsInterface {
+    }
+
+    @Priority(value = -10)
+    public static class MultiImpl3 implements MultiImplsInterface {
+    }
+
+    private interface NoImplInterface {
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/PriorityServiceComparatorTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/PriorityServiceComparatorTest.java b/code/base/src/test/java/org/apache/tamaya/base/PriorityServiceComparatorTest.java
new file mode 100644
index 0000000..4206592
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/PriorityServiceComparatorTest.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.base;
+
+import org.apache.tamaya.base.configsource.SystemConfigSource;
+import org.apache.tamaya.base.PriorityServiceComparator;
+import org.junit.Test;
+
+import javax.annotation.Priority;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 12.09.16.
+ */
+public class PriorityServiceComparatorTest {
+
+    @Test
+    public void compare() throws Exception {
+        assertTrue(PriorityServiceComparator.getInstance().compare("a", "b")==0);
+        assertTrue(PriorityServiceComparator.getInstance().compare(getClass(), getClass())==0);
+        assertTrue(PriorityServiceComparator.getInstance().compare(new A(), new SystemConfigSource())==-1);
+        assertTrue(PriorityServiceComparator.getInstance().compare(new SystemConfigSource(), new A())==1);
+    }
+
+    @Priority(100)
+    private static final class A{}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/TestConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/TestConfigurationProvider.java b/code/base/src/test/java/org/apache/tamaya/base/TestConfigurationProvider.java
new file mode 100644
index 0000000..be10fb7
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/TestConfigurationProvider.java
@@ -0,0 +1,82 @@
+/*
+ * 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.base;
+
+import org.apache.tamaya.spi.Filter;
+import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.base.DefaultConfigBuilder;
+
+import javax.config.Config;
+import javax.config.spi.ConfigBuilder;
+import javax.config.spi.ConfigProviderResolver;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link Config} to evaluate the
+ * chain of {@link javax.config.spi.ConfigSource} and {@link Filter}
+ * instance to evaluate the current Configuration.
+ */
+public class TestConfigurationProvider extends ConfigProviderResolver {
+
+    private static final Map<ClassLoader,Config> configurations = new ConcurrentHashMap<>();
+
+    @Override
+    public Config getConfig() {
+        return getConfig(ServiceContext.defaultClassLoader());
+    }
+
+    @Override
+    public Config getConfig(ClassLoader classLoader){
+        Config config = configurations.get(classLoader);
+        if(config==null){
+            synchronized (configurations) {
+                config = configurations.get(classLoader);
+                if(config==null) {
+                    config = new DefaultConfigBuilder()
+                            .addDiscoveredConverters()
+                            .addDiscoveredFilters()
+                            .addDefaultSources()
+                            .addDiscoveredSources()
+                            .build();
+                    configurations.put(classLoader, config);
+                }
+            }
+        }
+        return config;
+    }
+
+    @Override
+    public ConfigBuilder getBuilder() {
+        return new DefaultConfigBuilder();
+    }
+
+    @Override
+    public void registerConfig(Config config, ClassLoader classLoader) {
+        Objects.requireNonNull(config);
+        this.configurations.put(classLoader, Objects.requireNonNull(config));
+    }
+
+    @Override
+    public void releaseConfig(Config config) {
+        configurations.forEach((k,v) -> {if(v.equals(config)){configurations.remove(k);}});
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/BaseConfigSourceTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/BaseConfigSourceTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/BaseConfigSourceTest.java
new file mode 100644
index 0000000..d2bbf0c
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/BaseConfigSourceTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.configsource.BaseConfigSource;
+import org.apache.tamaya.base.configsource.ConfigSourceComparator;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.config.spi.ConfigSource;
+import java.util.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class BaseConfigSourceTest {
+
+    @Test
+    public void givenOrdinalOverwritesGivenDefaulOrdinal() {
+        BaseConfigSource bs = new BaseConfigSource() {
+            @Override
+            public Map<String, String> getProperties() {
+                return Collections.emptyMap();
+            }
+        };
+
+        bs.setDefaultOrdinal(10);
+
+        assertThat(bs.getDefaultOrdinal()).isEqualTo(10);
+        assertThat(bs.getOrdinal()).isEqualTo(10);
+
+        bs.setOrdinal(20);
+
+        assertThat(bs.getOrdinal()).isEqualTo(20);
+    }
+
+    @Test
+    public void testGetOrdinal() {
+
+        ConfigSource defaultPropertySource = new BaseConfigSource(56) {
+
+            @Override
+            public String getName() {
+                return "testWithDefault";
+            }
+
+            @Override
+            public String getValue(String key) {
+                return null;
+            }
+
+            @Override
+            public Map<String,String> getProperties() {
+                return Collections.emptyMap();
+            }
+        };
+
+        Assert.assertEquals(56, ConfigSourceComparator.getOrdinal(defaultPropertySource));
+        Assert.assertEquals(1000, new OverriddenOrdinalConfigSource().getOrdinal());
+
+        // propertySource with invalid ordinal
+        Assert.assertEquals(1, new OverriddenInvalidOrdinalConfigSource().getOrdinal());
+    }
+
+    @Test
+    public void testGet() {
+        Assert.assertEquals(1000, new OverriddenOrdinalConfigSource().getOrdinal());
+    }
+
+    private static class OverriddenOrdinalConfigSource extends BaseConfigSource {
+
+        private OverriddenOrdinalConfigSource() {
+            super(250);
+        }
+
+        @Override
+        public String getName() {
+            return "overriddenOrdinal";
+        }
+
+        @Override
+        public Map<String,String> getProperties() {
+            Map<String,String> result = new HashMap<>(1);
+            result.put(CONFIG_ORDINAL, "1000");
+            return result;
+        }
+    }
+
+    private static class OverriddenInvalidOrdinalConfigSource extends BaseConfigSource {
+
+        private OverriddenInvalidOrdinalConfigSource() {
+            super(1);
+        }
+
+        @Override
+        public String getName() {
+            return "overriddenInvalidOrdinal";
+        }
+
+        @Override
+        public Map<String, String> getProperties() {
+            Map<String,String> result = new HashMap<>(1);
+            result.put(CONFIG_ORDINAL, "invalid");
+            return result;
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/BuildableConfigSourceProviderTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/BuildableConfigSourceProviderTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/BuildableConfigSourceProviderTest.java
new file mode 100644
index 0000000..4ebe6f7
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/BuildableConfigSourceProviderTest.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.base.configsource;
+
+import org.apache.tamaya.base.configsource.BuildableConfigSource;
+import org.apache.tamaya.base.configsource.BuildableConfigSourceProvider;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class BuildableConfigSourceProviderTest {
+
+    @Test
+    public void getPropertySources() throws Exception {
+        BuildableConfigSource ps = BuildableConfigSource.builder()
+                .withName("test1").build();
+        BuildableConfigSourceProvider prov = BuildableConfigSourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        assertNotNull(prov);
+        assertEquals(prov.getConfigSources(null).iterator().next(), ps);
+    }
+
+    @Test
+    public void equals() throws Exception {
+        BuildableConfigSource ps = BuildableConfigSource.builder()
+                .withName("test1").build();
+        BuildableConfigSourceProvider prov1 = BuildableConfigSourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        BuildableConfigSourceProvider prov2 = BuildableConfigSourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        assertEquals(prov1, prov2);
+        BuildableConfigSource ps2 = BuildableConfigSource.builder()
+                .withName("test12").build();
+        prov2 = BuildableConfigSourceProvider.builder()
+                .withPropertySourcs(ps2).build();
+        assertNotEquals(prov1, prov2);
+    }
+
+    @Test
+    public void testHashCode() throws Exception {
+        BuildableConfigSource ps = BuildableConfigSource.builder()
+                .withName("test1").build();
+        BuildableConfigSourceProvider prov1 = BuildableConfigSourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        BuildableConfigSourceProvider prov2 = BuildableConfigSourceProvider.builder()
+                .withPropertySourcs(ps).build();
+        assertEquals(prov1.hashCode(), prov2.hashCode());
+        BuildableConfigSource ps2 = BuildableConfigSource.builder()
+                .withName("test12").build();
+        prov2 = BuildableConfigSourceProvider.builder()
+                .withPropertySourcs(ps2).build();
+        assertNotEquals(prov1.hashCode(), prov2.hashCode());
+    }
+
+
+    @Test
+    public void builder() throws Exception {
+        assertNotNull(BuildableConfigSource.builder());
+        assertNotEquals(BuildableConfigSource.builder(), BuildableConfigSource.builder());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/BuildableConfigSourceTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/BuildableConfigSourceTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/BuildableConfigSourceTest.java
new file mode 100644
index 0000000..3786a89
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/BuildableConfigSourceTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.configsource.BuildableConfigSource;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class BuildableConfigSourceTest {
+    @Test
+    public void getOrdinal() throws Exception {
+        BuildableConfigSource ps1 = BuildableConfigSource.builder()
+                .withOrdinal(55).build();
+        assertEquals(55, ps1.getOrdinal());
+    }
+
+    @Test
+    public void getName() throws Exception {
+        BuildableConfigSource ps1 = BuildableConfigSource.builder()
+                .withName("test1").build();
+        assertEquals("test1", ps1.getName());
+        ps1 = BuildableConfigSource.builder().build();
+        assertNotNull(ps1.getName());
+    }
+
+    @Test
+    public void get() throws Exception {
+        BuildableConfigSource ps1 = BuildableConfigSource.builder()
+                .withProperty("a", "b").build();
+        assertEquals("b", ps1.getValue("a"));
+    }
+
+    @Test
+    public void getProperties() throws Exception {
+        BuildableConfigSource ps1 = BuildableConfigSource.builder()
+                .withProperty("a", "b").build();
+        assertNotNull(ps1.getProperties());
+        assertEquals(1, ps1.getProperties().size());
+        assertEquals("b", ps1.getProperties().get("a"));
+    }
+
+    @Test
+    public void equals() throws Exception {
+        BuildableConfigSource ps1 = BuildableConfigSource.builder()
+                .withName("test1").build();
+        BuildableConfigSource ps2 = BuildableConfigSource.builder()
+                .withName("test1").build();
+        assertEquals(ps1, ps2);
+        ps2 = BuildableConfigSource.builder()
+                .withName("test2").build();
+        assertNotEquals(ps1, ps2);
+    }
+
+    @Test
+    public void testHashCode() throws Exception {
+        BuildableConfigSource ps1 = BuildableConfigSource.builder()
+                .withName("test1").build();
+        BuildableConfigSource ps2 = BuildableConfigSource.builder()
+                .withName("test1").build();
+        assertEquals(ps1.hashCode(), ps2.hashCode());
+        ps2 = BuildableConfigSource.builder()
+                .withName("test2").build();
+        assertNotEquals(ps1.hashCode(), ps2.hashCode());
+    }
+
+    @Test
+    public void builder() throws Exception {
+        assertNotNull(BuildableConfigSource.builder());
+        assertNotEquals(BuildableConfigSource.builder(), BuildableConfigSource.builder());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/CLIPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/CLIPropertySourceTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/CLIPropertySourceTest.java
new file mode 100644
index 0000000..726b3b3
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/CLIPropertySourceTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.configsource.CLIConfigSource;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for PropertySource for reading main arguments as configuration.
+ */
+public class CLIPropertySourceTest {
+
+    @Test
+    public void setCLIProps() throws Exception {
+        System.clearProperty("main.args");
+        CLIConfigSource ps = new CLIConfigSource();
+        assertTrue(ps.getProperties().isEmpty());
+        CLIConfigSource.initMainArgs("-a", "b");
+        assertFalse(ps.getProperties().isEmpty());
+        assertEquals(ps.getValue("a"), "b");
+        CLIConfigSource.initMainArgs("--c");
+        assertFalse(ps.getProperties().isEmpty());
+        assertEquals(ps.getValue("c"), "c");
+        CLIConfigSource.initMainArgs("sss");
+        assertFalse(ps.getProperties().isEmpty());
+        assertEquals(ps.getValue("sss"), "sss");
+        CLIConfigSource.initMainArgs("-a", "b", "--c", "sss", "--val=vvv");
+        assertFalse(ps.getProperties().isEmpty());
+        assertEquals(ps.getValue("a"), "b");
+        assertEquals(ps.getValue("c"), "c");
+        assertEquals(ps.getValue("sss"), "sss");
+    // getProperties() throws Exception {
+        System.setProperty("main.args", "-a b\t--c sss  ");
+        ps = new CLIConfigSource();
+        assertFalse(ps.getProperties().isEmpty());
+        System.clearProperty("main.args");
+        assertEquals(ps.getValue("a"), "b");
+        assertEquals(ps.getValue("c"), "c");
+        assertEquals(ps.getValue("sss"), "sss");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/EnumConverterTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/EnumConverterTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/EnumConverterTest.java
new file mode 100644
index 0000000..5aefbd0
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/EnumConverterTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.apache.tamaya.spi.TypeLiteral;
+import org.apache.tamaya.base.convert.EnumConverter;
+import org.junit.Test;
+
+import java.math.RoundingMode;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Test class testing the {@link EnumConverter} class.
+ */
+public class EnumConverterTest {
+
+    private final EnumConverter testConverter = new EnumConverter(RoundingMode.class);
+
+    private final ConversionContext DUMMY_CONTEXT = new ConversionContext.Builder("someKey", Enum.class).build();
+
+    @Test
+    public void testConvert() {
+        ConversionContext.setContext(DUMMY_CONTEXT);
+        assertEquals(testConverter.convert(RoundingMode.CEILING.toString()), RoundingMode.CEILING);
+    }
+
+    @Test
+    public void testConvert_LowerCase() {
+        ConversionContext.setContext(DUMMY_CONTEXT);
+        assertEquals(testConverter.convert("ceiling"), RoundingMode.CEILING);
+    }
+
+    @Test
+    public void testConvert_MixedCase()  {
+        ConversionContext.setContext(DUMMY_CONTEXT);
+        assertEquals(testConverter.convert("CeiLinG"), RoundingMode.CEILING);
+    }
+
+    @Test
+    public void testConvert_OtherValue() {
+        ConversionContext.setContext(DUMMY_CONTEXT);
+        assertNull(testConverter.convert("fooBars"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/EnvironmentPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/EnvironmentPropertySourceTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/EnvironmentPropertySourceTest.java
new file mode 100644
index 0000000..424f773
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/EnvironmentPropertySourceTest.java
@@ -0,0 +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.base.configsource;
+
+import org.apache.tamaya.base.configsource.EnvironmentConfigSource;
+import org.junit.Test;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link EnvironmentConfigSource}.
+ */
+public class EnvironmentPropertySourceTest {
+
+    private final EnvironmentConfigSource envPropertySource = new EnvironmentConfigSource();
+
+    @Test
+    public void testGetOrdinal() throws Exception {
+        assertEquals(EnvironmentConfigSource.DEFAULT_ORDINAL, envPropertySource.getOrdinal());
+    }
+
+    @Test
+    public void testGetName() throws Exception {
+        assertEquals("environment-properties", envPropertySource.getName());
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        for (Map.Entry<String, String> envEntry : System.getenv().entrySet()) {
+            assertEquals(envPropertySource.getValue(envEntry.getKey()), envEntry.getValue());
+        }
+    }
+
+    @Test
+    public void testGetProperties() throws Exception {
+        Map<String, String> props = envPropertySource.getProperties();
+        for(Map.Entry<String,String> en: props.entrySet()){
+            if(!en.getKey().endsWith("[meta]")){
+                assertEquals(System.getenv(en.getKey()), en.getValue());
+            }
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/JavaConfigurationProviderTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/JavaConfigurationProviderTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/JavaConfigurationProviderTest.java
new file mode 100644
index 0000000..e5f1136
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/JavaConfigurationProviderTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.configsource.JavaConfigurationConfigSource;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import javax.config.spi.ConfigSource;
+
+public class JavaConfigurationProviderTest {
+
+    private static final String A_UMLAUT = "\u00E4";
+    private static final String O_UMLAUT = "\u00F6";
+
+    @Test
+    public void loadsSimpleAndXMLPropertyFilesProper() {
+        ConfigSource propertySource = new JavaConfigurationConfigSource();
+        MatcherAssert.assertThat(propertySource.getProperties().keySet(), Matchers.hasSize(7));  // double the size for .source values.
+
+        for (int i = 1; i < 6; i++) {
+            String key = "confkey" + i;
+            String value = "javaconf-value" + i;
+
+            MatcherAssert.assertThat(value, Matchers.equalTo(propertySource.getValue(key)));
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/MapPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/MapPropertySourceTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/MapPropertySourceTest.java
new file mode 100644
index 0000000..433b12b
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/MapPropertySourceTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.configsource.MapConfigSource;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MapPropertySourceTest {
+
+    private Map<String,String> sourceMap;
+    private Properties sourceProperties;
+
+    @Before
+    public void createMapAndProperties() throws Exception {
+        sourceMap = new HashMap<>();
+        sourceMap.put("a", "AAA");
+        sourceMap.put("b", "BBB");
+
+        sourceProperties = new Properties();
+        sourceProperties.setProperty("a", "AAA");
+        sourceProperties.setProperty("b", "BBB");
+    }
+
+    @Test
+    public void sourceWillProperlyInitializedWithMapWithoutPrefix() throws Exception {
+        MapConfigSource propertySource = new MapConfigSource("UT", sourceMap);
+
+        assertThat(propertySource.getProperties()).describedAs("Should contain exactly 2 properties.")
+                                                  .hasSize(2);
+        assertThat(propertySource.getValue("a")).isNotNull();
+        assertThat(propertySource.getValue("b")).isNotNull();
+    }
+
+    @Test
+    public void sourceWillProperlyInitializedWithMapWithPrefix() throws Exception {
+        MapConfigSource propertySource = new MapConfigSource("UT", sourceMap, "pre-");
+
+        assertThat(propertySource.getProperties()).describedAs("Should contain exactly 2 properties.")
+                                                  .hasSize(2);
+        assertThat(propertySource.getValue("pre-a")).isNotNull();
+        assertThat(propertySource.getValue("pre-b")).isNotNull();
+    }
+
+    @Test
+    public void sourceWillProperlyInitializedWithPropertiesWithPrefix() throws Exception {
+        MapConfigSource propertySource = new MapConfigSource("UT", sourceProperties, "pre-");
+
+        assertThat(propertySource.getProperties()).describedAs("Should contain exactly 2 properties.")
+                                                  .hasSize(2);
+        assertThat(propertySource.getValue("pre-a")).isNotNull();
+        assertThat(propertySource.getValue("pre-b")).isNotNull();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/PropertiesFilePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/PropertiesFilePropertySourceTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/PropertiesFilePropertySourceTest.java
new file mode 100644
index 0000000..2b6ba65
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/PropertiesFilePropertySourceTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.configsource.SimpleConfigSource;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.config.spi.ConfigSource;
+
+public class PropertiesFilePropertySourceTest {
+
+    private final SimpleConfigSource testfilePropertySource = new SimpleConfigSource(Thread.currentThread()
+            .getContextClassLoader().getResource("testfile.properties"));
+    private final SimpleConfigSource overrideOrdinalPropertySource = new SimpleConfigSource(
+            Thread.currentThread().getContextClassLoader().getResource("overrideOrdinal.properties"));
+
+
+    @Test
+    public void testGetOrdinal() {
+        Assert.assertEquals(0, testfilePropertySource.getOrdinal());
+        Assert.assertEquals(Integer.parseInt(overrideOrdinalPropertySource.getValue(ConfigSource.CONFIG_ORDINAL)),
+                overrideOrdinalPropertySource.getOrdinal());
+    }
+
+
+    @Test
+    public void testGet() {
+        Assert.assertEquals("val3", testfilePropertySource.getValue("key3"));
+        Assert.assertEquals("myval5", overrideOrdinalPropertySource.getValue("mykey5"));
+        Assert.assertNull(testfilePropertySource.getValue("nonpresentkey"));
+    }
+
+
+    @Test
+    public void testGetProperties() throws Exception {
+        Assert.assertEquals(5, testfilePropertySource.getProperties().size());
+        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key1"));
+        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key2"));
+        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key3"));
+        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key4"));
+        Assert.assertTrue(testfilePropertySource.getProperties().containsKey("key5"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/SimplePropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/SimplePropertySourceTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/SimplePropertySourceTest.java
new file mode 100644
index 0000000..581f42b
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/SimplePropertySourceTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.configsource.SimpleConfigSource;
+import org.junit.Test;
+
+import java.net.URL;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.endsWith;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.aMapWithSize;
+import static org.hamcrest.Matchers.hasEntry;
+
+public class SimplePropertySourceTest {
+    @Test
+    public void successfulCreationWithPropertiesFromXMLPropertiesFile() {
+        URL resource = getClass().getResource("/valid-properties.xml");
+
+        SimpleConfigSource source = new SimpleConfigSource(resource);
+
+        assertThat(source, notNullValue());
+        assertThat(source.getProperties(), aMapWithSize(2)); // double the size for .source values.
+        assertThat(source.getProperties(), hasEntry("a", "b"));
+        assertThat(source.getProperties(), hasEntry("b", "1"));
+
+    }
+
+    @Test
+    public void failsToCreateFromNonXMLPropertiesXMLFile() {
+        URL resource = getClass().getResource("/non-xml-properties.xml");
+        Exception catchedException = null;
+
+        try {
+            new SimpleConfigSource(resource);
+        } catch (Exception ce) {
+            catchedException = ce;
+        }
+
+        assertThat(catchedException.getMessage(), allOf(startsWith("Error loading properties from"),
+                                                        endsWith("non-xml-properties.xml")));
+    }
+
+    @Test
+    public void failsToCreateFromInvalidPropertiesXMLFile() {
+        URL resource = getClass().getResource("/invalid-properties.xml");
+        Exception catchedException = null;
+
+        try {
+            new SimpleConfigSource(resource);
+        } catch (Exception ce) {
+            catchedException = ce;
+        }
+
+        assertThat(catchedException.getMessage(), allOf(startsWith("Error loading properties from"),
+                                                        endsWith("invalid-properties.xml")));
+    }
+
+
+    @Test
+    public void successfulCreationWithPropertiesFromSimplePropertiesFile() {
+        URL resource = getClass().getResource("/testfile.properties");
+
+        SimpleConfigSource source = new SimpleConfigSource(resource);
+
+        assertThat(source, notNullValue());
+        assertThat(source.getProperties(), aMapWithSize(5)); // double the size for .source values.
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/SystemPropertySourceTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/SystemPropertySourceTest.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/SystemPropertySourceTest.java
new file mode 100644
index 0000000..54aead3
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/SystemPropertySourceTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.configsource.SystemConfigSource;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Map;
+import java.util.Properties;
+
+import static javax.config.spi.ConfigSource.CONFIG_ORDINAL;
+
+public class SystemPropertySourceTest {
+
+    private final SystemConfigSource testPropertySource = new SystemConfigSource();
+
+
+    @Test
+    public void testGetOrdinal() throws Exception {
+
+        // test the default ordinal
+        Assert.assertEquals(SystemConfigSource.DEFAULT_ORDINAL, testPropertySource.getOrdinal());
+
+        // set the ordinal to 1001
+        System.setProperty(CONFIG_ORDINAL, "1001");
+        Assert.assertEquals(1001, new SystemConfigSource().getOrdinal());
+        // currently its not possible to change ordinal at runtime
+
+        // reset it to not destroy other tests!!
+        System.clearProperty(CONFIG_ORDINAL);
+    }
+
+    @Test
+    public void testGetName() throws Exception {
+        Assert.assertEquals("system-properties", testPropertySource.getName());
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        String propertyKeyToCheck = System.getProperties().stringPropertyNames().iterator().next();
+
+        String property = testPropertySource.getValue(propertyKeyToCheck);
+        Assert.assertNotNull("Property '" + propertyKeyToCheck + "' is not present in " +
+                SystemConfigSource.class.getSimpleName(), property);
+        Assert.assertEquals(System.getProperty(propertyKeyToCheck), property);
+    }
+
+    @Test
+    public void testGetProperties() throws Exception {
+        checkWithSystemProperties(testPropertySource.getProperties());
+
+        // modify system properties
+        System.setProperty("test", "myTestVal");
+
+        checkWithSystemProperties(testPropertySource.getProperties());
+
+        // cleanup
+        System.clearProperty("test");
+    }
+
+    private void checkWithSystemProperties(Map<String,String> toCheck) {
+        Properties systemEntries = System.getProperties();
+        int num = 0;
+        for (Map.Entry<String,String> propertySourceEntry : toCheck.entrySet()) {
+            if(propertySourceEntry.getKey().endsWith("[meta]")){
+                continue; // meta entry
+            }
+            num ++;
+            Assert.assertEquals("Entry values for key '" + propertySourceEntry.getKey() + "' do not match",
+                                systemEntries.getProperty(propertySourceEntry.getKey()), propertySourceEntry.getValue());
+        }
+        Assert.assertEquals("size of System.getProperties().entrySet() must be the same as SystemPropertySrouce.getProperties().entrySet()",
+                systemEntries.size(), num);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/configsource/TestConfigDefaultSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/configsource/TestConfigDefaultSource.java b/code/base/src/test/java/org/apache/tamaya/base/configsource/TestConfigDefaultSource.java
new file mode 100644
index 0000000..5011572
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/configsource/TestConfigDefaultSource.java
@@ -0,0 +1,52 @@
+/*
+ * 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.base.configsource;
+
+
+import org.apache.tamaya.base.configsource.BaseConfigSource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test provider reading properties from classpath:cfg/defaults/**.properties.
+ */
+public class TestConfigDefaultSource extends BaseConfigSource {
+
+    private Map<String,String> properties = new HashMap<>();
+
+    public TestConfigDefaultSource() {
+        super(100);
+        properties.put("name","Anatole");
+        properties.put("name2","Sabine");
+        properties = Collections.unmodifiableMap(properties);
+    }
+
+    @Override
+    public String getName() {
+        return "default-testdata-properties";
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/convert/A.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/convert/A.java b/code/base/src/test/java/org/apache/tamaya/base/convert/A.java
new file mode 100644
index 0000000..ca801f1
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/convert/A.java
@@ -0,0 +1,29 @@
+/*
+ * 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.base.convert;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+class A implements AutoCloseable{
+    @Override
+    public void close() throws Exception {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/convert/B.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/convert/B.java b/code/base/src/test/java/org/apache/tamaya/base/convert/B.java
new file mode 100644
index 0000000..505a613
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/convert/B.java
@@ -0,0 +1,29 @@
+/*
+ * 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.base.convert;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class B extends A implements Runnable{
+    @Override
+    public void run() {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/convert/C.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/convert/C.java b/code/base/src/test/java/org/apache/tamaya/base/convert/C.java
new file mode 100644
index 0000000..3a00bea
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/convert/C.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.base.convert;
+
+import java.io.IOException;
+import java.nio.CharBuffer;
+
+/**
+ * Test class for testing transitively evaluated property converters.
+ */
+public class C extends B implements Readable{
+
+    private final String inValue;
+
+    public C(String inValue){
+        this.inValue = inValue;
+    }
+
+    @Override
+    public int read(CharBuffer cb) throws IOException {
+        return 0;
+    }
+
+    /**
+     * Returns the input value, set on creation. Used for test assertion.
+     * @return the in value.
+     */
+    public String getInValue() {
+        return inValue;
+    }
+
+    @Override
+    public String toString() {
+        return "C{" +
+                "inValue='" + inValue + '\'' +
+                '}';
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/convert/CTestConverter.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/convert/CTestConverter.java b/code/base/src/test/java/org/apache/tamaya/base/convert/CTestConverter.java
new file mode 100644
index 0000000..494c571
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/convert/CTestConverter.java
@@ -0,0 +1,31 @@
+/*
+ * 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.base.convert;
+
+import javax.config.spi.Converter;
+
+/**
+ * Created by Anatole on 13.06.2015.
+ */
+public class CTestConverter implements Converter<C> {
+    @Override
+    public C convert(String value) {
+        return new C(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/convert/ConverterManagerTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/convert/ConverterManagerTest.java b/code/base/src/test/java/org/apache/tamaya/base/convert/ConverterManagerTest.java
new file mode 100644
index 0000000..43bd244
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/convert/ConverterManagerTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.base.convert;
+
+import org.junit.Test;
+
+import javax.config.spi.Converter;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+
+public class ConverterManagerTest {
+
+    private final ConversionContext DUMMY_CONTEXT = new ConversionContext.Builder(
+            "someKey", Object.class).build();
+
+    @Test
+    public void customTypeWithFactoryMethodOfIsRecognizedAsSupported() {
+        ConverterManager manager = new ConverterManager();
+
+        assertThat(manager.isTargetTypeSupported(MyType.class),
+                   is(true));
+    }
+
+    @Test
+    public void factoryMethodOfIsUsedAsConverter() {
+        ConverterManager manager = new ConverterManager();
+
+        List<Converter> converters = manager.getConverters(
+                MyType.class);
+
+        assertThat(converters, hasSize(1));
+
+        Converter<MyType> converter = converters.get(0);
+
+        Object result = converter.convert("IN");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(MyType.class));
+        assertThat(((MyType)result).getValue(), equalTo("IN"));
+    }
+
+    @Test
+    public void testDirectConverterMapping(){
+        ConverterManager manager = new ConverterManager();
+        List<Converter<C>> converters = List.class.cast(manager.getConverters(C.class));
+        assertThat(converters, hasSize(1));
+
+        Converter<C> converter = converters.get(0);
+        C result = converter.convert("testDirectConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat((result).getInValue(), equalTo("testDirectConverterMapping"));
+    }
+
+    @Test
+    public void testDirectSuperclassConverterMapping(){
+        ConverterManager manager = new ConverterManager();
+        manager.addDiscoveredConverters();
+        List<Converter<B>> converters = List.class.cast(manager.getConverters(B.class));
+        assertThat(converters, hasSize(1));
+        converters = List.class.cast(manager.getConverters(B.class));
+        assertThat(converters, hasSize(1));
+
+        Converter<B> converter = converters.get(0);
+        B result = converter.convert("testDirectSuperclassConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectSuperclassConverterMapping"));
+    }
+
+    @Test
+    public void testMultipleConverterLoad(){
+        ConverterManager manager = new ConverterManager();
+        manager.addDiscoveredConverters();
+        List<Converter<B>> converters = List.class.cast(manager.getConverters(B.class));
+        assertThat(converters, hasSize(1));
+        manager = new ConverterManager();
+        converters = List.class.cast(manager.getConverters(B.class));
+        assertThat(converters, hasSize(0));
+        manager.addDiscoveredConverters();
+        converters = List.class.cast(manager.getConverters(B.class));
+        assertThat(converters, hasSize(1));
+    }
+
+    @Test
+    public void testTransitiveSuperclassConverterMapping(){
+        ConverterManager manager = new ConverterManager();
+        manager.addDiscoveredConverters();
+        List<Converter<A>> converters = List.class.cast(manager.getConverters(A.class));
+        assertThat(converters, hasSize(1));
+
+        Converter<A> converter = converters.get(0);
+        A result = converter.convert("testTransitiveSuperclassConverterMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveSuperclassConverterMapping"));
+    }
+
+    @Test
+    public void testDirectInterfaceMapping(){
+        ConverterManager manager = new ConverterManager();
+        manager.addDiscoveredConverters();
+        List<Converter<Readable>> converters = List.class.cast(manager.getConverters(Readable.class));
+        assertThat(converters, hasSize(1));
+
+        Converter<Readable> converter = converters.get(0);
+        Readable result = converter.convert("testDirectInterfaceMapping");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testDirectInterfaceMapping"));
+    }
+
+    @Test
+    public void testTransitiveInterfaceMapping1(){
+        ConverterManager manager = new ConverterManager();
+        manager.addDiscoveredConverters();
+        List<Converter<Runnable>> converters = List.class.cast(manager.getConverters(Runnable.class));
+        assertThat(converters, hasSize(1));
+
+        Converter<Runnable> converter = converters.get(0);
+        Runnable result = converter.convert("testTransitiveInterfaceMapping1");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping1"));
+    }
+
+    @Test
+    public void testTransitiveInterfaceMapping2(){
+        ConverterManager manager = new ConverterManager();
+        manager.addDiscoveredConverters();
+        List<Converter<AutoCloseable>> converters = List.class.cast(manager.getConverters(AutoCloseable.class));
+        assertThat(converters, hasSize(1));
+
+        Converter<AutoCloseable> converter = converters.get(0);
+        AutoCloseable result = converter.convert("testTransitiveInterfaceMapping2");
+
+        assertThat(result, notNullValue());
+        assertThat(result, instanceOf(C.class));
+        assertThat(((C)result).getInValue(), equalTo("testTransitiveInterfaceMapping2"));
+    }
+
+    public static class MyType {
+        private final String typeValue;
+
+        private MyType(String value) {
+            typeValue = value;
+        }
+
+        public static MyType of(String source) {
+            return new MyType(source);
+        }
+
+        public String getValue() {
+            return typeValue;
+        }
+
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/convert/EnumConverterTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/convert/EnumConverterTest.java b/code/base/src/test/java/org/apache/tamaya/base/convert/EnumConverterTest.java
new file mode 100644
index 0000000..e8c40f6
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/convert/EnumConverterTest.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.base.convert;
+
+import org.apache.tamaya.base.convert.EnumConverter;
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.apache.tamaya.spi.TypeLiteral;
+import org.junit.Test;
+
+import java.math.RoundingMode;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Test class testing the {@link EnumConverter} class.
+ */
+public class EnumConverterTest {
+
+	private final EnumConverter<RoundingMode> testConverter = new EnumConverter<>(RoundingMode.class);
+
+	private final ConversionContext DUMMY_CONTEXT = new ConversionContext.Builder("someKey", Enum.class)
+			.build();
+
+	@Test
+	public void testConversionWithMixedCasing() {
+		for (String input : Arrays.asList(RoundingMode.CEILING.toString(), "ceiling", "CeiLinG")) {
+			assertEquals(RoundingMode.CEILING, testConverter.convert(input));
+		}
+	}
+
+	@Test
+	public void testConvert_OtherValue() {
+		assertNull(testConverter.convert("fooBars"));
+	}
+}
\ No newline at end of file


[6/6] incubator-tamaya git commit: Added full JSR implementation.

Posted by an...@apache.org.
Added full JSR implementation.

Signed-off-by: Anatole Tresch <an...@apache.org>


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

Branch: refs/heads/configjsr
Commit: 063f8adadaaa8ecb650c9f5195ac94ff6d8fae95
Parents: a31af00
Author: Anatole Tresch <an...@apache.org>
Authored: Sun Dec 17 09:00:16 2017 +0100
Committer: Anatole Tresch <an...@apache.org>
Committed: Sun Dec 17 09:00:16 2017 +0100

----------------------------------------------------------------------
 .../org/apache/tamaya/base/DefaultConfig.java   | 165 +++++
 .../tamaya/base/DefaultConfigBuilder.java       | 305 +++++++++
 .../tamaya/base/DefaultServiceContext.java      | 225 +++++++
 .../tamaya/base/PriorityServiceComparator.java  |  84 +++
 .../org/apache/tamaya/base/ReflectionUtil.java  |  42 ++
 .../base/configsource/BaseConfigSource.java     | 170 +++++
 .../configsource/BuildableConfigSource.java     | 208 ++++++
 .../BuildableConfigSourceProvider.java          | 113 ++++
 .../base/configsource/CLIConfigSource.java      | 130 ++++
 .../configsource/ConfigSourceComparator.java    | 117 ++++
 .../base/configsource/ConfigSourceManager.java  | 375 +++++++++++
 .../configsource/EnvironmentConfigSource.java   | 281 +++++++++
 .../JavaConfigurationConfigSource.java          | 131 ++++
 .../base/configsource/MapConfigSource.java      |  98 +++
 .../PropertiesResourceConfigSource.java         | 109 ++++
 .../base/configsource/SimpleConfigSource.java   | 282 +++++++++
 .../base/configsource/SystemConfigSource.java   | 186 ++++++
 .../base/configsource/WrappedConfigSource.java  | 117 ++++
 .../tamaya/base/configsource/package-info.java  |  23 +
 .../tamaya/base/convert/ConversionContext.java  | 253 ++++++++
 .../tamaya/base/convert/ConverterManager.java   | 630 +++++++++++++++++++
 .../tamaya/base/convert/EnumConverter.java      |  81 +++
 .../tamaya/base/convert/package-info.java       |  23 +
 .../tamaya/base/filter/FilterComparator.java    |  72 +++
 .../tamaya/base/filter/FilterContext.java       | 144 +++++
 .../tamaya/base/filter/FilterManager.java       | 273 ++++++++
 .../apache/tamaya/base/filter/package-info.java |  23 +
 .../org/apache/tamaya/base/package-info.java    |  23 +
 .../org/apache/tamaya/spi/ConfigContext.java    | 154 +++++
 .../java/org/apache/tamaya/spi/ConfigValue.java | 209 ++++++
 .../apache/tamaya/spi/ConfigValueBuilder.java   | 179 ++++++
 .../org/apache/tamaya/spi/Experimental.java     |  32 +
 .../main/java/org/apache/tamaya/spi/Filter.java |  50 ++
 .../org/apache/tamaya/spi/ServiceContext.java   | 147 +++++
 .../tamaya/spi/ServiceContextManager.java       | 118 ++++
 .../spi/StandaloneConfigContextBuilder.java     | 407 ++++++++++++
 .../apache/tamaya/spi/TamayaConfigBuilder.java  | 333 ++++++++++
 .../java/org/apache/tamaya/spi/TypeLiteral.java | 225 +++++++
 .../org/apache/tamaya/spi/package-info.java     |  23 +
 .../tamaya/base/DefaultConfigBuilderTest.java   | 198 ++++++
 .../apache/tamaya/base/DefaultConfigTest.java   | 130 ++++
 .../tamaya/base/DefaultServiceContextTest.java  | 137 ++++
 .../base/PriorityServiceComparatorTest.java     |  45 ++
 .../tamaya/base/TestConfigurationProvider.java  |  82 +++
 .../base/configsource/BaseConfigSourceTest.java | 124 ++++
 .../BuildableConfigSourceProviderTest.java      |  78 +++
 .../configsource/BuildableConfigSourceTest.java |  89 +++
 .../configsource/CLIPropertySourceTest.java     |  59 ++
 .../base/configsource/EnumConverterTest.java    |  63 ++
 .../EnvironmentPropertySourceTest.java          |  62 ++
 .../JavaConfigurationProviderTest.java          |  46 ++
 .../configsource/MapPropertySourceTest.java     |  76 +++
 .../PropertiesFilePropertySourceTest.java       |  60 ++
 .../configsource/SimplePropertySourceTest.java  |  88 +++
 .../configsource/SystemPropertySourceTest.java  |  92 +++
 .../configsource/TestConfigDefaultSource.java   |  52 ++
 .../java/org/apache/tamaya/base/convert/A.java  |  29 +
 .../java/org/apache/tamaya/base/convert/B.java  |  29 +
 .../java/org/apache/tamaya/base/convert/C.java  |  56 ++
 .../tamaya/base/convert/CTestConverter.java     |  31 +
 .../base/convert/ConverterManagerTest.java      | 184 ++++++
 .../tamaya/base/convert/EnumConverterTest.java  |  53 ++
 .../base/services/DefaultServiceContext.java    | 204 ++++++
 .../tamaya/filter/FilterComparatorTest.java     |  75 +++
 .../resources/META-INF/javaconfig.properties    |  22 +
 .../src/test/resources/META-INF/javaconfig.xml  |  25 +
 .../javax.config.spi.ConfigProviderResolver     |  18 +
 .../services/javax.config.spi.Converter         |  19 +
 ...tServiceContextTest$InvalidPriorityInterface |  18 +
 ...efaultServiceContextTest$MultiImplsInterface |  20 +
 .../org.apache.tamaya.spi.ServiceContext        |  19 +
 .../src/test/resources/invalid-properties.xml   |  25 +
 .../src/test/resources/non-xml-properties.xml   |  18 +
 .../test/resources/overrideOrdinal.properties   |  25 +
 .../base/src/test/resources/testfile.properties |  22 +
 .../src/test/resources/valid-properties.xml     |  25 +
 .../examples/customconfigsource/Main.java       |  91 +++
 .../customconfigsource/SimpleConfigSource.java  |  65 ++
 .../SimpleConfigSourceProvider.java             |  49 ++
 .../customconfigsource/package-info.java        |  19 +
 .../examples/custompropertysource/Main.java     |  91 ---
 .../SimpleConfigSource.java                     |  64 --
 .../SimplePropertySourceProvider.java           |  49 --
 .../custompropertysource/package-info.java      |  19 -
 .../services/javax.config.spi.ConfigSource      |  19 +
 .../javax.config.spi.ConfigSourceProvider       |  19 +
 .../org.apache.tamaya.spi.PropertySource        |  19 -
 ...org.apache.tamaya.spi.PropertySourceProvider |  19 -
 88 files changed, 9220 insertions(+), 261 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java
new file mode 100644
index 0000000..a3762f1
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfig.java
@@ -0,0 +1,165 @@
+/*
+ * 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.base;
+
+
+import org.apache.tamaya.base.configsource.ConfigSourceManager;
+import org.apache.tamaya.base.convert.ConverterManager;
+import org.apache.tamaya.spi.ConfigValue;
+import org.apache.tamaya.spi.Filter;
+import org.apache.tamaya.base.filter.FilterManager;
+import org.apache.tamaya.spi.*;
+
+import javax.config.Config;
+import javax.config.spi.ConfigSource;
+import javax.config.spi.Converter;
+import java.lang.reflect.Type;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the Configuration API.
+ */
+public class DefaultConfig implements Config, ConfigContextSupplier {
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(DefaultConfig.class.getName());
+
+    /**
+     * The current {@link ConverterManager} of the current instance.
+     */
+    private final ConverterManager converterManager = new ConverterManager();
+
+    /**
+     * The current {@link ConverterManager} of the current instance.
+     */
+    private final FilterManager filterManager = new FilterManager();
+
+    /**
+     * The current {@link ConfigSourceManager} of the current instance.
+     */
+    private final ConfigSourceManager configSourceManager = new ConfigSourceManager();
+
+
+    /**
+     * Constructor.
+     * @param configContext The configuration Context to be used.
+     */
+    public DefaultConfig(ConfigContext configContext){
+        this.configSourceManager.addSources(configContext.getSources());
+        this.configSourceManager.setConfigValueCombinationPolicy(configContext.getConfigValueCombinationPolicy());
+        configContext.getConverters().forEach((t,c) -> this.converterManager.addConverter(t, Collection.class.cast(c)));
+        this.filterManager.addFilter(configContext.getFilters());
+    }
+
+    /**
+     * Accesses the current String value for the given key and tries to convert it
+     * using the {@link javax.config.spi.Converter} instances provided by the current
+     * {@link ConfigContext}.
+     *
+     * @param key  the property's absolute, or relative path, e.g. @code
+     *             a/b/c/d.myProperty}, never {@code null}.
+     * @param targetType The target type required, not {@code null}.
+     * @param <T>  the value type
+     * @return the converted value, never {@code null}.
+     */
+    @Override
+    public <T> T getValue(String key, Class<T> targetType) {
+        Objects.requireNonNull(key, "Key must not be null.");
+        Objects.requireNonNull(targetType, "Target type must not be null.");
+
+        ConfigValue value = configSourceManager.evaluteRawValue(key);
+        if(value==null || value.getValue()==null){
+            return null;
+        }
+        value = filterManager.filterValue(value, this);
+        if(value!=null){
+            return (T)converterManager.convertValue(key, value.getValue(), targetType, this);
+        }
+        return null;
+    }
+
+
+    @Override
+    public <T> Optional<T> getOptionalValue(String key, Class<T> type) {
+        Objects.requireNonNull(key, "Key must not be null.");
+        Objects.requireNonNull(type, "Type must not be null.");
+        T val = getValue(key, type);
+        return Optional.ofNullable(val);
+    }
+
+    /**
+     * Get the current properties, composed by the loaded {@link ConfigSource} and filtered
+     * by registered {@link Filter}.
+     *
+     * @return the final properties.
+     */
+    @Override
+    public Set<String> getPropertyNames() {
+        Map<String, ConfigValue> filtered = configSourceManager.evaluateRawValues();
+        return filtered.keySet();
+    }
+
+    @Override
+    public Iterable<ConfigSource> getConfigSources() {
+        return configSourceManager.getSources();
+    }
+
+
+    public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+        Objects.requireNonNull(key);
+        Objects.requireNonNull(type);
+
+        Optional<T> val = getOptionalValue(key, type);
+        return val.orElse(defaultValue);
+    }
+
+    @Override
+    public ConfigContext getConfigContext() {
+        return new ConfigContext() {
+            @Override
+            public List<ConfigSource> getSources() {
+                return configSourceManager.getSources();
+            }
+
+            @Override
+            public List<Filter> getFilters() {
+                return filterManager.getFilters();
+            }
+
+            @Override
+            public Map<Type, List<Converter>> getConverters() {
+                return converterManager.getConverters();
+            }
+        };
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder("Configuration{\n")
+            .append(this.configSourceManager).append('\n')
+            .append(this.filterManager).append('\n')
+            .append(this.converterManager).append('\n')
+            .append('}');
+        return b.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/DefaultConfigBuilder.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/DefaultConfigBuilder.java b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfigBuilder.java
new file mode 100644
index 0000000..2eb851a
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/DefaultConfigBuilder.java
@@ -0,0 +1,305 @@
+/*
+ * 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.base;
+
+import org.apache.tamaya.base.configsource.*;
+import org.apache.tamaya.base.convert.ConverterManager;
+import org.apache.tamaya.base.filter.FilterManager;
+import org.apache.tamaya.spi.TamayaConfigBuilder;
+import org.apache.tamaya.spi.*;
+import org.apache.tamaya.spi.Filter;
+
+import javax.config.Config;
+import javax.config.spi.ConfigSource;
+import javax.config.spi.Converter;
+import java.lang.reflect.Type;
+import java.util.*;
+
+/**
+ * Default implementation of {@link TamayaConfigBuilder}.
+ */
+public class DefaultConfigBuilder implements TamayaConfigBuilder {
+
+    protected final ConfigSourceManager configSourceManager = new ConfigSourceManager();
+    protected final ConverterManager converterManager = new ConverterManager();
+    protected final FilterManager filterManager = new FilterManager();
+
+    /**
+     * Creates a new builder instance.
+     */
+    public DefaultConfigBuilder() {
+    }
+
+    /**
+     * Creates a new builder instance.
+     */
+    public DefaultConfigBuilder(ConfigContext context) {
+        this.configSourceManager.addSources(context.getSources());
+        this.configSourceManager.setConfigValueCombinationPolicy(context.getConfigValueCombinationPolicy());
+        this.filterManager.addFilter(context.getFilters());
+        context.getConverters().forEach((t,c) -> converterManager.addConverter(t, Collection.class.cast(c)));
+    }
+
+    /**
+     * Creates a new builder instance initializing it with the given context.
+     * @param contextSupplier the context supplier to be used, not null.
+     */
+    public DefaultConfigBuilder(ConfigContextSupplier contextSupplier) {
+        this(((ConfigContextSupplier)contextSupplier).getConfigContext());
+    }
+
+//    /**
+//     * Allows to set configuration context during unit tests.
+//     */
+//    @Override
+//    public TamayaConfigBuilder setConfiguration(Config configuration) {
+//        this.contextBuilder.withContext(((DefaultConfig)configuration).getConfigContext());
+//        return this;
+//    }
+
+
+    @Override
+    public TamayaConfigBuilder withSources(ConfigSource... sources){
+        this.configSourceManager.addSources(sources);
+        return this;
+    }
+
+    @Override
+    public <T> TamayaConfigBuilder withConverter(Class<T> type, Converter<T> converter) {
+        this.converterManager.addConverter(type, converter);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder withConverters(Converter<?>... converters) {
+        this.converterManager.addConverters(converters);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder withConverters(Collection<Converter<?>> converters) {
+        this.converterManager.addConverters(Collection.class.cast(converters));
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder withSources(Collection<ConfigSource> sources){
+        this.configSourceManager.addSources(sources);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder addDiscoveredFilters() {
+        this.filterManager.addDefaultFilters();
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder addDefaultSources() {
+        this.configSourceManager.addSources(
+                new EnvironmentConfigSource(),
+                new JavaConfigurationConfigSource(),
+                new CLIConfigSource(),
+                new SystemConfigSource());
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder addDiscoveredSources() {
+        this.configSourceManager.addDiscoveredSources();
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder addDiscoveredConverters() {
+        this.converterManager.addDiscoveredConverters();
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder forClassLoader(ClassLoader loader) {
+        this.configSourceManager.setClassloader(loader);
+        this.filterManager.setClassloader(loader);
+        this.converterManager.setClassloader(loader);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder removeSources(ConfigSource... propertySources) {
+        this.configSourceManager.removeSources(propertySources);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder removeSources(Collection<ConfigSource> propertySources) {
+        this.configSourceManager.removeSources(propertySources);
+        return this;
+    }
+
+    @Override
+    public List<ConfigSource> getSources() {
+        return this.configSourceManager.getSources();
+    }
+
+    @Override
+    public TamayaConfigBuilder increasePriority(ConfigSource propertySource) {
+        this.configSourceManager.increasePriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder decreasePriority(ConfigSource propertySource) {
+        this.configSourceManager.decreasePriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder highestPriority(ConfigSource propertySource) {
+        this.configSourceManager.highestPriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder lowestPriority(ConfigSource propertySource) {
+        this.configSourceManager.lowestPriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder withFilters(Filter... filters){
+        this.filterManager.addFilter(filters);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder withFilters(Collection<Filter> filters){
+        this.filterManager.addFilter(filters);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder removeFilters(Filter... filters) {
+        this.filterManager.removeFilters(filters);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder removeFilters(Collection<Filter> filters) {
+        this.filterManager.removeFilters(filters);
+        return this;
+    }
+
+
+    @Override
+    public <T> TamayaConfigBuilder removeConverters(Class<T> typeToConvert,
+                                                    Converter<T>... converters) {
+        this.converterManager.removeConverters(typeToConvert, converters);
+        return this;
+    }
+
+    @Override
+    public <T> TamayaConfigBuilder removeConverters(Class<T> typeToConvert,
+                                                    Collection<Converter<T>> converters) {
+        this.converterManager.removeConverters(typeToConvert, Collection.class.cast(converters));
+        return this;
+    }
+
+    @Override
+    public <T> TamayaConfigBuilder removeConverters(Class<T> typeToConvert) {
+        this.converterManager.removeConverters(typeToConvert);
+        return this;
+    }
+
+
+    @Override
+    public TamayaConfigBuilder withPropertyValueCombinationPolicy(ConfigValueCombinationPolicy combinationPolicy){
+        this.configSourceManager.setConfigValueCombinationPolicy(combinationPolicy);
+        return this;
+    }
+
+    @Override
+    public <T> TamayaConfigBuilder withConverters(Class<T> type, Converter<T>... converters){
+        this.converterManager.addConverter(type, converters);
+        return this;
+    }
+
+    @Override
+    public <T> TamayaConfigBuilder withConverters(Class<T> type, Collection<Converter<T>> converters){
+        this.converterManager.addConverter(type, Collection.class.cast(converters));
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder sortFilter(Comparator<Filter> comparator) {
+        this.filterManager.sortFilter(comparator);
+        return this;
+    }
+
+    @Override
+    public TamayaConfigBuilder sortSources(Comparator<ConfigSource> comparator) {
+        this.configSourceManager.sortSources(comparator);
+        return this;
+    }
+
+    @Override
+    public List<Filter> getFilters() {
+        return this.filterManager.getFilters();
+    }
+
+    @Override
+    public Map<Type, List<Converter>> getConverter() {
+        return this.converterManager.getConverters();
+    }
+
+    /**
+     * Builds a new configuration based on the configuration of this builder instance.
+     *
+     * @return a new {@link Config configuration instance},
+     *         never {@code null}.
+     */
+    @Override
+    public Config build() {
+        return new DefaultConfig(getConfigContext());
+    }
+
+    @Override
+    public ConfigContext getConfigContext() {
+        return new ConfigContext() {
+            @Override
+            public List<ConfigSource> getSources() {
+                return configSourceManager.getSources();
+            }
+
+            @Override
+            public List<Filter> getFilters() {
+                return filterManager.getFilters();
+            }
+
+            @Override
+            public Map<Type, List<Converter>> getConverters() {
+                return converterManager.getConverters();
+            }
+
+            @Override
+            public ConfigValueCombinationPolicy getConfigValueCombinationPolicy() {
+                return configSourceManager.getConfigValueCombinationPolicy();
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/DefaultServiceContext.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/DefaultServiceContext.java b/code/base/src/main/java/org/apache/tamaya/base/DefaultServiceContext.java
new file mode 100644
index 0000000..752fd3c
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/DefaultServiceContext.java
@@ -0,0 +1,225 @@
+/*
+ * 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.base;
+
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.io.IOException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link ServiceContext} interface and hereby uses the JDK
+ * {@link ServiceLoader} to load the services required.
+ */
+public final class DefaultServiceContext implements ServiceContext {
+    private static final Logger LOG = Logger.getLogger(DefaultServiceContext.class.getName());
+    /**
+     * List current services loaded, per class.
+     */
+    private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+    /**
+     * Singletons.
+     */
+    private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+    @SuppressWarnings("rawtypes")
+	private Map<Class, Class> factoryTypes = new ConcurrentHashMap<>();
+
+    @Override
+    public <T> T getService(Class<T> serviceType) {
+        return getService(serviceType, ServiceContext.defaultClassLoader());
+    }
+
+    @Override
+    public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+        Object cached = singletons.get(serviceType);
+        if (cached == null) {
+            cached = create(serviceType);
+            if(cached!=null) {
+                singletons.put(serviceType, cached);
+            }
+        }
+        return serviceType.cast(cached);
+    }
+
+    @Override
+    public <T> T create(Class<T> serviceType) {
+        return create(serviceType, ServiceContext.defaultClassLoader());
+    }
+
+    @Override
+    public <T> T create(Class<T> serviceType, ClassLoader classLoader) {
+        @SuppressWarnings("unchecked")
+		Class<? extends T> implType = factoryTypes.get(serviceType);
+        if(implType==null) {
+            Collection<T> services = getServices(serviceType, classLoader);
+            if (services.isEmpty()) {
+                return null;
+            } else {
+                return getServiceWithHighestPriority(services, serviceType);
+            }
+        }
+        try {
+            return implType.newInstance();
+        } catch (Exception e) {
+            LOG.log(Level.SEVERE, "Failed to create instance of " + implType.getName(), e);
+            return  null;
+        }
+    }
+
+    /**
+            * Loads and registers services.
+            *
+            * @param <T>         the concrete type.
+     * @param serviceType The service type.
+            * @return the items found, never {@code null}.
+            */
+    @Override
+    public <T> List<T> getServices(final Class<T> serviceType) {
+        return  getServices(serviceType, ServiceContext.defaultClassLoader());
+    }
+
+    /**
+     * Loads and registers services.
+     *
+     * @param <T>         the concrete type.
+     * @param serviceType The service type.
+     * @return the items found, never {@code null}.
+     */
+    @Override
+    public <T> List<T> getServices(final Class<T> serviceType, ClassLoader classLoader) {
+        @SuppressWarnings("unchecked")
+		List<T> found = (List<T>) servicesLoaded.get(serviceType);
+        if (found != null) {
+            return found;
+        }
+        List<T> services = new ArrayList<>();
+        try {
+            for (T t : ServiceLoader.load(serviceType, classLoader)) {
+                services.add(t);
+            }
+            if(services.isEmpty()) {
+                for (T t : ServiceLoader.load(serviceType, serviceType.getClassLoader())) {
+                    services.add(t);
+                }
+            }
+            Collections.sort(services, org.apache.tamaya.base.PriorityServiceComparator.getInstance());
+            services = Collections.unmodifiableList(services);
+        } catch (ServiceConfigurationError e) {
+            LOG.log(Level.WARNING,
+                    "Error loading services current type " + serviceType, e);
+            if(services==null){
+                services = Collections.emptyList();
+            }
+        }
+        @SuppressWarnings("unchecked")
+		final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services));
+        return previousServices != null ? previousServices : services;
+    }
+
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such
+     * annotation is present, a default priority of {@code 1} is returned.
+     * @param o the instance, not {@code null}.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o){
+        int prio = 1; //X TODO discuss default priority
+        Priority priority = o.getClass().getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
+
+    /**
+     * @param services to scan
+     * @param <T>      type of the service
+     *
+     * @return the service with the highest {@link Priority#value()}
+     *
+     * @throws IllegalStateException if there are multiple service implementations with the maximum priority
+     */
+    private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) {
+        T highestService = null;
+        // we do not need the priority stuff if the list contains only one element
+        if (services.size() == 1) {
+            highestService = services.iterator().next();
+            this.factoryTypes.put(serviceType, highestService.getClass());
+            return highestService;
+        }
+
+        Integer highestPriority = null;
+        int highestPriorityServiceCount = 0;
+
+        for (T service : services) {
+            int prio = getPriority(service);
+            if (highestPriority == null || highestPriority < prio) {
+                highestService = service;
+                highestPriorityServiceCount = 1;
+                highestPriority = prio;
+            } else if (highestPriority == prio) {
+                highestPriorityServiceCount++;
+            }
+        }
+
+        if (highestPriorityServiceCount > 1) {
+            throw new IllegalStateException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}",
+                                                           highestPriorityServiceCount,
+                                                           serviceType.getName(),
+                                                           highestPriority,
+                                                           services));
+        }
+        this.factoryTypes.put(serviceType, highestService.getClass());
+        return highestService;
+    }
+
+    @Override
+    public int ordinal() {
+        return 1;
+    }
+
+    @Override
+    public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException {
+        if(cl==null){
+            cl = Thread.currentThread().getContextClassLoader();
+        }
+        if(cl==null){
+            cl = getClass().getClassLoader();
+        }
+        return cl.getResources(resource);
+    }
+
+    @Override
+    public URL getResource(String resource, ClassLoader cl) {
+        if(cl==null){
+            cl = Thread.currentThread().getContextClassLoader();
+        }
+        if(cl==null){
+            cl = getClass().getClassLoader();
+        }
+        return cl.getResource(resource);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/PriorityServiceComparator.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/PriorityServiceComparator.java b/code/base/src/main/java/org/apache/tamaya/base/PriorityServiceComparator.java
new file mode 100644
index 0000000..37f5095
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/PriorityServiceComparator.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.base;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Comparator implementation for odering services loaded based on their increasing priority values.
+ */
+public class PriorityServiceComparator implements Comparator<Object>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final PriorityServiceComparator INSTANCE = new PriorityServiceComparator();
+
+    /** Singleton constructor. */
+    private PriorityServiceComparator(){}
+
+    /**
+     * Get the shared instance of the comparator.
+     * @return the shared instance, never null.
+     */
+    public static PriorityServiceComparator getInstance(){
+        return INSTANCE;
+    }
+
+    @Override
+    public int compare(Object o1, Object o2) {
+        int prio = getPriority(o1) - getPriority(o2);
+        if (prio < 0) {
+            return 1;
+        } else if (prio > 0) {
+            return -1;
+        } else {
+            return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+        }
+    }
+
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such
+     * annotation is present, a default priority {@code 1} is returned.
+     *
+     * @param o the instance, not {@code null}.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o) {
+        return getPriority(o.getClass());
+    }
+
+    /**
+     * Checks the given type optionally annotated with a @Priority. If present the annotation's value is evaluated.
+     * If no such annotation is present, a default priority {@code 1} is returned.
+     *
+     * @param type the type, not {@code null}.
+     * @return a priority, by default 1.
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public static int getPriority(Class type) {
+        int prio = 1;
+		Priority priority = (Priority)type.getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/ReflectionUtil.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/ReflectionUtil.java b/code/base/src/main/java/org/apache/tamaya/base/ReflectionUtil.java
new file mode 100644
index 0000000..85d2dc3
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/ReflectionUtil.java
@@ -0,0 +1,42 @@
+/*
+ * 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.base;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+
+/**
+ * Small utility class used by other parts.
+ */
+public final class ReflectionUtil {
+
+    private ReflectionUtil(){}
+
+    public static ParameterizedType getParametrizedType(Class<?> clazz) {
+        Type[] genericTypes = clazz.getGenericInterfaces();
+        for (Type type : genericTypes) {
+            if (type instanceof ParameterizedType) {
+                return (ParameterizedType) type;
+            }
+
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/BaseConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/BaseConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/BaseConfigSource.java
new file mode 100644
index 0000000..12adfaa
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/BaseConfigSource.java
@@ -0,0 +1,170 @@
+/*
+ * 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.base.configsource;
+
+import javax.config.spi.ConfigSource;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Abstract {@link ConfigSource} that allows to set a default ordinal that will be used, if no
+ * ordinal is provided with the config.
+ */
+public abstract class BaseConfigSource implements ConfigSource{
+    /** default ordinal that will be used, if no ordinal is provided with the config. */
+    private int defaultOrdinal;
+    /** Used if the ordinal has been set explicitly. */
+    private volatile Integer ordinal;
+    /** The name of the property source. */
+    private String name;
+
+    /**
+     * Constructor.
+     * @param name the (unique) property source name, not {@code null}.
+     */
+    protected BaseConfigSource(String name){
+        this.name = Objects.requireNonNull(name);
+        this.defaultOrdinal = 0;
+    }
+
+    /**
+     * Constructor.
+     * @param defaultOrdinal default ordinal that will be used, if no ordinal is provided with the config.
+     */
+    protected BaseConfigSource(int defaultOrdinal){
+        this.name = getClass().getSimpleName();
+        this.defaultOrdinal = defaultOrdinal;
+    }
+
+    /**
+     * Constructor.
+     * @param name the (unique) property source name, not {@code null}.
+     * @param defaultOrdinal default ordinal that will be used, if no ordinal is provided with the config.
+     */
+    protected BaseConfigSource(String name, int defaultOrdinal){
+        this.name = Objects.requireNonNull(name);
+        this.defaultOrdinal = defaultOrdinal;
+    }
+
+
+    /**
+     * Constructor, using a default ordinal of 0.
+     */
+    protected BaseConfigSource(){
+        this(0);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the property source's (unique) name.
+     * @param name the name, not {@code null}.
+     */
+    public void setName(String name){
+        this.name = Objects.requireNonNull(name);
+    }
+
+    /**
+     * Allows to set the ordinal of this property source explcitly. This will override any evaluated
+     * ordinal, or default ordinal. To reset an explcit ordinal call {@code setOrdinal(null);}.
+     * @param ordinal the explicit ordinal, or {@code null}.
+     */
+    public void setOrdinal(Integer ordinal){
+        this.ordinal = ordinal;
+    }
+
+    /**
+     * Allows to set the ordinal of this property source explcitly. This will override any evaluated
+     * ordinal, or default ordinal. To reset an explcit ordinal call {@code setOrdinal(null);}.
+     * @param defaultOrdinal the default ordinal, or {@code null}.
+     */
+    public void setDefaultOrdinal(Integer defaultOrdinal){
+        this.defaultOrdinal = defaultOrdinal;
+    }
+
+    public int getOrdinal() {
+        Integer ordinal = this.ordinal;
+        if(ordinal!=null){
+            Logger.getLogger(getClass().getName()).finest(
+                    "Using explicit ordinal '"+ordinal+"' for property source: " + getName());
+            return ordinal;
+        }
+        String configuredOrdinal = getValue(CONFIG_ORDINAL);
+        if(configuredOrdinal!=null){
+            try {
+                return Integer.parseInt(configuredOrdinal);
+            } catch (Exception e) {
+                Logger.getLogger(getClass().getName()).log(Level.WARNING,
+                        "Configured ordinal is not an int number: " + configuredOrdinal, e);
+            }
+        }
+        return getDefaultOrdinal();
+    }
+
+    /**
+     * Returns the  default ordinal used, when no ordinal is set, or the ordinal was not parseable to an int value.
+     * @return the  default ordinal used, by default 0.
+     */
+    public int getDefaultOrdinal(){
+        return defaultOrdinal;
+    }
+
+    @Override
+    public String getValue(String key) {
+        Map<String,String> properties = getProperties();
+        String val = properties.get(key);
+        if(val==null){
+            return null;
+        }
+        return val;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BaseConfigSource that = (BaseConfigSource) o;
+
+        return name.equals(that.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "{" +
+                toStringValues() +
+                '}';
+    }
+
+    protected String toStringValues() {
+        return  "  defaultOrdinal=" + defaultOrdinal + '\n' +
+                "  ordinal=" + ordinal  + '\n' +
+                "  name='" + name + '\''  + '\n';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/BuildableConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/BuildableConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/BuildableConfigSource.java
new file mode 100644
index 0000000..b0e859b
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/BuildableConfigSource.java
@@ -0,0 +1,208 @@
+/*
+ * 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.base.configsource;
+
+import javax.config.spi.ConfigSource;
+import java.util.*;
+
+/**
+ * A Buildable property source.
+ */
+public class BuildableConfigSource implements ConfigSource{
+
+    private int ordinal;
+    private String name = "PropertySource-"+UUID.randomUUID().toString();
+    private Map<String,String> properties = new HashMap<>();
+
+    @Override
+    public int getOrdinal() {
+        return ordinal;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getValue(String key) {
+        return properties.get(key);
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return Collections.unmodifiableMap(properties);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BuildableConfigSource that = (BuildableConfigSource) o;
+
+        return name.equals(that.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "BuildablePropertySource{" +
+                "ordinal=" + ordinal +
+                ", name='" + name + '\'' +
+                ", properties=" + properties +
+                '}';
+    }
+
+    /**
+     * Builder builder.
+     *
+     * @return the builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+
+    /**
+     * The type Builder.
+     */
+    public static final class Builder {
+        private int ordinal;
+        private String source;
+        private String name = "PropertySource-"+ UUID.randomUUID().toString();
+        private Map<String,String> properties = new HashMap<>();
+
+        private Builder() {
+        }
+
+        /**
+         * With ordinal builder.
+         *
+         * @param ordinal the ordinal
+         * @return the builder
+         */
+        public Builder withOrdinal(int ordinal) {
+            this.ordinal = ordinal;
+            return this;
+        }
+
+        /**
+         * With source builder.
+         *
+         * @param source the source
+         * @return the builder
+         */
+        public Builder withSource(String source) {
+            this.source = Objects.requireNonNull(source);
+            return this;
+        }
+
+        /**
+         * With name builder.
+         *
+         * @param name the name
+         * @return the builder
+         */
+        public Builder withName(String name) {
+            this.name = Objects.requireNonNull(name);
+            return this;
+        }
+
+        /**
+         * With simple property builder.
+         *
+         * @param key   the key
+         * @param value the value
+         * @return the builder
+         */
+        public Builder withProperty(String key, String value) {
+            return withProperty(key, value, this.source);
+        }
+
+        /**
+         * With simple property builder.
+         *
+         * @param key    the key
+         * @param value  the value
+         * @param source the source
+         * @return the builder
+         */
+        public Builder withProperty(String key, String value, String source) {
+            this.properties.put(key, value);
+            if(source!=null) {
+                this.properties.put(key+"[meta]", "source="+source);
+            }
+            return this;
+        }
+
+        /**
+         * With properties builder.
+         *
+         * @param properties the properties
+         * @param source     the source
+         * @return the builder
+         */
+        public Builder withProperty(Map<String, String> properties, String source) {
+            properties.forEach((k,v) -> {
+                withProperty(k, v, source);
+            });
+            return this;
+        }
+
+        /**
+         * With simple properties builder.
+         *
+         * @param properties the properties
+         * @return the builder
+         */
+        public Builder withProperties(Map<String, String> properties) {
+            properties.forEach((k,v) -> {
+                withProperty(k, v);
+            });
+            return this;
+        }
+
+        /**
+         * But builder.
+         *
+         * @return the builder
+         */
+        public Builder but() {
+            return builder().withOrdinal(ordinal).withName(name).withProperties(properties);
+        }
+
+        /**
+         * Build buildable property source.
+         *
+         * @return the buildable property source
+         */
+        public BuildableConfigSource build() {
+            BuildableConfigSource buildableConfigSource = new BuildableConfigSource();
+            buildableConfigSource.name = this.name;
+            buildableConfigSource.properties = this.properties;
+            buildableConfigSource.ordinal = this.ordinal;
+            return buildableConfigSource;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/BuildableConfigSourceProvider.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/BuildableConfigSourceProvider.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/BuildableConfigSourceProvider.java
new file mode 100644
index 0000000..d670576
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/BuildableConfigSourceProvider.java
@@ -0,0 +1,113 @@
+/*
+ * 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.base.configsource;
+
+import javax.config.spi.ConfigSource;
+import javax.config.spi.ConfigSourceProvider;
+import java.util.*;
+
+/**
+ * A Buildable property source.
+ */
+public class BuildableConfigSourceProvider implements ConfigSourceProvider{
+
+    private List<ConfigSource> sources = new ArrayList<>();
+
+    @Override
+    public Collection<ConfigSource> getConfigSources(ClassLoader cl) {
+        return Collections.unmodifiableCollection(sources);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BuildableConfigSourceProvider that = (BuildableConfigSourceProvider) o;
+
+        return sources.equals(that.sources);
+    }
+
+    @Override
+    public int hashCode() {
+        return sources.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "BuildablePropertySourceProvider{" +
+                "sources=" + sources +
+                '}';
+    }
+
+    /**
+     * Builder builder.
+     *
+     * @return the builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+
+
+
+    /**
+     * The type Builder.
+     */
+    public static final class Builder {
+        private List<ConfigSource> sources = new ArrayList<>();
+
+        private Builder() {
+        }
+
+        /**
+         * With propertySources.
+         *
+         * @param propertySources the propertySources
+         * @return the builder
+         */
+        public Builder withPropertySourcs(ConfigSource... propertySources) {
+            this.sources.addAll(Arrays.asList(propertySources));
+            return this;
+        }
+
+        /**
+         * With property sources builder.
+         *
+         * @param sources the property sources
+         * @return the builder
+         */
+        public Builder withPropertySourcs(Collection<ConfigSource> sources) {
+            this.sources.addAll(sources);
+            return this;
+        }
+
+        /**
+         * Build buildable property source.
+         *
+         * @return the buildable property source
+         */
+        public BuildableConfigSourceProvider build() {
+            BuildableConfigSourceProvider buildablePropertySource = new BuildableConfigSourceProvider();
+            buildablePropertySource.sources.addAll(this.sources);
+            return buildablePropertySource;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/CLIConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/CLIConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/CLIConfigSource.java
new file mode 100644
index 0000000..4e57229
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/CLIConfigSource.java
@@ -0,0 +1,130 @@
+/*
+ * 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.base.configsource;
+
+import java.util.*;
+
+/**
+ * PropertySource that allows to add the programs main arguments as configuration entries. Unix syntax using '--' and
+ * '-' params is supported.
+ */
+public class CLIConfigSource extends BaseConfigSource {
+
+    /** The original main arguments. */
+    private static String[] args = new String[0];
+
+    /** The map of parsed main arguments. */
+    private static Map<String,String> mainArgs;
+
+    /** Initializes the initial state. */
+    static{
+        initMainArgs(args);
+    }
+
+    /**
+     * Creates a new instance.
+     */
+    public CLIConfigSource(){
+        this((String[])null);
+    }
+
+    /**
+     * Creates a new instance, allows optionally to pass the main arguments.
+     * @param args the args, or null.
+     */
+    public CLIConfigSource(String... args){
+        super("CLI");
+        if(args!=null){
+            initMainArgs(args);
+        }
+    }
+
+    /**
+     * Creates a new instance, allows optionally to pass the main arguments.
+     * @param args the args, or null.
+     * @param ordinal the ordinal to be applied.
+     */
+    public CLIConfigSource(int ordinal, String... args){
+        if(args!=null){
+            initMainArgs(args);
+        }
+        setOrdinal(ordinal);
+    }
+
+
+
+    /**
+     * Configure the main arguments, hereby parsing and mapping the main arguments into
+     * configuration propertiesi as key-value pairs.
+     * @param args the main arguments, not null.
+     */
+    public static void initMainArgs(String... args){
+        CLIConfigSource.args = Objects.requireNonNull(args);
+        // TODO is there a way to figure out the args?
+        String argsProp = System.getProperty("main.args");
+        if(argsProp!=null){
+            CLIConfigSource.args = argsProp.split("\\s");
+        }
+        Map<String,String> result;
+        if(CLIConfigSource.args==null){
+            result = Collections.emptyMap();
+        }else{
+            result = new HashMap<>();
+            String prefix = System.getProperty("main.args.prefix");
+            if(prefix==null){
+                prefix="";
+            }
+            String key = null;
+            for(String arg: CLIConfigSource.args){
+                if(arg.startsWith("--")){
+                    arg = arg.substring(2);
+                    int index = arg.indexOf("=");
+                    if(index>0){
+                        key = arg.substring(0,index).trim();
+                        result.put(prefix+key, arg.substring(index+1).trim());
+                        key = null;
+                    }else{
+                        result.put(prefix+arg, arg);
+                    }
+                }else if(arg.startsWith("-")){
+                    key = arg.substring(1);
+                }else{
+                    if(key!=null){
+                        result.put(prefix+key, arg);
+                        key = null;
+                    }else{
+                        result.put(prefix+arg, arg);
+                    }
+                }
+            }
+        }
+        CLIConfigSource.mainArgs = Collections.unmodifiableMap(result);
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return Collections.unmodifiableMap(mainArgs);
+    }
+
+    @Override
+    protected String toStringValues() {
+        return  super.toStringValues() +
+                "  args=" + Arrays.toString(args) + '\n';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/ConfigSourceComparator.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/ConfigSourceComparator.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/ConfigSourceComparator.java
new file mode 100644
index 0000000..c1015ea
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/ConfigSourceComparator.java
@@ -0,0 +1,117 @@
+/*
+ * 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.base.configsource;
+
+import javax.config.spi.ConfigSource;
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.logging.Logger;
+
+/**
+ * Comparator for ordering of PropertySources based on their ordinal method and class name.
+ */
+public class ConfigSourceComparator implements Comparator<ConfigSource>, Serializable {
+    /** serial version UID. */
+    private static final long serialVersionUID = 1L;
+
+    private static final Logger LOG = Logger.getLogger(ConfigSourceComparator.class.getName());
+
+    private static final ConfigSourceComparator INSTANCE = new ConfigSourceComparator();
+
+    private String alternativeOrdinalKey;
+
+    /** Singleton constructor. */
+    private ConfigSourceComparator(){}
+
+    /**
+     * Get the shared instance of the comparator.
+     * @return the shared instance, never null.
+     */
+    public static ConfigSourceComparator getInstance(){
+        return INSTANCE;
+    }
+
+
+    /**
+     * Order property source reversely, the most important comes first.
+     *
+     * @param source1 the first PropertySource
+     * @param source2 the second PropertySource
+     * @return the comparison result.
+     */
+    private int compareConfigSources(ConfigSource source1, ConfigSource source2) {
+        if (getOrdinal(source1) < getOrdinal(source2)) {
+            return -1;
+        } else if (getOrdinal(source1) > getOrdinal(source2)) {
+            return 1;
+        } else {
+            return source1.getClass().getName().compareTo(source2.getClass().getName());
+        }
+    }
+
+    /**
+     * Evaluates an ordinal value from a {@link ConfigSource}, Hereby the ordinal of type {@code int}
+     * is evaluated as follows:
+     * <ol>
+     *     <li>It evaluates the {@code String} value for {@link ConfigSource#CONFIG_ORDINAL} and tries
+     *     to convert it to an {@code int} value, using {@link Integer#parseInt(String)}.</li>
+     *     <li>It tries to find and evaluate a method {@code int getOrdinal()}.</li>
+     *     <li>It tries to find and evaluate a static field {@code int ORDINAL}.</li>
+     *     <li>It tries to find and evaluate a class level {@link javax.annotation.Priority} annotation.</li>
+     *     <li>It uses the default priority ({@code 0}.</li>
+     * </ol>
+     * @param propertySource the property source, not {@code null}.
+     * @return the ordinal value to compare the property source.
+     */
+    public static int getOrdinal(ConfigSource propertySource) {
+        return getOrdinal(propertySource, null);
+    }
+
+    public static int getOrdinal(ConfigSource propertySource, String alternativeOrdinalKey) {
+        if(alternativeOrdinalKey!=null) {
+            String ordinalValue = propertySource.getValue(alternativeOrdinalKey);
+            if (ordinalValue != null) {
+                try {
+                    return Integer.parseInt(ordinalValue.trim());
+                } catch (Exception e) {
+                    LOG.finest("Failed to parse ordinal from " + alternativeOrdinalKey +
+                            " in " + propertySource.getName() + ": " + ordinalValue);
+                }
+            }
+        }
+        return propertySource.getOrdinal();
+    }
+
+    /**
+     * Overrides/adds the key to evaluate/override a property sources ordinal.
+     * @param ordinalKey sets the alternative ordinal key, if null default
+     *                   behaviour will be active.
+     * @return the instance for chaining.
+     */
+    public ConfigSourceComparator setOrdinalKey(String ordinalKey) {
+        this.alternativeOrdinalKey = ordinalKey;
+        return this;
+    }
+
+    @Override
+    public int compare(ConfigSource source1, ConfigSource source2) {
+        return compareConfigSources(source1, source2);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/ConfigSourceManager.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/ConfigSourceManager.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/ConfigSourceManager.java
new file mode 100644
index 0000000..7a09bf5
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/ConfigSourceManager.java
@@ -0,0 +1,375 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.base.FormatUtils;
+import org.apache.tamaya.spi.*;
+
+import javax.config.Config;
+import javax.config.spi.ConfigSource;
+import javax.config.spi.ConfigSourceProvider;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link Config} to evaluate the
+ * chain of {@link javax.config.spi.ConfigSource} and {@link Filter}
+ * instance to evaluate the current Configuration.
+ */
+public class ConfigSourceManager {
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(ConfigSourceManager.class.getName());
+    /**
+     * The current list of loaded {@link ConfigSource} instances.
+     */
+    private final List<ConfigSource> configSources = new ArrayList<>();
+
+    /**
+     * The overriding policy used when combining PropertySources registered to evalute the final configuration
+     * values.
+     */
+    ConfigValueCombinationPolicy configValueCombinationPolicy;
+
+    private ClassLoader classloader = ServiceContext.defaultClassLoader();
+
+    /**
+     * Create a new filter manager.
+     */
+    public ConfigSourceManager(){
+        configValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(
+                ConfigValueCombinationPolicy.class);
+        if(configValueCombinationPolicy == null){
+            configValueCombinationPolicy = ConfigValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+        }
+        LOG.info("Using PropertyValueCombinationPolicy: " + configValueCombinationPolicy);
+    }
+
+    /**
+     * Create a new filter manager.
+     * @param configSources the config sources to be used, not null.
+     */
+    public ConfigSourceManager(List<ConfigSource> configSources){
+        this.configSources.addAll(configSources);
+        LOG.info("Registered " + configSources.size() + " config sources: " + configSources);
+    }
+
+    /**
+     * Get the classloader used for instance creation.
+     * @return the classloader, never null.
+     */
+    public ClassLoader getClassloader(){
+        return classloader;
+    }
+
+    /**
+     * Sets the classloader to use for loading of instances.
+     * @param ClassLoader the classloader, not null.
+     * @return this instance for chaining.
+     */
+    public ConfigSourceManager setClassloader(ClassLoader ClassLoader){
+        this.classloader = Objects.requireNonNull(classloader);
+        return this;
+    }
+
+    /**
+     * The current unmodifiable list of loaded {@link ConfigSource} instances.
+     */
+    public List<ConfigSource> getSources(){
+        return Collections.unmodifiableList(configSources);
+    }
+
+    /**
+     * Registers a new ConfigSource instance.
+     *
+     * @param configSources  the config source, not {@code null}.
+     */
+    public ConfigSourceManager addSources(Collection<ConfigSource> configSources) {
+        Objects.requireNonNull(configSources);
+        for(ConfigSource configSource:configSources) {
+            if (!this.configSources.contains(configSource)) {
+                this.configSources.add(configSource);
+            }
+        }
+        return this;
+    }
+
+    public ConfigSourceManager addDiscoveredSources() {
+        List<ConfigSource> propertySources = new ArrayList<>();
+        addCoreSources(propertySources);
+        for(ConfigSource ps: ServiceContextManager.getServiceContext().getServices(ConfigSource.class)) {
+            if(!propertySources.contains(ps)){
+                propertySources.add(ps);
+            }
+        }
+        for(ConfigSourceProvider provider:
+                ServiceContextManager.getServiceContext().getServices(ConfigSourceProvider.class)){
+            provider.getConfigSources(classloader).forEach(propertySources::add);
+        }
+        Collections.sort(propertySources, ConfigSourceComparator.getInstance());
+        return addSources(propertySources);
+    }
+
+    protected ConfigSourceManager addCoreSources(List<ConfigSource> propertySources) {
+        for(ConfigSource ps: new ConfigSource[]{
+                new EnvironmentConfigSource(),
+                new JavaConfigurationConfigSource(),
+                new CLIConfigSource(),
+                new SystemConfigSource()
+        }){
+            if(!propertySources.contains(ps)){
+                propertySources.add(ps);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Registers a new ConfigSource instance.
+     *
+     * @param configSources  the config source, not {@code null}.
+     */
+    public ConfigSourceManager addSources(ConfigSource... configSources) {
+        return addSources(Arrays.asList(configSources));
+    }
+
+
+    /**
+     * Access a {@link ConfigSource} using its (unique) name.
+     * @param name the propoerty source's name, not {@code null}.
+     * @return the propoerty source found, or {@code null}.
+     */
+    public ConfigSource getSource(String name) {
+        for(ConfigSource ps: getSources()){
+            if(name.equals(ps.getName())){
+                return ps;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes the given config sources, if existing. The existing order of config
+     * sources is preserved.
+     *
+     * @param configSources the config sources to remove, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public final ConfigSourceManager removeSources(ConfigSource... configSources) {
+        return removeSources(Arrays.asList(configSources));
+    }
+    /**
+     * Removes the given config sources, if existing. The existing order of config
+     * sources is preserved.
+     *
+     * @param configSources the config sources to remove, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public ConfigSourceManager removeSources(Collection<ConfigSource> configSources) {
+        this.configSources.removeAll(configSources);
+        return this;
+    }
+
+    /**
+     * Increases the priority of the given property source, by moving it towards the end
+     * of the chain of property sources. If the property source given is already at the end
+     * this method has no effect. This operation does not change any ordinal values.
+     *
+     * @param configSource the config source to be incresed regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    public ConfigSourceManager increasePriority(ConfigSource configSource){
+        int index = configSources.indexOf(configSource);
+        if(index<0){
+            throw new IllegalArgumentException("No such ConfigSource: " + configSource);
+        }
+        if(index<(configSources.size()-1)){
+            configSources.remove(configSource);
+            configSources.add(index+1, configSource);
+        }
+        return this;
+    }
+
+    /**
+     * Decreases the priority of the given property source, by moving it towards the start
+     * of the chain of property sources. If the property source given is already the first
+     * this method has no effect. This operation does not change any ordinal values.
+     *
+     * @param configSource the config source to be decresed regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    public ConfigSourceManager decreasePriority(ConfigSource configSource){
+        int index = configSources.indexOf(configSource);
+        if(index<0){
+            throw new IllegalArgumentException("No such ConfigSource: " + configSource);
+        }
+        if(index>0){
+            configSources.remove(configSource);
+            configSources.add(index-1, configSource);
+        }
+        return this;
+    }
+
+    /**
+     * Increases the priority of the given property source to be maximal, by moving it to
+     * the tail of the of property source chain. If the property source given is
+     * already the last item this method has no effect. This operation does not change
+     * any ordinal values.
+     *
+     * @param configSource the config source to be maximized regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    public ConfigSourceManager highestPriority(ConfigSource configSource){
+        int index = configSources.indexOf(configSource);
+        if(index<0){
+            throw new IllegalArgumentException("No such ConfigSource: " + configSource);
+        }
+        if(index<(configSources.size()-1)){
+            configSources.remove(configSource);
+            configSources.add(configSource);
+        }
+        return this;
+    }
+
+    /**
+     * Decreases the priority of the given property source to be minimal, by moving it to
+     * the start of the chain of property source chain. If the property source given is
+     * already the first item this method has no effect. This operation does not change
+     * any ordinal values.
+     *
+     * @param configSource the config source to be minimized regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    public ConfigSourceManager lowestPriority(ConfigSource configSource){
+        int index = configSources.indexOf(configSource);
+        if(index<0){
+            throw new IllegalArgumentException("No such PropertySource: " + configSource);
+        }
+        if(index>0){
+            configSources.remove(configSource);
+            configSources.add(0, configSource);
+        }
+        return this;
+    }
+
+    public ConfigSourceManager sortSources(Comparator<ConfigSource> comparator) {
+        Collections.sort(configSources, comparator);
+        return this;
+    }
+
+    /**
+     * Access the {@link ConfigValueCombinationPolicy} used to evaluate the final
+     * property values.
+     * @return the {@link ConfigValueCombinationPolicy} used, never null.
+     */
+    public ConfigValueCombinationPolicy getConfigValueCombinationPolicy(){
+        return configValueCombinationPolicy;
+    }
+
+    /**
+     * Removes all contained items.
+     * @return this instance for chaining.
+     */
+    public ConfigSourceManager clear() {
+        this.configSources.clear();
+        this.configValueCombinationPolicy = ConfigValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY;
+        return this;
+    }
+
+    /**
+     * Evaluates the raw value using the context's PropertyValueCombinationPolicy.
+     * @param key the key, not null.
+     * @return the value, before filtering is applied.
+     */
+    public ConfigValue evaluteRawValue(String key) {
+        List<ConfigSource> configSources = getSources();
+        ConfigValue unfilteredValue = null;
+        ConfigValueCombinationPolicy combinationPolicy = getConfigValueCombinationPolicy();
+        for (ConfigSource propertySource : configSources) {
+            unfilteredValue = combinationPolicy.collect(unfilteredValue, key, propertySource);
+        }
+        return unfilteredValue;
+    }
+
+    public Map<String, ConfigValue> evaluateRawValues() {
+        List<ConfigSource> configSources = getSources();
+        ConfigValueCombinationPolicy combinationPolicy = getConfigValueCombinationPolicy();
+        Map<String, ConfigValue> result = new HashMap<>();
+        for (ConfigSource propertySource : configSources) {
+            for (Map.Entry<String,String> propEntry: propertySource.getProperties().entrySet()) {
+                ConfigValue unfilteredValue = result.get(propEntry.getKey());
+                unfilteredValue = combinationPolicy.
+                        collect(unfilteredValue, propEntry.getKey(), propertySource);
+                if(unfilteredValue!=null){
+                    result.put(unfilteredValue.getKey(), unfilteredValue);
+                }
+            }
+        }
+        return result;
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder("Config Sources\n");
+             b.append("--------------\n");
+        if(configSources.isEmpty()){
+            b.append("  No config sources loaded.\n\n");
+        }else {
+            b.append("  CLASS                         NAME                                                                  ORDINAL SCANNABLE SIZE    STATE     ERROR\n\n");
+            for (ConfigSource ps : configSources) {
+                b.append("  ");
+                FormatUtils.appendFormatted(b, ps.getClass().getSimpleName(), 30);
+                FormatUtils.appendFormatted(b, ps.getName(), 70);
+                FormatUtils.appendFormatted(b, String.valueOf(ConfigSourceComparator.getOrdinal(ps)), 8);
+                String state = ps.getValue("_state");
+                if(state==null){
+                    FormatUtils.appendFormatted(b, "OK", 10);
+                }else {
+                    FormatUtils.appendFormatted(b, state, 10);
+                    if("ERROR".equals(state)){
+                        String val = ps.getValue("_exception");
+                        if(val!=null) {
+                            FormatUtils.appendFormatted(b, val, 30);
+                        }
+                    }
+                }
+                b.append('\n');
+            }
+            b.append("\n");
+        }
+        b.append("\n");
+        b.append("  ConfigValueCombinationPolicy: " + configValueCombinationPolicy.getClass().getName()).append('\n');
+        return b.toString();
+    }
+
+    public void setConfigValueCombinationPolicy(ConfigValueCombinationPolicy configValueCombinationPolicy) {
+        this.configValueCombinationPolicy = Objects.requireNonNull(configValueCombinationPolicy);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/EnvironmentConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/EnvironmentConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/EnvironmentConfigSource.java
new file mode 100644
index 0000000..2e45bb0
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/EnvironmentConfigSource.java
@@ -0,0 +1,281 @@
+/*
+ * 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.base.configsource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>{@link javax.config.spi.ConfigSource} to access environment variables via Tamaya
+ * which are set via {@code export VARIABLE=value} on UNIX systems or
+ * {@code set VARIABLE=value} on Windows systems.</p>
+ *
+ * <p>Using the {@linkplain EnvironmentConfigSource} without any
+ * additional configuration gives access to all existing environment
+ * variables available to the Java process Tamaya is running in.</p>
+ *
+ * <h1>Simple usage example</h1>
+ *
+ * <pre>
+ * $ export OPS_MODE=production
+ * $ export COLOR=false
+ * $ java -jar application.jar
+ * </pre>
+ *
+ * <p>To access {@code OPS_MODE} and {@code COLOR} with the following code
+ * fragment could be used:</p>
+ *
+ * <pre>
+ * PropertySource ps = new EnvironmentPropertySource();
+ * PropertyValue opsMode = ps.get("OPS_MODE");
+ * PropertyValue color = ps.get("COLOR");
+ * </pre>
+ *
+ * <h1>Application specific environmet variables with prefix</h1>
+ *
+ * <p>Given the case where to instances of the same application are running on
+ * a single machine but need different values for the environment variable
+ * {@code CUSTOMER}. The {@linkplain EnvironmentConfigSource} allows you
+ * to prefix the environment variable with an application specific prefix
+ * and to access it by the non-prefixed variable name.</p>
+ *
+ * <pre>
+ * $ export CUSTOMER=none
+ * $ export a81.CUSTOMER=moon
+ * $ export b78.CUSTOMER=luna
+ * </pre>
+ *
+ * <p>Given an environment with these tree variables the application running
+ * for the customer called Moon could be started with the following command:</p>
+ *
+ * <pre>
+ * $ java -Dtamaya.envprops.prefix=a81 -jar application.jar
+ * </pre>
+ *
+ * <p>The application specific value can now be accessed from the code of the
+ * application like this:</p>
+ *
+ * <pre>
+ * PropertySource ps = new EnvironmentPropertySource();
+ * PropertyValue pv = ps.get("CUSTOMER");
+ * System.out.println(pv.getValue());
+ * </pre>
+ *
+ * <p>The output of application would be {@code moon}.</p>
+ *
+ * <h1>Disabling the access to environment variables</h1>
+ *
+ * <p>The access to environment variables could be simply
+ * disabled by the setting the systemproperty {@code tamaya.envprops.disable}
+ * or {@code tamaya.defaults.disable} to {@code true}.</p>
+ */
+public class EnvironmentConfigSource extends BaseConfigSource {
+    private static final String TAMAYA_ENVPROPS_PREFIX = "tamaya.envprops.prefix";
+    private static final String TAMAYA_ENVPROPS_DISABLE = "tamaya.envprops.disable";
+    private static final String TAMAYA_DEFAULT_DISABLE = "tamaya.defaults.disable";
+
+    /**
+     * Default ordinal for {@link EnvironmentConfigSource}
+     */
+    public static final int DEFAULT_ORDINAL = 300;
+
+    /**
+     * Prefix that allows environment properties to virtually be mapped on specified sub section.
+     */
+    private String prefix;
+
+    /**
+     * If true, this property source does not return any properties. This is useful since this
+     * property source is applied by default, but can be switched off by setting the
+     * {@code tamaya.envprops.disable} system/environment property to {@code true}.
+     */
+    private boolean disabled = false;
+
+    private SystemPropertiesProvider propertiesProvider = new SystemPropertiesProvider();
+
+    /**
+     * Creates a new instance. Also initializes the {@code prefix} and {@code disabled} properties
+     * from the system-/ environment properties:
+     * <pre>
+     *     tamaya.envprops.prefix
+     *     tamaya.envprops.disable
+     * </pre>
+     */
+    public EnvironmentConfigSource(){
+        initFromSystemProperties();
+    }
+
+    /**
+     * Initializes the {@code prefix} and {@code disabled} properties from the system-/
+     * environment properties:
+     * <pre>
+     *     tamaya.envprops.prefix
+     *     tamaya.envprops.disable
+     * </pre>
+     */
+    private void initFromSystemProperties() {
+        String value = System.getProperty("tamaya.envprops.prefix");
+        if(value==null){
+            prefix = System.getenv("tamaya.envprops.prefix");
+        }
+        value = System.getProperty("tamaya.envprops.disable");
+        if(value==null){
+            value = System.getenv("tamaya.envprops.disable");
+        }
+        if(value==null){
+            value = System.getProperty("tamaya.defaults.disable");
+        }
+        if(value==null){
+            value = System.getenv("tamaya.defaults.disable");
+        }
+        if(value!=null && !value.isEmpty()) {
+            this.disabled = Boolean.parseBoolean(value);
+        }
+    }
+
+    /**
+     * Creates a new instance using a fixed ordinal value.
+     * @param ordinal the ordinal number.
+     */
+    public EnvironmentConfigSource(int ordinal){
+        this(null, ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     * @param ordinal the ordinal to be used.
+     */
+    public EnvironmentConfigSource(String prefix, int ordinal){
+        super("environment-properties");
+        this.prefix = prefix;
+        setOrdinal(ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     */
+    public EnvironmentConfigSource(String prefix){
+        this.prefix = prefix;
+    }
+
+    @Override
+    public int getDefaultOrdinal() {
+        return DEFAULT_ORDINAL;
+    }
+
+    @Override
+    public String getName() {
+        if (isDisabled()) {
+            return "environment-properties(disabled)";
+        }
+        return "environment-properties";
+    }
+
+    @Override
+    public String getValue(String key) {
+        if (isDisabled()) {
+            return null;
+        }
+        String effectiveKey = hasPrefix() ? getPrefix() + "." + key
+                                          : key;
+        return getPropertiesProvider().getenv(effectiveKey);
+    }
+
+    private boolean hasPrefix() {
+        return null != prefix;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        if(disabled){
+            return Collections.emptyMap();
+        }
+        String prefix = this.prefix;
+        if(prefix==null) {
+            Map<String, String> entries = new HashMap<>(System.getenv().size());
+            for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
+                entries.put(entry.getKey(), entry.getValue());
+            }
+            return entries;
+        }else{
+            Map<String, String> entries = new HashMap<>(System.getenv().size());
+            for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
+                entries.put(prefix + entry.getKey(), entry.getValue());
+            }
+            return entries;
+        }
+    }
+
+
+    @Override
+    protected String toStringValues() {
+        return  super.toStringValues() +
+                "  prefix=" + prefix + '\n' +
+                "  disabled=" + disabled + '\n';
+    }
+
+    void setPropertiesProvider(SystemPropertiesProvider spp) {
+        propertiesProvider = spp;
+        initFromSystemProperties();
+    }
+
+    SystemPropertiesProvider getPropertiesProvider() {
+        return propertiesProvider;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public boolean isDisabled() {
+        return disabled;
+    }
+
+    /**
+     * <p>Provides access to the system properties used to configure
+     * {@linkplain EnvironmentConfigSource}.</p>
+     *
+     * <p>This implementation delegates all property lookups
+     * to {@linkplain System#getProperty(String)}.</p>
+     */
+    static class SystemPropertiesProvider {
+        String getEnvPropsPrefix() {
+            return System.getenv(TAMAYA_ENVPROPS_PREFIX);
+        }
+
+        String getEnvPropsDisable() {
+            return System.getenv(TAMAYA_ENVPROPS_DISABLE);
+        }
+
+        String getDefaultsDisable() {
+            return System.getenv(TAMAYA_DEFAULT_DISABLE);
+        }
+
+        String getenv(String name) {
+            return System.getenv(name);
+        }
+
+        Map<String, String> getenv() {
+            return System.getenv();
+        }
+    }
+}



[5/6] incubator-tamaya git commit: Added full JSR implementation.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/JavaConfigurationConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/JavaConfigurationConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/JavaConfigurationConfigSource.java
new file mode 100644
index 0000000..6fb3fc8
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/JavaConfigurationConfigSource.java
@@ -0,0 +1,131 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.config.spi.ConfigSource;
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+
+import static java.lang.String.format;
+import static java.lang.Thread.currentThread;
+
+/**
+ * Provider which reads all {@value DEFAULT_SIMPLE_PROPERTIES_FILE_NAME} and
+ * {@value DEFAULT_XML_PROPERTIES_FILE_NAME} files found in the
+ * classpath. By setting
+ * {@code tamaya.defaultprops.disable} or {@code tamaya.defaults.disable}
+ * as system or environment property this feature can be disabled.
+ */
+public class JavaConfigurationConfigSource extends BaseConfigSource {
+    /**
+     * Default location in the classpath, where Tamaya looks for simple line based configuration by default.
+     */
+    public static final String DEFAULT_SIMPLE_PROPERTIES_FILE_NAME="META-INF/javaconfig.properties";
+
+    /**
+     * Default location in the classpath, where Tamaya looks for XML based configuration by default.
+     */
+    public static final String DEFAULT_XML_PROPERTIES_FILE_NAME = "META-INF/javaconfig.xml";
+
+    private static final int DEFAULT_ORDINAL = 900;
+
+    private boolean enabled = evaluateEnabled();
+
+    public JavaConfigurationConfigSource(){
+        super("resource:META-INF/javaconfig.*", DEFAULT_ORDINAL);
+    }
+
+    private boolean evaluateEnabled() {
+        String value = System.getProperty("tamaya.defaultprops.disable");
+        if(value==null){
+            value = System.getenv("tamaya.defaultprops.disable");
+        }
+        if(value==null){
+            value = System.getProperty("tamaya.defaults.disable");
+        }
+        if(value==null){
+            value = System.getenv("tamaya.defaults.disable");
+        }
+        if(value==null){
+            return true;
+        }
+        return value.isEmpty() || !Boolean.parseBoolean(value);
+    }
+
+    private List<ConfigSource> getPropertySources() {
+        List<ConfigSource> propertySources = new ArrayList<>();
+        propertySources.addAll(loadPropertySourcesByName(DEFAULT_SIMPLE_PROPERTIES_FILE_NAME));
+        propertySources.addAll(loadPropertySourcesByName(DEFAULT_XML_PROPERTIES_FILE_NAME));
+        Collections.sort(propertySources, ConfigSourceComparator.getInstance());
+        return propertySources;
+    }
+
+    private Collection<? extends ConfigSource> loadPropertySourcesByName(String filename) {
+        List<ConfigSource> propertySources = new ArrayList<>();
+        Enumeration<URL> propertyLocations;
+        try {
+            propertyLocations = ServiceContextManager.getServiceContext()
+                    .getResources(filename, currentThread().getContextClassLoader());
+        } catch (IOException e) {
+            String msg = format("Error while searching for %s", filename);
+
+            throw new IllegalStateException(msg, e);
+        }
+
+        while (propertyLocations.hasMoreElements()) {
+            URL currentUrl = propertyLocations.nextElement();
+            SimpleConfigSource sps = new SimpleConfigSource(currentUrl);
+
+            propertySources.add(sps);
+        }
+
+        return propertySources;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled){
+        this.enabled = enabled;
+    }
+
+
+    @Override
+    public Map<String, String> getProperties() {
+        if (!isEnabled()) {
+            return Collections.emptyMap();
+        }
+        Map<String,String> result = new HashMap<>();
+        for(ConfigSource ps:getPropertySources()){
+            result.putAll(ps.getProperties());
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "JavaConfigPropertySource{" +
+                "enabled=" + enabled +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/MapConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/MapConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/MapConfigSource.java
new file mode 100644
index 0000000..2defa06
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/MapConfigSource.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.base.configsource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Simple PropertySource implementation that just takes a Map and an (optional) priority.
+ * Optionally the entries passed can be mapped to a different rootContext.
+ */
+public class MapConfigSource extends BaseConfigSource {
+
+    /**
+     * The current properties.
+     */
+    private final Map<String, String> props = new HashMap<>();
+
+    /**
+     * Creates a new instance, hereby using the default mechanism for evaluating the property source's
+     * priority.
+     *
+     * @param name unique name of this source.
+     * @param props the properties
+     */
+    public MapConfigSource(String name, Map<String, String> props) {
+        this(name, props, null);
+    }
+
+    /**
+     * Creates a new instance, hereby using the default mechanism for evaluating the property source's
+     * priority, but applying a custom mapping {@code prefix} to the entries provided.
+     *
+     * @param name        unique name of this source.
+     * @param props       the properties
+     * @param prefix      the prefix context mapping, or null (for no mapping).
+     */
+    public MapConfigSource(String name, Map<String, String> props, String prefix) {
+        super(name);
+        if (prefix == null) {
+            for (Map.Entry<String, String> en : props.entrySet()) {
+                this.props.put(en.getKey(), en.getValue());
+            }
+        } else {
+            for (Map.Entry<String, String> en : props.entrySet()) {
+                this.props.put(prefix + en.getKey(), en.getValue());
+            }
+        }
+    }
+
+    /**
+     * Creates a new instance, hereby using the default mechanism for evaluating the property source's
+     * priority, but applying a custom mapping {@code rootContext} to the entries provided.
+     *
+     * @param name unique name of this source.
+     * @param props       the properties
+     * @param prefix      the prefix context mapping, or null (for no mapping).
+     */
+    public MapConfigSource(String name, Properties props, String prefix) {
+        this(name, getMap(props), prefix);
+    }
+
+    /**
+     * Simple method to convert Properties into a Map instance.
+     * @param props the properties, not null.
+     * @return the corresponding Map instance.
+     */
+    public static Map<String, String> getMap(Properties props) {
+        Map<String, String> result = new HashMap<>();
+        for (Map.Entry en : props.entrySet()) {
+            result.put(en.getKey().toString(), en.getValue().toString());
+        }
+        return result;
+    }
+
+
+    @Override
+    public Map<String, String> getProperties() {
+        return Collections.unmodifiableMap(this.props);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/PropertiesResourceConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/PropertiesResourceConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/PropertiesResourceConfigSource.java
new file mode 100644
index 0000000..4e974df
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/PropertiesResourceConfigSource.java
@@ -0,0 +1,109 @@
+/*
+ * 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.base.configsource;
+
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Simple PropertySource, with a fixed ordinal that reads a .properties file from a given URL.
+ */
+public class PropertiesResourceConfigSource extends MapConfigSource {
+    /** The logger used. */
+    private static final Logger LOGGER = Logger.getLogger(PropertiesResourceConfigSource.class.getName());
+
+    /**
+     * Creates a new instance.
+     * @param url the resource URL, not null.
+     */
+    public PropertiesResourceConfigSource(URL url){
+        this(url, null);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the (optional) prefix context for mapping (prefixing) the properties loaded.
+     * @param url the resource URL, not null.
+     */
+    public PropertiesResourceConfigSource(URL url, String prefix){
+        super(url.toExternalForm(), loadProps(url), prefix);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the (optional) prefix context for mapping (prefixing) the properties loaded.
+     * @param path the resource path, not null.
+     */
+    public PropertiesResourceConfigSource(String path, String prefix){
+        super(path, loadProps(path, null), prefix);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the (optional) prefix context for mapping (prefixing) the properties loaded.
+     * @param path the resource path, not null.
+     */
+    public PropertiesResourceConfigSource(String path, String prefix, ClassLoader cl){
+        super(path, loadProps(path, cl), prefix);
+    }
+
+    /**
+     * Loads the properties using the JDK's Property loading mechanism.
+     * @param path the resource classpath, not null.
+     * @return the loaded properties.
+     */
+    private static Map<String, String> loadProps(String path, ClassLoader cl) {
+        if(cl==null){
+            cl = PropertiesResourceConfigSource.class.getClassLoader();
+        }
+        URL url = ServiceContextManager.getServiceContext().getResource(path, cl);
+        return loadProps(url);
+    }
+
+    /**
+     * Loads the properties using the JDK's Property loading mechanism.
+     * @param url the resource URL, not null.
+     * @return the loaded properties.
+     */
+    private static Map<String, String> loadProps(URL url) {
+        Map<String,String> result = new HashMap<>();
+        if(url!=null) {
+            try (InputStream is = url.openStream()) {
+                Properties props = new Properties();
+                props.load(is);
+                for (Map.Entry en : props.entrySet()) {
+                    result.put(en.getKey().toString(), en.getValue().toString());
+                }
+            } catch (Exception e) {
+                LOGGER.log(Level.WARNING, "Failed to read properties from " + url, e);
+            }
+        }else{
+            LOGGER.log(Level.WARNING, "No properties found at " + url);
+        }
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/SimpleConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/SimpleConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/SimpleConfigSource.java
new file mode 100644
index 0000000..8d59c4c
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/SimpleConfigSource.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.base.configsource;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+/**
+ * Simple implementation of a {@link javax.config.spi.ConfigSource} for
+ * simple property files and XML property files.
+ */
+public class SimpleConfigSource extends BaseConfigSource {
+
+    private static final Logger LOG = Logger.getLogger(SimpleConfigSource.class.getName());
+
+    /**
+     * The current properties.
+     */
+    private Map<String, String> properties = new HashMap<>();
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimpleConfigSource(File propertiesLocation) {
+        super(propertiesLocation.toString(), 0);
+        try {
+            this.properties = load(propertiesLocation.toURI().toURL());
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed to load properties from " + propertiesLocation, e);
+        }
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimpleConfigSource(URL propertiesLocation) {
+        super(propertiesLocation.toString(), 0);
+        this.properties = load(Objects.requireNonNull(propertiesLocation));
+    }
+
+    /**
+     * Creates a new Properties based PropertySource.
+     *
+     * @param name the property source name, not null.
+     * @param properties the properties, not null
+     * @param defaultOrdinal the default ordinal
+     */
+    public SimpleConfigSource(String name, Map<String, String> properties, int defaultOrdinal){
+        super(name, defaultOrdinal);
+        for(Map.Entry<String,String> en: properties.entrySet()) {
+            this.properties.put(en.getKey(), en.getValue());
+        }
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given properties map.
+     *
+     * @param name       the name, not null.
+     * @param properties the properties, not null.
+     */
+    public SimpleConfigSource(String name, Map<String, String> properties) {
+        this(name, properties, 0);
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param name               The property source name
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimpleConfigSource(String name, URL propertiesLocation) {
+        super(name, 0);
+        this.properties = load(propertiesLocation);
+    }
+
+    private SimpleConfigSource(Builder builder) {
+        properties = builder.properties;
+        if(builder.defaultOrdinal!=null){
+            setDefaultOrdinal(builder.defaultOrdinal);
+        }
+        if(builder.ordinal!=null){
+            setOrdinal(builder.ordinal);
+        }
+        setName(builder.name);
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return this.properties;
+    }
+
+    /**
+     * loads the Properties from the given URL
+     *
+     * @param propertiesFile {@link URL} to load Properties from
+     * @return loaded {@link Properties}
+     * @throws IllegalStateException in case of an error while reading properties-file
+     */
+    private static Map<String, String> load(URL propertiesFile) {
+        boolean isXML = isXMLPropertieFiles(propertiesFile);
+
+        Map<String, String> properties = new HashMap<>();
+        try (InputStream stream = propertiesFile.openStream()) {
+            Properties props = new Properties();
+            if (stream != null) {
+                if (isXML) {
+                    props.loadFromXML(stream);
+                } else {
+                    props.load(stream);
+                }
+            }
+            String source = propertiesFile.toString();
+            for (String key : props.stringPropertyNames()) {
+                properties.put(key, props.getProperty(key));
+            }
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Error loading properties from " + propertiesFile, e);
+        }
+
+        return properties;
+    }
+
+    private static boolean isXMLPropertieFiles(URL url) {
+        return url.getFile().endsWith(".xml");
+    }
+
+
+    /**
+     * {@code SimplePropertySource} builder static inner class.
+     */
+    public static final class Builder {
+        private String name;
+        private Integer defaultOrdinal;
+        private Integer ordinal;
+        private Map<String, String> properties = new HashMap<>();
+
+        private Builder() {
+        }
+
+        /**
+         * Sets the {@code name} to a new UUID and returns a reference to this Builder so that the methods
+         * can be chained together.
+         *
+         * @return a reference to this Builder
+         */
+        public Builder withUuidName() {
+            this.name = UUID.randomUUID().toString();
+            return this;
+        }
+
+        /**
+         * Sets the {@code name} and returns a reference to this Builder so that the methods
+         * can be chained together.
+         *
+         * @param val the {@code name} to set, not null.
+         * @return a reference to this Builder
+         */
+        public Builder withName(String val) {
+            this.name = Objects.requireNonNull(name);
+            return this;
+        }
+
+        /**
+         * Sets the {@code ordinal} and returns a reference to this Builder so that the methods
+         * can be chained together.
+         *
+         * @param val the {@code ordinal} to set
+         * @return a reference to this Builder
+         */
+        public Builder withOrdinal(int val) {
+            this.ordinal = val;
+            return this;
+        }
+
+        /**
+         * Sets the {@code defaultOrdinal} and returns a reference to this Builder so that the methods
+         * can be chained together.
+         *
+         * @param val the {@code defaultOrdinal} to set
+         * @return a reference to this Builder
+         */
+        public Builder withDefaultOrdinal(int val) {
+            this.defaultOrdinal = val;
+            return this;
+        }
+
+        /**
+         * Reads the {@code properties} from the given resource and returns a reference
+         * to this Builder so that the methods can be chained together.
+         *
+         * @param resource the {@code resource} to read
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(URL resource) {
+            this.properties.putAll(load(resource));
+            return this;
+        }
+
+        /**
+         * Reads the {@code properties} from the given resource and returns a reference
+         * to this Builder so that the methods can be chained together.
+         *
+         * @param file the {@code file} to read from (xml or properties format).
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(File file) {
+            try {
+                this.properties.putAll(load(file.toURI().toURL()));
+            } catch (MalformedURLException e) {
+                throw new IllegalArgumentException("Failed to read file: " + file, e);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the {@code properties} and returns a reference to this Builder so that the methods can be chained together.
+         *
+         * @param val the {@code properties} to set
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(Map<String, String> val) {
+            for(Map.Entry<String,String> en: val.entrySet()) {
+                this.properties.put(en.getKey(), en.getValue());
+            }
+            return this;
+        }
+
+        /**
+         * Sets the {@code properties} and returns a reference to this Builder so that the methods can be chained together.
+         *
+         * @param val the {@code properties} to set
+         * @return a reference to this Builder
+         */
+        public Builder withProperty(String key, String val) {
+            this.properties.put(key, val);
+            return this;
+        }
+
+        /**
+         * Returns a {@code SimplePropertySource} built from the parameters previously set.
+         *
+         * @return a {@code SimplePropertySource} built with parameters of this {@code SimplePropertySource.Builder}
+         */
+        public SimpleConfigSource build() {
+            return new SimpleConfigSource(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/SystemConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/SystemConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/SystemConfigSource.java
new file mode 100644
index 0000000..0daf5ce
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/SystemConfigSource.java
@@ -0,0 +1,186 @@
+/*
+ * 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.base.configsource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This {@link javax.config.spi.ConfigSource} manages the system properties. You can disable this feature by
+ * setting {@code tamaya.envprops.disable} or {@code tamaya.defaults.disable}.
+ */
+public class SystemConfigSource extends BaseConfigSource {
+
+    /**
+     * default ordinal used.
+     */
+    public static final int DEFAULT_ORDINAL = 1000;
+
+    private volatile Map<String,String> cachedProperties;
+
+    /**
+     * previous System.getProperties().hashCode()
+     * so we can check if we need to reload
+     */
+    private volatile int previousHash;
+
+    /**
+     * Prefix that allows system properties to virtually be mapped on specified sub section.
+     */
+    private String prefix;
+
+    /**
+     * If true, this property source does not return any properties. This is useful since this
+     * property source is applied by default, but can be switched off by setting the
+     * {@code tamaya.envprops.disable} system/environment property to {@code true}.
+     */
+    private boolean disabled = false;
+
+    /**
+     * Creates a new instance. Also initializes the {@code prefix} and {@code disabled} properties
+     * from the system-/ environment properties:
+     * <pre>
+     *     tamaya.envprops.prefix
+     *     tamaya.envprops.disable
+     * </pre>
+     */
+    public SystemConfigSource(){
+        super("system-properties", DEFAULT_ORDINAL);
+        initFromSystemProperties();
+        if(!disabled){
+            cachedProperties = Collections.unmodifiableMap(loadProperties());
+        }
+    }
+
+    /**
+     * Initializes the {@code prefix} and {@code disabled} properties from the system-/
+     * environment properties:
+     * <pre>
+     *     tamaya.envprops.prefix
+     *     tamaya.envprops.disable
+     * </pre>
+     */
+    private void initFromSystemProperties() {
+        String value = System.getProperty("tamaya.sysprops.prefix");
+        if(value==null){
+            prefix = System.getenv("tamaya.sysprops.prefix");
+        }
+        value = System.getProperty("tamaya.sysprops.disable");
+        if(value==null){
+            value = System.getenv("tamaya.sysprops.disable");
+        }
+        if(value==null){
+            value = System.getProperty("tamaya.defaults.disable");
+        }
+        if(value==null){
+            value = System.getenv("tamaya.defaults.disable");
+        }
+        if(value!=null && !value.isEmpty()) {
+            this.disabled = Boolean.parseBoolean(value);
+        }
+    }
+
+    /**
+     * Creates a new instance using a fixed ordinal value.
+     * @param ordinal the ordinal number.
+     */
+    public SystemConfigSource(int ordinal){
+        this(null, ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     * @param ordinal the ordinal to be used.
+     */
+    public SystemConfigSource(String prefix, int ordinal){
+        this.prefix = prefix;
+        setOrdinal(ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     */
+    public SystemConfigSource(String prefix){
+        this.prefix = prefix;
+    }
+
+
+    private Map<String, String> loadProperties() {
+        Properties sysProps = System.getProperties();
+        previousHash = System.getProperties().hashCode();
+        final String prefix = this.prefix;
+        Map<String, String> entries = new HashMap<>();
+        for (Map.Entry<Object,Object> entry : sysProps.entrySet()) {
+            if(entry.getKey() instanceof String && entry.getValue() instanceof String) {
+                if (prefix == null) {
+                    entries.put((String) entry.getKey(), (String) entry.getValue());
+                } else {
+                    entries.put(prefix + entry.getKey(), (String) entry.getValue());
+                }
+            }
+        }
+        return entries;
+    }
+
+    @Override
+    public String getName() {
+        if(disabled){
+            return super.getName() + "(disabled)";
+        }
+        return super.getName();
+    }
+
+    @Override
+    public String getValue(String key) {
+        if(disabled){
+            return null;
+        }
+        String prefix = this.prefix;
+        if(prefix==null) {
+            return System.getProperty(key);
+        }
+        return System.getProperty(key.substring(prefix.length()));
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        if(disabled){
+            return Collections.emptyMap();
+        }
+        // only need to reload and fill our map if something has changed
+        // synchronization was removed, Instance was marked as volatile. In the worst case it
+        // is reloaded twice, but the values will be the same.
+        if (previousHash != System.getProperties().hashCode()) {
+            Map<String, String> properties = loadProperties();
+            this.cachedProperties = Collections.unmodifiableMap(properties);
+        }
+        return this.cachedProperties;
+    }
+
+    @Override
+    protected String toStringValues() {
+        return  super.toStringValues() +
+                "  prefix=" + prefix + '\n' +
+                "  disabled=" + disabled + '\n';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/WrappedConfigSource.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/WrappedConfigSource.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/WrappedConfigSource.java
new file mode 100644
index 0000000..40842d1
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/WrappedConfigSource.java
@@ -0,0 +1,117 @@
+/*
+ * 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.base.configsource;
+
+import javax.config.spi.ConfigSource;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Property source effectively managed by the configuration context, allowing resetting of ordinal and its
+ * delegate (e.g. in case of refresh).
+ */
+class WrappedConfigSource implements ConfigSource{
+
+    private Integer ordinal;
+    private ConfigSource delegate;
+    private long loaded = System.currentTimeMillis();
+
+    private WrappedConfigSource(ConfigSource delegate) {
+        this(delegate, null);
+    }
+
+    private WrappedConfigSource(ConfigSource delegate, Integer ordinal) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.ordinal = ordinal;
+    }
+
+    public static WrappedConfigSource of(ConfigSource ps) {
+        if(ps instanceof WrappedConfigSource){
+            return (WrappedConfigSource)ps;
+        }
+        return new WrappedConfigSource(ps);
+    }
+
+    public static WrappedConfigSource of(ConfigSource ps, Integer ordinal) {
+        if(ps instanceof WrappedConfigSource){
+            return new WrappedConfigSource(((WrappedConfigSource)ps).getDelegate(), ordinal);
+        }
+        return new WrappedConfigSource(ps, ordinal);
+    }
+
+    public int getOrdinal() {
+        if(this.ordinal!=null){
+            return this.ordinal;
+        }
+        return ConfigSourceComparator.getOrdinal(delegate);
+    }
+
+    public void setOrdinal(Integer ordinal) {
+        this.ordinal = ordinal;
+    }
+
+    public void setDelegate(ConfigSource delegate) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.loaded = System.currentTimeMillis();
+    }
+
+    @Override
+    public String getName() {
+        return delegate.getName();
+    }
+
+    @Override
+    public String getValue(String key) {
+        return delegate.getValue(key);
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return delegate.getProperties();
+    }
+
+    public ConfigSource getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof WrappedConfigSource)) return false;
+
+        WrappedConfigSource that = (WrappedConfigSource) o;
+
+        return getDelegate().getName().equals(that.getDelegate().getName());
+    }
+
+    @Override
+    public int hashCode() {
+        return getDelegate().getName().hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "WrappedPropertySource{" +
+                "name=" + getName() +
+                ", ordinal=" + getOrdinal() +
+                ", loadedAt=" + loaded +
+                ", delegate-class=" + delegate.getClass().getName() +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/package-info.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/configsource/package-info.java b/code/base/src/main/java/org/apache/tamaya/base/configsource/package-info.java
new file mode 100644
index 0000000..26e6d85
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/configsource/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Contains default implementations for config sources.
+ */
+package org.apache.tamaya.base.configsource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/convert/ConversionContext.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/convert/ConversionContext.java b/code/base/src/main/java/org/apache/tamaya/base/convert/ConversionContext.java
new file mode 100644
index 0000000..6f88211
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/convert/ConversionContext.java
@@ -0,0 +1,253 @@
+/*
+ * 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.base.convert;
+
+import org.apache.tamaya.spi.TypeLiteral;
+
+import javax.config.Config;
+import javax.config.spi.Converter;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Type;
+import java.util.*;
+
+/**
+ * A conversion context containing all the required values for implementing conversion. Use the included #Builder
+ * for creating new instances of. This class is thread-safe to use. Adding supported formats is synchronized.
+ * @see Converter
+ */
+public class ConversionContext {
+
+    private final Config configuration;
+    private final String key;
+    private final Type targetType;
+    private final AnnotatedElement annotatedElement;
+    private final List<String> supportedFormats = new ArrayList<>();
+
+    private static ThreadLocal<ConversionContext> INSTANCE = new ThreadLocal<>();
+
+    public static ConversionContext getContext(){
+        return INSTANCE.get();
+    }
+
+    public static void setContext(ConversionContext context){
+        INSTANCE.set(Objects.requireNonNull(context));
+    }
+
+    public static void reset() {
+        INSTANCE.remove();
+    }
+
+    /**
+     * Private constructor used from builder.
+     * @param builder the builder, not {@code null}.
+     */
+    protected ConversionContext(Builder builder){
+        this.key = Objects.requireNonNull(builder.key);
+        this.annotatedElement = builder.annotatedElement;
+        this.targetType = Objects.requireNonNull(builder.targetType, "Target type required.");
+        this.supportedFormats.addAll(builder.supportedFormats);
+        this.configuration = builder.configuration;
+    }
+
+    /**
+     * Get the key accessed. This information is very useful to evaluate additional metadata needed to determine/
+     * control further aspects of the conversion.
+     * @return the key. This may be null in case where a default value has to be converted and no unique underlying
+     * key/value configuration is present.
+     */
+    public final String getKey(){
+        return key;
+    }
+
+    /**
+     * Get the target type required.
+     * @return the target type required.
+     */
+    public final Type getTargetType(){
+        return targetType;
+    }
+
+    /**
+     * Get the annotated element, if conversion is performed using injection mechanisms.
+     * @return the annotated element, or {@code null}.
+     */
+    public final AnnotatedElement getAnnotatedElement(){
+        return annotatedElement;
+    }
+
+    /**
+     * Get the configuration, which is targeted.
+     * @return the current configuration context, or {@code null}.
+     */
+    public final Config getConfiguration(){
+        return configuration;
+    }
+
+    /**
+     * Allows to add information on the supported/tried formats, which can be shown to the user, especially when
+     * conversion failed. Adding of formats is synchronized, all formats are added in order to the overall list.
+     * This means formats should be passed in order of precedence.
+     * @param converterType the converters, which implements the formats provided.
+     * @param formatDescriptors the format descriptions in a human readable form, e.g. as regular expressions.
+     */
+    public final void addSupportedFormats(@SuppressWarnings("rawtypes") Class<? extends Converter> converterType, String... formatDescriptors){
+        synchronized (supportedFormats){
+            for(String format: formatDescriptors) {
+                supportedFormats.add(format + " (" + converterType.getSimpleName() + ")");
+            }
+        }
+    }
+
+    /**
+     * Get the supported/tried formats in precedence order. The contents of this method depends on the
+     * {@link Converter} instances involved in a conversion.
+     * @return the supported/tried formats, never {@code null}.
+     */
+    public final List<String> getSupportedFormats(){
+        synchronized (supportedFormats){
+            return new ArrayList<>(supportedFormats);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "ConversionContext{" +
+                "configuration=" + configuration +
+                ", key='" + key + '\'' +
+                ", targetType=" + targetType +
+                ", annotatedElement=" + annotatedElement +
+                ", supportedFormats=" + supportedFormats +
+                '}';
+    }
+
+
+    /**
+     * Builder to create new instances of {@link ConversionContext}.
+     */
+    public static final class Builder{
+        /** The backing configuration. */
+        private Config configuration;
+        /** The accessed key, or null. */
+        private String key;
+        /** The target type. */
+        private Type targetType;
+        /** The injection target (only set with injection used). */
+        private AnnotatedElement annotatedElement;
+        /** The ordered list of formats tried. */
+        private final Set<String> supportedFormats = new HashSet<>();
+
+        /**
+         * Creates a new Builder instance.
+         * @param key the requested key, may be null.
+         * @param targetType the target type
+         */
+        public Builder(String key, Type targetType) {
+            this(null, key, targetType);
+        }
+
+        /**
+         * Creates a new Builder instance.
+         * @param configuration the configuration, not {@code null}.
+         * @param key the requested key, may be {@code null}.
+         * @param targetType the target type
+         */
+        public Builder(Config configuration, String key, Type targetType){
+            this.key = Objects.requireNonNull(key, "Key required");
+            this.configuration = configuration;
+            this.targetType = Objects.requireNonNull(targetType, "Target type required.");
+        }
+
+        /**
+         * Sets the key.
+         * @param key the key, not {@code null}.
+         * @return the builder instance, for chaining
+         */
+        public Builder setKey(String key){
+            this.key = Objects.requireNonNull(key);
+            return this;
+        }
+
+        /**
+         * Sets the configuration.
+         * @param configuration the configuration, not {@code null}
+         * @return the builder instance, for chaining
+         */
+        public Builder setConfiguration(Config configuration){
+            this.configuration = configuration;
+            return this;
+        }
+
+        /**
+         * Sets the annotated element, when configuration is injected.
+         * @param annotatedElement the annotated element, not {@code null}
+         * @return the builder instance, for chaining
+         */
+        public Builder setAnnotatedElement(AnnotatedElement annotatedElement){
+            this.annotatedElement = Objects.requireNonNull(annotatedElement);
+            return this;
+        }
+
+        /**
+         * Sets the target type explicitly. This is required in some rare cases, e.g. injection of {@code Provider}
+         * instances, where the provider's result type must be produced.
+         * @param targetType the
+         * @return the builder for chaining.
+         */
+        public Builder setTargetType(Type targetType) {
+            this.targetType = Objects.requireNonNull(targetType);
+            return this;
+        }
+
+        /**
+         * Add the formats provided by a {@link Converter}. This method should be called by each converters
+         * performing/trying conversion, so the user can be given feedback on the supported formats on failure.
+         * @param converterType the converters type, not {@code null}.
+         * @param formatDescriptors the formats supported in a human readable form, e.g. as regular expressions.
+         * @return the builder instance, for chaining
+         */
+        public Builder addSupportedFormats(@SuppressWarnings("rawtypes") Class<? extends Converter> converterType, String... formatDescriptors){
+            for(String format: formatDescriptors) {
+                supportedFormats.add(format + " (" + converterType.getSimpleName() + ")");
+            }
+            return this;
+        }
+
+        /**
+         * Builds a new context instance.
+         * @return a new context, never null.
+         */
+        public ConversionContext build(){
+            ConversionContext ctx = new ConversionContext(this);
+            INSTANCE.set(ctx);
+            return ctx;
+        }
+
+        @Override
+        public String toString() {
+            return "Builder{" +
+                    "configuration=" + configuration +
+                    ", key='" + key + '\'' +
+                    ", targetType=" + targetType +
+                    ", annotatedElement=" + annotatedElement +
+                    ", supportedFormats=" + supportedFormats +
+                    '}';
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/convert/ConverterManager.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/convert/ConverterManager.java b/code/base/src/main/java/org/apache/tamaya/base/convert/ConverterManager.java
new file mode 100644
index 0000000..b7a0888
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/convert/ConverterManager.java
@@ -0,0 +1,630 @@
+/*
+ * 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.base.convert;
+
+import org.apache.tamaya.base.FormatUtils;
+import org.apache.tamaya.base.PriorityServiceComparator;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.config.Config;
+import javax.config.spi.Converter;
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Manager that deals with {@link Converter} instances.
+ * This class is thread-safe.
+ */
+public class ConverterManager {
+    /**
+     * The logger used.
+     */
+    private static final Logger LOG = Logger.getLogger(ConverterManager.class.getName());
+    /**
+     * The registered converters.
+     */
+    private final Map<Type, List<Converter>> converters = new ConcurrentHashMap<>();
+    /**
+     * The transitive converters.
+     */
+    private final Map<Type, List<Converter>> transitiveConverters = new ConcurrentHashMap<>();
+
+    private ClassLoader classloader = ServiceContext.defaultClassLoader();
+
+    private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() {
+
+        @Override
+        public int compare(Object o1, Object o2) {
+            int prio = PriorityServiceComparator.getPriority(o1) - PriorityServiceComparator.getPriority(o2);
+            if (prio < 0) {
+                return 1;
+            } else if (prio > 0) {
+                return -1;
+            } else {
+                return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+            }
+        }
+    };
+
+    /**
+     * Get the classloader used for instance creation.
+     * @return the classloader, never null.
+     */
+    public ClassLoader getClassloader(){
+        return classloader;
+    }
+
+    /**
+     * Sets the classloader to use for loading of instances.
+     * @param ClassLoader the classloader, not null.
+     * @return this instance for chaining.
+     */
+    public ConverterManager setClassloader(ClassLoader ClassLoader){
+        this.classloader = Objects.requireNonNull(classloader);
+        return this;
+    }
+
+    /**
+     * Checks the current implemented generic interfaces and evaluates the given single type parameter.
+     *
+     * @param clazz         the class to check, not  {@code null}.
+     * @param interfaceType the interface type to be checked, not {@code null}.
+     * @return the generic type parameters, or an empty array, if it cannot be evaluated.
+     */
+    private Type[] getGenericInterfaceTypeParameters(Class<?> clazz, Class<?> interfaceType) {
+        Objects.requireNonNull(clazz, "Class parameter must be given.");
+        Objects.requireNonNull(interfaceType, "Interface parameter must be given.");
+
+        for (Type type : clazz.getGenericInterfaces()) {
+            if (type instanceof ParameterizedType) {
+                ParameterizedType parameterizedType = (ParameterizedType) type;
+                if(parameterizedType.getRawType().equals(interfaceType)){
+                    return parameterizedType.getActualTypeArguments();
+                }
+            }
+        }
+        return new Type[0];
+    }
+
+    /**
+     * This method can be used for adding {@link PropertyConverter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converters is for
+     * @param converters the converters to add for this type
+     * @return this builder, for chaining, never null.
+     */
+    public <T> ConverterManager addConverter(Type typeToConvert, Converter<T>... converters) {
+        return addConverter(typeToConvert, Arrays.asList(converters));
+    }
+
+    /**
+     * This method can be used for adding {@link PropertyConverter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converters is for
+     * @param converters the converters to add for this type
+     * @return this builder, for chaining, never null.
+     */
+    public <T> ConverterManager addConverter(Type typeToConvert, Collection<Converter<T>> converters) {
+        Objects.requireNonNull(converters);
+        List<Converter> converterList = List.class.cast(this.converters.get(typeToConvert));
+        if(converterList==null){
+            converterList = new ArrayList<>();
+        }else{
+            converterList = new ArrayList<>(converterList);
+        }
+        for(Converter converter:converters) {
+            if (!converterList.contains(converter)) {
+                converterList.add(converter);
+            }
+        }
+        Collections.sort(converterList, PRIORITY_COMPARATOR);
+        this.converters.put(typeToConvert, Collections.unmodifiableList(converterList));
+        addTransitiveConverters(typeToConvert, Collection.class.cast(converters));
+        return this;
+    }
+
+    private ConverterManager addTransitiveConverters(Type typeToConvert, Collection<Converter> converters) {
+        // evaluate transitive closure for all inherited supertypes and implemented interfaces
+        // direct implemented interfaces
+        if(typeToConvert instanceof Class) {
+            Class targetClass = (Class) typeToConvert;
+            for (Class<?> ifaceType : targetClass.getInterfaces()) {
+                List<Converter> converterList = List.class.cast(this.transitiveConverters.get(typeToConvert));
+                if(converterList==null){
+                    converterList = new ArrayList<>();
+                }else{
+                    converterList = new ArrayList<>(converterList);
+                }
+                for(Converter converter:converters){
+                    if(!converterList.contains(converter)){
+                        converterList.add(converter);
+                    }
+                }
+                Collections.sort(converterList, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(ifaceType, Collections.unmodifiableList(converterList));
+            }
+            Class<?> superClass = targetClass.getSuperclass();
+            while (superClass != null && !superClass.equals(Object.class)) {
+                List<Converter> converterList = List.class.cast(this.transitiveConverters.get(superClass));
+                if(converterList==null){
+                    converterList = new ArrayList<>();
+                }else{
+                    converterList = new ArrayList<>(converterList);
+                }
+                for(Converter converter:converters){
+                    if(!converterList.contains(converter)){
+                        converterList.add(converter);
+                    }
+                }
+                Collections.sort(converterList, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(superClass, Collections.unmodifiableList(converterList));
+                addTransitiveConverters(superClass, converters);
+                superClass = superClass.getSuperclass();
+            }
+        }
+        return this;
+    }
+
+    public ConverterManager addConverters(Converter... converters){
+        return addConverters(Arrays.asList(converters));
+    }
+
+    public ConverterManager addConverters(Collection<Converter> converters){
+        for(Converter conv:converters) {
+            addConverter(conv);
+        }
+        return this;
+    }
+
+    public ConverterManager addConverter(Converter conv) {
+        for (Type type : conv.getClass().getGenericInterfaces()) {
+            if (type instanceof ParameterizedType) {
+                ParameterizedType pt = (ParameterizedType) type;
+                if (Converter.class.equals(((ParameterizedType) type).getRawType())) {
+                    Type target = pt.getActualTypeArguments()[0];
+                    addConverter(target, conv);
+                }
+            }
+        }
+        return this;
+    }
+
+    public ConverterManager addDiscoveredConverters() {
+        addCoreConverters();
+        for(Map.Entry<Type, Collection<Converter<?>>> en:getDefaultConverters().entrySet()){
+            for(Converter pc: en.getValue()) {
+                addConverter(en.getKey(), pc);
+            }
+        }
+        return this;
+    }
+
+    protected Map<Type, Collection<Converter<?>>> getDefaultConverters() {
+        Map<Type, Collection<Converter<?>>> result = new HashMap<>();
+        for (Converter<?> conv : ServiceContextManager.getServiceContext().getServices(
+                Converter.class, classloader)) {
+            addConverter(conv);
+        }
+        return result;
+    }
+
+    protected ConverterManager addCoreConverters() {
+        // should be overridden by subclasses.
+        return this;
+    }
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param converters    the converters to remove
+     * @return this builder, for chaining, never null.
+     */
+    public ConverterManager removeConverters(Type typeToConvert,
+                                             @SuppressWarnings("unchecked") Converter... converters){
+        return removeConverters(typeToConvert, Arrays.asList(converters));
+    }
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param converters    the converters to remove
+     * @return this builder, for chaining, never null.
+     */
+    public ConverterManager removeConverters(Type typeToConvert,
+                                             Collection<Converter> converters){
+        Objects.requireNonNull(converters);
+        List<Converter> converterList = List.class.cast(this.converters.get(typeToConvert));
+        if(converterList!=null){
+            converterList = new ArrayList<>(converterList);
+            converterList.removeAll(converters);
+        }
+        Collections.sort(converterList, PRIORITY_COMPARATOR);
+        this.converters.put(typeToConvert, Collections.unmodifiableList(converterList));
+        return this;
+    }
+
+    /**
+     * Removes all converters for the given type, which actually renders a given type
+     * unsupported for type conversion.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @return this builder, for chaining, never null.
+     */
+    public ConverterManager removeConverters(Type typeToConvert){
+        this.converters.remove(typeToConvert);
+        this.transitiveConverters.remove(typeToConvert);
+        return this;
+    }
+
+    /**
+     * Removes all contained items.
+     * @return this instance for chaining.
+     */
+    public ConverterManager clear() {
+        this.converters.clear();
+        this.transitiveConverters.clear();
+        return this;
+    }
+
+    /**
+     * Allows to evaluate if a given target type is supported.
+     *
+     * @param targetType the target type, not {@code null}.
+     * @return true, if a converters for the given type is registered, or a default one can be created.
+     */
+    public boolean isTargetTypeSupported(Type targetType) {
+        return converters.containsKey(targetType) || transitiveConverters.containsKey(targetType) || createDefaultPropertyConverter(targetType) != null;
+    }
+
+    /**
+     * Get a map of all property converters currently registered. This will not contain the converters that
+     * may be created, when an instance is adapted, which provides a String constructor or compatible
+     * factory methods taking a single String instance.
+     *
+     * @return the current map of instantiated and registered converters.
+     * @see #createDefaultPropertyConverter(Type)
+     */
+    public Map<Type, List<Converter>> getConverters() {
+        return new HashMap<>(this.converters);
+    }
+
+    /**
+     * Get the list of all current registered converters for the given target type.
+     * If not converters are registered, they component tries to create and addSources a dynamic
+     * converters based on String constructor or static factory methods available.
+     * The converters provided are of the following type and returned in the following order:
+     * <ul>
+     * <li>Converters mapped explicitly to the required target type are returned first, ordered
+     * by decreasing priority. This means, if explicit converters are registered these are used
+     * primarily for converting a value.</li>
+     * <li>The target type of each explicitly registered converters also can be transitively mapped to
+     * 1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces
+     * implemented by its superclasses. These groups of transitive converters is returned similarly in the
+     * order as mentioned, whereas also here a priority based decreasing ordering is applied.</li>
+     * <li>java.lang wrapper classes and native types are automatically mapped.</li>
+     * <li>If no explicit converters are registered, for Enum types a default implementation is provided that
+     * compares the configuration values with the different enum members defined (cases sensitive mapping).</li>
+     * </ul>
+     * <p>
+     * So given that list above directly registered mappings always are tried first, before any transitive mapping
+     * should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place.
+     * Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and
+     * the inheritance hierarchy (exception Object). Superinterfaces of implemented interfaces are ignored.
+     *
+     * @param targetType the target type, not {@code null}.
+     * @return the ordered list of converters (may be empty for not convertible types).
+     * @see #createDefaultPropertyConverter(Type)
+     */
+    public List<Converter> getConverters(Type targetType) {
+        List<Converter> converterList = new ArrayList<>();
+        addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
+        addConvertersToList(List.class.cast(this.transitiveConverters.get(targetType)), converterList);
+
+        // handling of java.lang wrapper classes
+        Type boxedType = mapBoxedType(targetType);
+        if (boxedType != null) {
+            addConvertersToList(List.class.cast(this.converters.get(boxedType)), converterList);
+        }
+        if (converterList.isEmpty() && !String.class.equals(targetType)) {
+            // adding any converters created on the fly, e.g. for enum types.
+            Converter defaultConverter = createDefaultPropertyConverter(targetType);
+            if (defaultConverter != null) {
+                addConverter(targetType, defaultConverter);
+                addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
+            }
+        }
+        // check for parametrized types, ignoring param type
+        // direct mapped converters
+        if(targetType!=null) {
+            addConvertersToList(List.class.cast(this.converters.get(
+                        targetType)), converterList);
+        }
+        return converterList;
+    }
+
+    public Object convertValue(String key, String value, Type type, Config config) {
+        if (value != null) {
+            List<Converter> converters = getConverters(type);
+            org.apache.tamaya.base.convert.ConversionContext context = new org.apache.tamaya.base.convert.ConversionContext.Builder(config, key, type)
+                    .build();
+            ConversionContext.setContext(context);
+            for (Converter converter : converters) {
+                try {
+                    Object t = converter.convert(value);
+                    if (t != null) {
+                        return t;
+                    }
+                } catch (Exception e) {
+                    LOG.log(Level.FINEST, "PropertyConverter: " + converter + " failed to convert value: " + value, e);
+                }
+            }
+            // if the target type is a String, we can return the value, no conversion required.
+            if(type.equals(String.class)){
+                return value;
+            }
+            // unsupported type, throw an exception
+            throw new IllegalStateException("Unparseable config value for type: " + type.getTypeName() + ": " + key +
+                    ", supported formats: " + context.getSupportedFormats());
+        }
+        return null;
+    }
+
+    private <T> void addConvertersToList(Collection<Converter> converters, List<Converter> converterList) {
+        if (converters != null) {
+            for(Converter<T> conv:converters) {
+                if(!converterList.contains(conv)) {
+                    converterList.add(conv);
+                }
+            }
+        }
+    }
+
+    /**
+     * Maps native types to the corresponding boxed types.
+     *
+     * @param parameterType the native type.
+     * @param <T>        the type
+     * @return the boxed type, or null.
+     */
+    @SuppressWarnings("unchecked")
+	private <T> Type mapBoxedType(Type parameterType) {
+        if (parameterType == int.class) {
+            return Integer.class;
+        }
+        if (parameterType == short.class) {
+            return Short.class;
+        }
+        if (parameterType == byte.class) {
+            return Byte.class;
+        }
+        if (parameterType == long.class) {
+            return Long.class;
+        }
+        if (parameterType == boolean.class) {
+            return Boolean.class;
+        }
+        if (parameterType == char.class) {
+            return Character.class;
+        }
+        if (parameterType == float.class) {
+            return Float.class;
+        }
+        if (parameterType == double.class) {
+            return Double.class;
+        }
+        if (parameterType == int[].class) {
+            return Integer[].class;
+        }
+        if (parameterType == short[].class) {
+            return Short[].class;
+        }
+        if (parameterType == byte[].class) {
+            return Byte[].class;
+        }
+        if (parameterType == long[].class) {
+            return Long[].class;
+        }
+        if (parameterType == boolean.class) {
+            return Boolean.class;
+        }
+        if (parameterType == char[].class) {
+            return Character[].class;
+        }
+        if (parameterType == float[].class) {
+            return Float[].class;
+        }
+        if (parameterType == double[].class) {
+            return Double[].class;
+        }
+        return null;
+    }
+
+    /**
+     * Creates a dynamic PropertyConverter for the given target type.
+     *
+     * @param targetType the target type
+     * @return a new converters, or null.
+     */
+    protected Converter createDefaultPropertyConverter(final Type targetType) {
+        if(!(targetType instanceof Class)){
+            return null;
+        }
+        Class targetClass = (Class)targetType;
+        if (Enum.class.isAssignableFrom(targetClass)) {
+            return new EnumConverter<>(targetClass);
+        }
+        Converter converter = null;
+        final Method factoryMethod = getFactoryMethod(targetClass, "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse");
+        if (factoryMethod != null) {
+            converter = new DefaultPropertyConverter<>(factoryMethod, targetClass);
+        }
+        if (converter == null) {
+            final Constructor constr;
+            try {
+                constr = targetClass.getDeclaredConstructor(String.class);
+            } catch (NoSuchMethodException e) {
+                LOG.log(Level.FINEST, "No matching constrctor for " + targetType, e);
+                return null;
+            }
+            converter = new Converter() {
+                    @Override
+                    public Object convert(String value) {
+                        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                            @Override
+                            public Object run() {
+                                AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                                    @Override
+                                    public Object run() {
+                                        constr.setAccessible(true);
+                                        return null;
+                                    }
+                                });
+                                return null;
+                            }
+                        });
+                        try {
+                            return constr.newInstance(value);
+                        } catch (Exception e) {
+                            LOG.log(Level.SEVERE, "Error creating new PropertyConverter instance " + targetType, e);
+                        }
+                        return null;
+                    }
+                };
+        }
+        return converter;
+    }
+
+    /**
+     * Tries to evaluate a factory method that can be used to create an instance based on a String.
+     *
+     * @param type        the target type
+     * @param methodNames the possible static method names
+     * @return the first method found, or null.
+     */
+    private Method getFactoryMethod(Class<?> type, String... methodNames) {
+        Method m;
+        for (String name : methodNames) {
+            try {
+                m = type.getDeclaredMethod(name, String.class);
+                return m;
+            } catch (NoSuchMethodException | RuntimeException e) {
+                LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof ConverterManager)) {
+            return false;
+        }
+        ConverterManager that = (ConverterManager) o;
+        return converters.equals(that.converters);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return converters.hashCode();
+    }
+
+    /**
+     * Default converters imüöementation perfoming several lookups for String converion
+     * option.
+     * @param <T>
+     */
+    private static class DefaultPropertyConverter<T> implements Converter<T> {
+
+        private final Method factoryMethod;
+        private final Class<T> targetType;
+
+        DefaultPropertyConverter(Method factoryMethod, Class<T> targetType){
+            this.factoryMethod = Objects.requireNonNull(factoryMethod);
+            this.targetType =  Objects.requireNonNull(targetType);
+        }
+
+        @Override
+        public T convert(String value) {
+            ConversionContext.getContext().addSupportedFormats(getClass(), "<String -> "+factoryMethod.toGenericString());
+
+            if (!Modifier.isStatic(factoryMethod.getModifiers())) {
+                throw new IllegalArgumentException(factoryMethod.toGenericString() +
+                        " is not a static method. Only static " +
+                        "methods can be used as factory methods.");
+            }
+            try {
+                AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                    @Override
+                    public Object run() {
+                        factoryMethod.setAccessible(true);
+                        return null;
+                    }
+                });
+                Object invoke = factoryMethod.invoke(null, value);
+                return targetType.cast(invoke);
+            } catch (Exception e) {
+                throw new IllegalArgumentException("Failed to decode '" + value + "'", e);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append("Converters\n");
+        b.append("----------\n");
+        b.append("  CLASS                         TYPE                          INFO\n\n");
+        for(Map.Entry<Type, List<Converter>> converterEntry: getConverters().entrySet()){
+            for(Converter converter: converterEntry.getValue()){
+                b.append("  ");
+                FormatUtils.appendFormatted(b, converter.getClass().getSimpleName(), 30);
+                if(converterEntry.getKey() instanceof ParameterizedType){
+                    ParameterizedType pt = (ParameterizedType)converterEntry.getKey();
+                    FormatUtils.appendFormatted(b, pt.getRawType().getTypeName(), 30);
+                }else{
+                    FormatUtils.appendFormatted(b, converterEntry.getKey().getTypeName(), 30);
+                }
+                b.append(FormatUtils.removeNewLines(converter.toString()));
+                b.append('\n');
+            }
+        }
+        return b.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/convert/EnumConverter.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/convert/EnumConverter.java b/code/base/src/main/java/org/apache/tamaya/base/convert/EnumConverter.java
new file mode 100644
index 0000000..c0f727b
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/convert/EnumConverter.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.base.convert;
+
+//import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to tge given enum type.
+ */
+//@Component(service = Converter.class)
+public class EnumConverter<T> implements Converter<T> {
+    private final Logger LOG = Logger.getLogger(EnumConverter.class.getName());
+    private Class<T> enumType;
+    private Method factory;
+
+    public EnumConverter(Class<T> enumType) {
+        if (!Enum.class.isAssignableFrom(enumType)) {
+            throw new IllegalArgumentException("Not an Enum: " + enumType.getName());
+        }
+        this.enumType = Objects.requireNonNull(enumType);
+        try {
+            this.factory = enumType.getMethod("valueOf", String.class);
+        } catch (NoSuchMethodException e) {
+            throw new IllegalArgumentException("Uncovertible enum type without valueOf method found, please provide a custom " +
+                    "PropertyConverter for: " + enumType.getName());
+        }
+    }
+
+    @Override
+    public T convert(String value) {
+        ConversionContext.getContext().addSupportedFormats(getClass(),"<enumValue>");
+        try {
+            return (T) factory.invoke(null, value);
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+        }
+        try {
+            return (T) factory.invoke(null, value.toUpperCase(Locale.ENGLISH));
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof EnumConverter)) return false;
+        EnumConverter<?> that = (EnumConverter<?>) o;
+        return Objects.equals(enumType, that.enumType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(enumType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/convert/package-info.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/convert/package-info.java b/code/base/src/main/java/org/apache/tamaya/base/convert/package-info.java
new file mode 100644
index 0000000..c63629a
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/convert/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Default implementations for converters and converter management.
+ */
+package org.apache.tamaya.base.convert;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/filter/FilterComparator.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/filter/FilterComparator.java b/code/base/src/main/java/org/apache/tamaya/base/filter/FilterComparator.java
new file mode 100644
index 0000000..dd2bd49
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/filter/FilterComparator.java
@@ -0,0 +1,72 @@
+/*
+ * 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.base.filter;
+
+import org.apache.tamaya.spi.Filter;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Comparator for PropertyFilters based on their priority annotations.
+ */
+public final class FilterComparator implements Comparator<Filter>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final FilterComparator INSTANCE = new FilterComparator();
+
+    /**
+     * Get the shared instance of the comparator.
+     * @return the shared instance, never null.
+     */
+    public static FilterComparator getInstance(){
+        return INSTANCE;
+    }
+
+    private FilterComparator(){}
+
+    /**
+     * Compare 2 filters for ordering the filter chain.
+     *
+     * @param filter1 the first filter
+     * @param filter2 the second filter
+     * @return the comparison result
+     */
+    private int comparePropertyFilters(Filter filter1, Filter filter2) {
+        Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
+        Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
+        int ord1 = prio1 != null ? prio1.value() : 0;
+        int ord2 = prio2 != null ? prio2.value() : 0;
+
+        if (ord1 < ord2) {
+            return -1;
+        } else if (ord1 > ord2) {
+            return 1;
+        } else {
+            return filter1.getClass().getName().compareTo(filter2.getClass().getName());
+        }
+    }
+
+    @Override
+    public int compare(Filter filter1, Filter filter2) {
+        return comparePropertyFilters(filter1, filter2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/filter/FilterContext.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/filter/FilterContext.java b/code/base/src/main/java/org/apache/tamaya/base/filter/FilterContext.java
new file mode 100644
index 0000000..6769445
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/filter/FilterContext.java
@@ -0,0 +1,144 @@
+/*
+ * 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.base.filter;
+
+import org.apache.tamaya.spi.ConfigValue;
+import org.apache.tamaya.spi.Filter;
+
+import javax.config.Config;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A filter context containing all the required values for implementing filtering.
+ *
+ * @see Filter
+ */
+public final class FilterContext {
+    /** The key. */
+    private final ConfigValue property;
+
+    private Map<String,String> configEntries = new HashMap<>();
+
+    /** The current context. */
+    private final Config config;
+
+    private boolean singlePropertyScoped;
+
+    private static ThreadLocal<FilterContext> INSTANCE = new ThreadLocal<>();
+
+    public static FilterContext getContext(){
+        return INSTANCE.get();
+    }
+
+    public static void setContext(FilterContext context){
+        INSTANCE.set(Objects.requireNonNull(context));
+    }
+
+    /**
+     * Creates a new FilterContext, for filtering of a multi value access
+     * using {@link Config#getPropertyNames()} .
+     *
+     * @param value the value under evaluation, not {@code null}.
+     * @param configEntries the raw configuration data available in the
+     *                      current evaluation context, not {@code null}.
+     * @param config the current config, not {@code null}.
+     */
+    public FilterContext(ConfigValue value, Map<String,String> configEntries, Config config) {
+        Objects.requireNonNull(value, "Value must not be null.");
+        Objects.requireNonNull(configEntries, "Initial configuration entries must be not null.");
+        Objects.requireNonNull(config, "config must be not null.");
+
+        this.singlePropertyScoped = false;
+        this.property = Objects.requireNonNull(value);
+        this.configEntries.putAll(configEntries);
+        this.config = config;
+    }
+
+    /**
+     * Creates a new FilterContext, for filtering of a single value access
+     * using {@link Config#getPropertyNames()}.
+     * @param value the value under evaluation, not {@code null}.
+     * @param config the current config, not {@code null}.
+     */
+    public FilterContext(ConfigValue value, Config config) {
+        this.config = config;
+        this.property = Objects.requireNonNull(value, "Value must not be null.");
+        this.singlePropertyScoped = true;
+    }
+
+    /**
+     * Get the current context.
+     * @return the current context, not {@code null}.
+     */
+    public Config getConfig(){
+        return config;
+    }
+
+    /**
+     * Get the property value under evaluation. This information is very useful to evaluate additional metadata needed to determine/
+     * control further aspects of the conversion.
+     *
+     * @return the key. This may be null in case where a default value has to be converted and no unique underlying
+     * key/value configuration is present.
+     */
+    public ConfigValue getProperty() {
+        return property;
+    }
+
+    /**
+     * Method that determines if filtering is done for a single property accessed, or as part of call to
+     * {@code getProperties()}.
+     * @return true, if its scoped to a single property accessed.
+     */
+    public boolean isSinglePropertyScoped(){
+        return singlePropertyScoped;
+    }
+
+    /**
+     * This map contains the following keys:
+     * <ul>
+     * <li>the original value <b>before</b> any filters were applied on it.</li>
+     * <li>all values starting with an {@code _<key>.}, for example {@code a.value}
+     * may have a map set with {@code a.value} (oringinal value), {@code _a.value.origin,
+     * _a.value.type, etc}. The exact contents is determine by the {@link javax.config.spi.ConfigSource}s
+     * active.</li>
+     * </ul>
+     * Also important to know is that this map given contains all the evaluated raw entries, regardless
+     * of the filters that are later applied. This ensures that met-information required by one filter is
+     * not hidden by another filter, because of an invalid filter ordering. In other words filters may remove
+     * key/value pairs, e.g. fir security reasons, by returning {@code null}, but the values in the raw map
+     * passed as input to the filter process will not be affected by any such removal (but the final properties
+     * returned are affected, of course).
+     * 
+     * Finally, when a single property is accessed, e.g. by calling {@code Configuration.get(String)}.
+     *
+     * @return the configuration instance, or null.
+     */
+    public Map<String, String> getConfigEntries() {
+        return configEntries;
+    }
+
+    @Override
+    public String toString() {
+        return "FilterContext{property='" + property + "', configEntries=" + configEntries.keySet() + '}';
+    }
+
+}



[4/6] incubator-tamaya git commit: Added full JSR implementation.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/filter/FilterManager.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/filter/FilterManager.java b/code/base/src/main/java/org/apache/tamaya/base/filter/FilterManager.java
new file mode 100644
index 0000000..32c8f3f
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/filter/FilterManager.java
@@ -0,0 +1,273 @@
+/*
+ * 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.base.filter;
+
+import org.apache.tamaya.base.FormatUtils;
+import org.apache.tamaya.spi.Filter;
+import org.apache.tamaya.spi.ConfigValue;
+import org.apache.tamaya.spi.ServiceContext;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.config.Config;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link javax.config.Config} to evaluate the
+ * chain of {@link javax.config.spi.ConfigSource} and {@link Filter}
+ * instance to evaluate the current Configuration.
+ */
+public class FilterManager {
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(FilterManager.class.getName());
+    /**
+     * The maximal number of filter cycles performed before aborting.
+     */
+    private static final int MAX_FILTER_LOOPS = 10;
+
+    private List<Filter> filters = new ArrayList<>();
+
+    private ClassLoader classloader = ServiceContext.defaultClassLoader();
+
+    /**
+     * Create a new filter manager.
+     */
+    public FilterManager(){
+    }
+
+    /**
+     * Create a new filter manager.
+     * @param filters the filters to be used, not null.
+     */
+    public FilterManager(List<Filter> filters){
+        this.filters.addAll(filters);
+        LOG.info("Registered " + filters.size() + " config filter: " + filters);
+    }
+
+    /**
+     * Get the classloader used for instance creation.
+     * @return the classloader, never null.
+     */
+    public ClassLoader getClassloader(){
+        return classloader;
+    }
+
+    /**
+     * Sets the classloader to use for loading of instances.
+     * @param ClassLoader the classloader, not null.
+     * @return this instance for chaining.
+     */
+    public FilterManager setClassloader(ClassLoader ClassLoader){
+        this.classloader = Objects.requireNonNull(classloader);
+        return this;
+    }
+
+    /**
+     * Get the current list of filters.
+     * @return the list of filters.
+     */
+    public List<Filter> getFilters(){
+        return Collections.unmodifiableList(filters);
+    }
+
+    /**
+     * Adds the given Filter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the
+     * filters call {@link #sortFilter}.
+     *
+     * @param filters the filters to add
+     * @return this instance, for chaining, never null.
+     */
+    public FilterManager addFilter(Filter... filters) {
+        return addFilter(Arrays.asList(filters));
+    }
+
+    /**
+     * Adds the given Filter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the
+     * filters call {@link #sortFilter}.
+     *
+     * @param filters the filters to add
+     * @return this instance, for chaining, never null.
+     */
+    public FilterManager addFilter(Collection<Filter> filters) {
+        Objects.requireNonNull(filters);
+        for(Filter filter:filters) {
+            if (!this.filters.contains(filter)) {
+                this.filters.add(filter);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Removes the given PropertyFilter instances, if existing. The order of the remaining
+     * filters is preserved.
+     *
+     * @param filters the filter to remove
+     * @return this builder, for chaining, never null.
+     */
+    public FilterManager removeFilters(Filter... filters){
+        return removeFilters(Arrays.asList(filters));
+    }
+
+    /**
+     * Removes the given PropertyFilter instances, if existing. The order of the remaining
+     * filters is preserved.
+     *
+     * @param filters the filter to remove
+     * @return this builder, for chaining, never null.
+     */
+    public FilterManager removeFilters(Collection<Filter> filters){
+        Objects.requireNonNull(filters);
+        this.filters.removeAll(filters);
+        return this;
+    }
+
+    /**
+     * Add all registered (default) property filters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    public FilterManager addDefaultFilters() {
+        for(Filter pf: ServiceContextManager.getServiceContext().getServices(Filter.class, classloader)){
+            addFilter(pf);
+        }
+        return this;
+    }
+
+    public FilterManager sortFilter(Comparator<Filter> comparator) {
+        Collections.sort(filters, comparator);
+        return this;
+    }
+
+    /**
+     * Removes all contained items.
+     * @return this instance for chaining.
+     */
+    public FilterManager clear() {
+        this.filters.clear();
+        return this;
+    }
+
+    /**
+     * Filters a single value.
+     * @param value the raw value, not {@code null}.
+     * @return the filtered value, including {@code null}.
+     */
+    public ConfigValue filterValue(ConfigValue value) {
+        FilterContext filterContext = new FilterContext(value, null);
+        return filterValue(filterContext);
+    }
+
+    /**
+     * Filters a single value.
+     * @param value the raw value, not {@code null}.
+     * @param config the config
+     * @return the filtered value, including {@code null}.
+     */
+    public ConfigValue filterValue(ConfigValue value, Config config) {
+        FilterContext filterContext = new FilterContext(value, config);
+        return filterValue(filterContext);
+    }
+
+    /**
+     * Filters all properties.
+     * @param rawProperties the unfiltered properties, not {@code null}.
+     * @param config the config
+     * @return the filtered value, inclusing null.
+     */
+    public Map<String, String> applyFilters(Map<String, String> rawProperties, Config config) {
+        Map<String, String> result = new HashMap<>();
+        // Apply filters to values, prevent values filtered to null!
+        for (Map.Entry<String, String> entry : rawProperties.entrySet()) {
+            FilterContext filterContext = new FilterContext(ConfigValue.of(entry.getKey(), rawProperties), config);
+            ConfigValue filtered = filterValue(filterContext);
+            if(filtered!=null){
+                result.putAll(filtered.asMap());
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Basic filter logic.
+     * @param context the filter context, not {@code null}.
+     * @return the filtered value.
+     */
+    private ConfigValue filterValue(FilterContext context) {
+        ConfigValue inputValue = context.getProperty();
+        ConfigValue filteredValue = inputValue;
+        for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
+            int changes = 0;
+            for (Filter filter :filters) {
+                filteredValue = filter.filterProperty(inputValue);
+                if (filteredValue != null && !filteredValue.equals(inputValue)) {
+                    changes++;
+                    LOG.finest("Filter - " + inputValue + " -> " + filteredValue + " by " + filter);
+                }
+                if(filteredValue==null){
+                    LOG.finest("Filter removed entry - " + inputValue + ": " + filter);
+                    break;
+                }else{
+                    inputValue = filteredValue;
+                }
+            }
+            if (changes == 0) {
+                LOG.finest("Finishing filter loop, no changes detected.");
+                break;
+            } else if (filteredValue == null) {
+                break;
+            } else {
+                if (i == (MAX_FILTER_LOOPS - 1)) {
+                    if (LOG.isLoggable(Level.WARNING)) {
+                        LOG.warning("Maximal filter loop count reached, aborting filter evaluation after cycles: " + i);
+                    }
+                } else {
+                    LOG.finest("Repeating filter loop, changes detected: " + changes);
+                }
+            }
+        }
+        return filteredValue;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append("Filters\n");
+        b.append("-------\n");
+        if(filters.isEmpty()){
+            b.append("  No filters loaded.\n\n");
+        }else {
+            b.append("  CLASS                         INFO\n\n");
+            for (Filter filter : filters) {
+                b.append("  ");
+                FormatUtils.appendFormatted(b, filter.getClass().getSimpleName(), 30);
+                b.append(FormatUtils.removeNewLines(filter.toString()));
+                b.append('\n');
+            }
+            b.append("\n");
+        }
+        return b.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/filter/package-info.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/filter/package-info.java b/code/base/src/main/java/org/apache/tamaya/base/filter/package-info.java
new file mode 100644
index 0000000..7880500
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/filter/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Default implementations for filter management and evaluation.
+ */
+package org.apache.tamaya.base.filter;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/package-info.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/base/package-info.java b/code/base/src/main/java/org/apache/tamaya/base/package-info.java
new file mode 100644
index 0000000..820476e
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Default implementations for config and related artifacts.
+ */
+package org.apache.tamaya.base;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/ConfigContext.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/ConfigContext.java b/code/base/src/main/java/org/apache/tamaya/spi/ConfigContext.java
new file mode 100644
index 0000000..7c77e12
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/ConfigContext.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import javax.config.spi.ConfigSource;
+import javax.config.spi.Converter;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Central SPI for programmatically dealing with the setup of the configuration system.
+ * This includes adding and enlisting {@link javax.config.spi.ConfigSource}s,
+ * managing {@link javax.config.spi.Converter}s, ConfigFilters, etc.
+ */
+public interface ConfigContext {
+
+    /**
+     * This method returns the current list of registered PropertySources ordered via their ordinal.
+     * PropertySources with a lower ordinal come last. The PropertySource with the
+     * highest ordinal comes first.
+     * If two PropertySources have the same ordinal number they will get sorted
+     * using their class name just to ensure the user at least gets the same ordering
+     * after a JVM restart, hereby names before are added last.
+     * PropertySources are loaded when this method is called the first time, which basically is
+     * when the first time configuration is accessed.
+     *
+     * @return a sorted list of registered PropertySources.  The returned list need not be modifiable
+     */
+    List<ConfigSource> getSources();
+
+//    /**
+//     * Access a {@link ConfigSource} using its (unique) name.
+//     * @param name the propoerty source's name, not {@code null}.
+//     * @return the propoerty source found, or {@code null}.
+//     */
+//    default ConfigSource getSource(String name) {
+//        for(ConfigSource ps: getSources()){
+//            if(name.equals(ps.getName())){
+//                return ps;
+//            }
+//        }
+//        return null;
+//    }
+
+    /**
+     * Access the current PropertyFilter instances.
+     * @return the list of registered PropertyFilters, never null.
+     */
+    List<Filter> getFilters();
+
+    /**
+     * <p>
+     * This method returns the Map of registered PropertyConverters
+     * per type.
+     * The List for each type is ordered via their {@link javax.annotation.Priority} and
+     * cladd name.
+     * </p>
+     *
+     * <p>A simplified scenario could be like:</p>
+     * <pre>
+     *  {
+     *      Date.class -&gt; {StandardDateConverter, TimezoneDateConverter, MyCustomDateConverter }
+     *      Boolean.class -&gt; {StandardBooleanConverter, FrenchBooleanConverter}
+     *      Integer.class -&gt; {DynamicDefaultConverter}
+     *  }
+     * </pre>
+     *
+     * @return map with sorted list of registered PropertySources per type.
+     */
+    Map<Type, List<Converter>> getConverters();
+
+    /**
+     * <p>
+     * This method returns the registered PropertyConverters for a given type.
+     * The List for each type is ordered via their {@link javax.annotation.Priority}.
+     * </p>
+     *
+     * <p>
+     * PropertyConverters with a higher Priority come first. The PropertyConverter with the
+     * lowest Priority comes last.
+     * If two PropertyConverter have the same ordinal number they will get sorted
+     * using their class name just to ensure the user at least gets the same ordering
+     * after a JVM restart.
+     * </p>
+     *
+     * <p>
+     * Additionally if a PropertyProvider is accessed, which is not registered the implementation
+     * should try to figure out, if there could be a default implementation as follows:</p>
+     * <ol>
+     *     <li>Look for static factory methods: {@code of(String), valueOf(String), getInstance(String),
+     *     instanceOf(String), fomr(String)}</li>
+     *     <li>Look for a matching constructor: {@code T(String)}.</li>
+     * </ol>
+     *
+     * <p>
+     * If a correspoding factory method or constructor could be found, a corresponding
+     * PropertyConverter should be created and registered automatically for the given
+     * type.
+     * </p>
+     *
+     * <p> The scenario could be like:</p>
+     *
+     * <pre>
+     *  {
+     *      Date.class -&gt; {MyCustomDateConverter,StandardDateConverter, TimezoneDateConverter}
+     *      Boolean.class -&gt; {StandardBooleanConverter, FrenchBooleanConverter}
+     *      Integer.class -&gt; {DynamicDefaultConverter}
+     *  }
+     * </pre>
+     *
+     * <p>
+     * The converters returned for a type should be used as a chain, whereas the result of the
+     * first converters that is able to convert the configured value, is taken as the chain's result.
+     * No more converters are called after a converters has successfully converted the input into
+     * the required target type.
+     * </p>
+     *
+     * @param type type of the desired converters
+     * @return a sorted list of registered PropertySources per type, or null.
+     */
+    default List<Converter> getConverters(Type type){
+        return Optional.ofNullable(getConverters().get(type)).orElse(Collections.emptyList());
+    }
+
+    /**
+     * Access the {@link ConfigValueCombinationPolicy} used to evaluate the final
+     * property values.
+     * @return the {@link ConfigValueCombinationPolicy} used, never null.
+     */
+    default ConfigValueCombinationPolicy getConfigValueCombinationPolicy(){
+        return ConfigValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/ConfigValue.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/ConfigValue.java b/code/base/src/main/java/org/apache/tamaya/spi/ConfigValue.java
new file mode 100644
index 0000000..fedcef5
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/ConfigValue.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Class modelling the result of a request for a property value. A property value is basically identified by its key.
+ * There might be reasons, where one want to further analyze, which PropertySources provided a value and which not, so
+ * it is possible to create a PropertyValue with a null value. Nevertheless in all cases the provider source (typically
+ * the name of the PropertySource) must be set.
+ */
+public final class ConfigValue implements Serializable{
+    private static final long serialVersionUID = 1L;
+    /** The requested key. */
+    private String key;
+    /** The value. */
+    private String value;
+    /** Additional metadata provided by the provider. */
+    private String metaEntry;
+
+    ConfigValue(ConfigValueBuilder builder){
+        this.key = Objects.requireNonNull(builder.key);
+        this.value = Objects.requireNonNull(builder.value);
+        this.metaEntry = builder.metaEntry;
+    }
+
+    /**
+     * Creates a new instance
+     * @param key the key, not {@code null}.
+     * @param value the value, not {@code null}.
+     * @param metaEntry the source, typically the name of the {@link javax.config.spi.ConfigSource} providing
+     *               the value, not {@code null}.
+     */
+    private ConfigValue(String key, String value, String metaEntry){
+        this.key = Objects.requireNonNull(key, "Key is required.");
+        this.value = Objects.requireNonNull(value, "Value is required.");
+        this.metaEntry = metaEntry;
+    }
+
+    /**
+     * The requested key.
+     * @return the, key never {@code null}.
+     */
+    public String getKey() {
+        return key;
+    }
+
+    /**
+     * The value.
+     * @return the value, in case a value is null it is valid to return {#code null} as result for
+     * {@link javax.config.spi.ConfigSource#getValue(String)}}.
+     */
+    public String getValue() {
+        return this.value;
+    }
+
+    /**
+     * Creates a full configuration map for this key, value pair and all its meta context data. This map
+     * is also used for subsequent processing, like value filtering.
+     * @return the property value entry map.
+     */
+    public String getMetaEntry() {
+        return metaEntry;
+    }
+
+    /**
+     * Creates a new builder instance.
+     * @param key the key, not {@code null}.
+     * @return a new builder instance.
+     */
+    public static ConfigValueBuilder builder(String key){
+        Objects.requireNonNull(key, "Key must be given.");
+        return new ConfigValueBuilder(key);
+    }
+
+    /**
+     * Creates a new builder instance.
+     * @param key the key, not {@code null}.
+     * @param value the property value, not {@code null}.
+     * @return a new builder instance.
+     */
+    public static ConfigValueBuilder builder(String key, String value) {
+        Objects.requireNonNull(key, "Key must be given.");
+        Objects.requireNonNull(value, "Value must be given");
+        return new ConfigValueBuilder(key, value);
+    }
+
+
+    /**
+     * Creates a new PropertyValue without any metadata..
+     * @param key the key, not {@code null}.
+     * @param value the value.
+     * @param metaEntry the metaEntry, typically the name of the {@link javax.config.spi.ConfigSource}
+     *               providing the value, not  {@code null}.
+     * @return a new property value instance, or {@code null},
+     *         if the value passed is {@code null}..
+     */
+    public static ConfigValue of(String key, String value, String metaEntry) {
+        if (value==null) {
+            return null;
+        }
+        return new ConfigValue(key, value, metaEntry);
+    }
+
+    /**
+     * Creates a new builder instance based on this item.
+     * @return a new builder, never null.
+     */
+    public ConfigValueBuilder toBuilder() {
+        return new ConfigValueBuilder(this.getKey())
+                .setValue(this.getValue())
+        .setMetaEntry(this.metaEntry);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ConfigValue)) return false;
+        ConfigValue that = (ConfigValue) o;
+        return Objects.equals(getKey(), that.getKey()) &&
+                Objects.equals(getValue(), that.getValue()) &&
+                Objects.equals(getMetaEntry(), that.getMetaEntry());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getKey(), getValue(),
+                getMetaEntry());
+    }
+
+    @Override
+    public String toString() {
+        return "PropertyValue{" +
+                "key='" + key + '\'' +
+                ", value='" + value + '\'' +
+                ", metaEntry='" + metaEntry + '\'' +
+                '}';
+    }
+
+    /**
+     * Maps a map of {@code Map<String,String>} to a {@code Map<String,PropertyValue>}.
+     * @param config the String based map, not {@code null}.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,ConfigValue> map(Map<String, String> config) {
+        Map<String,ConfigValue> result = new HashMap<>(config.size());
+        for(Map.Entry<String,String> en:config.entrySet()){
+            result.put(en.getKey(), ConfigValue.of(en.getKey(), en.getValue(), config.get(en.getKey()+"[meta]")));
+        }
+        return result;
+    }
+
+    /**
+     * Maps a map of {@code Map<String,String>} to a {@code Map<String,PropertyValue>}.
+     *
+     * @param config the String based map, not {@code null}.
+     * @param source the source name, not {@code null}.
+     * @param metaData additional metadata, not {@code null}.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,ConfigValue> map(Map<String, String> config, String source,
+                                              Map<String,String> metaData) {
+        Objects.requireNonNull(config, "Config must be given.");
+        Objects.requireNonNull(source, "Source must be given.");
+        Objects.requireNonNull(metaData, "Meta data must be given.");
+
+        Map<String,ConfigValue> result = new HashMap<>(config.size());
+
+        for(Map.Entry<String,String> en:config.entrySet()){
+            ConfigValue value = new ConfigValueBuilder(en.getKey(), source).setValue(en.getValue())
+                                                                               .addMetaEntries(metaData).build();
+            result.put(en.getKey(), value);
+        }
+        return result;
+    }
+
+    public Map<? extends String, ? extends String> asMap() {
+        Map<String,String> map = new HashMap<>();
+        map.put(key, value);
+        map.put(key+"[meta]", this.metaEntry);
+        return map;
+    }
+
+    public static ConfigValue of(String key, Map<String, String> rawProperties) {
+        String value = rawProperties.get(key);
+        String meta = rawProperties.get(key+"[meta]");
+        return new ConfigValue(key, value, meta);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/ConfigValueBuilder.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/ConfigValueBuilder.java b/code/base/src/main/java/org/apache/tamaya/spi/ConfigValueBuilder.java
new file mode 100644
index 0000000..d1c2d60
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/ConfigValueBuilder.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.*;
+
+/**
+ * Builder to create a {@link ConfigValue} instance.
+ */
+public class ConfigValueBuilder {
+    /** The key accessed. */
+    String key;
+    /** The property value. */
+    String value;
+    /** additional metadata entries (optional). */
+    String metaEntry;
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
+     * Before calling build at least a {@link #value} and its {@link #metaEntry}
+     * must be set.
+     */
+    ConfigValueBuilder(String key){
+        this.key = Objects.requireNonNull(key);
+    }
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
+     * @param key to access a property value, not  {@code null}.
+     * @param value property value.
+     */
+    ConfigValueBuilder(String key, String value) {
+        this.key = Objects.requireNonNull(key);
+        this.value = Objects.requireNonNull(value);
+    }
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
+     *
+     * @param key to access a property value.
+     * @param value the value, not {@code null}. If a value is  {@code null}
+     *              {@link javax.config.spi.ConfigSource#getValue(String)} should return {@code null}.
+     * @param metaEntry property metaEntry.
+     */
+    ConfigValueBuilder(String key, String value, String metaEntry) {
+        this.key = Objects.requireNonNull(key);
+        this.value = value;
+        this.metaEntry = Objects.requireNonNull(metaEntry);
+    }
+
+    /**
+     * Replaces/sets the context data.
+     * @param metaEntry the context data to be applied.
+     * @return the builder for chaining.
+     */
+    public ConfigValueBuilder setMetaEntry(String metaEntry) {
+        this.metaEntry = metaEntry;
+        return this;
+    }
+
+    /**
+     * Add an additional context data information.
+     * @param key the context data key, not {@code null}.
+     * @param value the context value, not {@code null} (will be converted to String).
+     * @return the builder for chaining.
+     */
+    public ConfigValueBuilder addMetaEntry(String key, String value) {
+        Objects.requireNonNull(key, "Meta key must be given.");
+        Objects.requireNonNull(value, "Meta value must be given.");
+        if(metaEntry==null){
+            metaEntry = key+"="+value;
+        }else{
+            metaEntry = "\n" + key+"="+value;
+        }
+        return this;
+    }
+
+    /**
+     * Adds the context data given.
+     * @param metaEntries the context data to be applied, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public ConfigValueBuilder addMetaEntries(Map<String, String> metaEntries) {
+        Properties props = new Properties();
+        props.putAll(metaEntries);
+        StringWriter stringWriter = new StringWriter();
+        try {
+            props.store(stringWriter, null);
+            stringWriter.flush();
+            if(metaEntry==null){
+                metaEntry = stringWriter.toString();
+            }else{
+                metaEntry += '\n' + stringWriter.toString();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return this;
+    }
+
+    /**
+     * Adds the context data given as JSON object.
+     * @param meta the context data in JSON format, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public ConfigValueBuilder addMetaEntry(String meta) {
+        if(metaEntry==null){
+            metaEntry = meta;
+        }else{
+            metaEntry += '\n' + meta;
+        }
+        return this;
+    }
+
+    /**
+     * Get the value's context data.
+     * @return the context data, not {@code null}.
+     */
+    public String getMetaEntry() {
+        return metaEntry;
+    }
+
+    /**
+     * Sets a new key.
+     * @param key the new key, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public ConfigValueBuilder setKey(String key) {
+        this.key = Objects.requireNonNull(key);
+        return this;
+    }
+
+    /**
+     * Sets a new value.
+     * @param value the new value, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public ConfigValueBuilder setValue(String value) {
+        this.value = Objects.requireNonNull(value, "Value must be given.");
+
+        return this;
+    }
+
+    /**
+     * Creates a new immutable {@link ConfigValue}.
+     * @return a new immutable {@link ConfigValue}, never {@code null}.
+     */
+    public ConfigValue build(){
+        return new ConfigValue(this);
+    }
+
+    @Override
+    public String toString() {
+        return "PropertyValueBuilder{" +
+                "key='" + key + '\'' +
+                "value='" + value + '\'' +
+                ", metaEntry=" + metaEntry +
+                '}';
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/Experimental.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/Experimental.java b/code/base/src/main/java/org/apache/tamaya/spi/Experimental.java
new file mode 100644
index 0000000..9831820
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/Experimental.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.lang.annotation.*;
+
+/**
+ * This is a simple annotation for flaging out functionality or features the Tamaya team is not sure if it is already
+ * stabilized, so use it with some caution.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD,
+        ElementType.TYPE})
+public @interface Experimental {
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/Filter.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/Filter.java b/code/base/src/main/java/org/apache/tamaya/spi/Filter.java
new file mode 100644
index 0000000..9fdad86
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/Filter.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+
+/**
+ * <p>Interface for filtering the current map of properties during the evaluation of the chain of PropertySources.
+ * Filters can be registered using the {@link org.apache.tamaya.spi.ServiceContext}. The ordinal
+ * hereby is defined by the corresponding {@code @Priority} annotation.</p>
+ * <p>Filters </p>
+ */
+@FunctionalInterface
+public interface Filter {
+
+    /**
+     * <p>Maps the current {@code valueToBeFiltered} value to a new value. The resulting value will be used as the result
+     * passed to the user.</p>
+     * <p>If a filter is currently not available, it should just pass the input map to the method's
+     * output.</p>
+     * <p>Returning {@code null} will remove the entry.</p>
+     * <h3>Implementation specification</h3>
+     * Implementations of this class must be
+     * <ul>
+     *     <li>reentrant</li>
+     *     <li>thread-safe</li>
+     * </ul>
+     * @param value the value to be filtered, which also can be {@code null} if removed by another filter.
+     * @return the filtered value, or {@code null} if the value should be removed alltogether.
+     * @see ConfigValue
+     * @see ConfigValueBuilder
+     */
+    ConfigValue filterProperty(ConfigValue value);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/ServiceContext.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/ServiceContext.java b/code/base/src/main/java/org/apache/tamaya/spi/ServiceContext.java
new file mode 100644
index 0000000..ff0bb9f
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/ServiceContext.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.List;
+
+
+/**
+ * This class models the component that is managing the lifecycle current the
+ * services used by the Configuration API.
+ */
+public interface ServiceContext {
+
+    /**
+     * @return ordinal of the ServiceContext. The one with the highest ordinal will be taken.
+     */
+    int ordinal();
+
+    static ClassLoader defaultClassLoader(){
+        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
+        if(classloader==null){
+            classloader = ServiceContextManager.class.getClassLoader();
+        }
+        return classloader;
+    }
+
+    /**
+     * Access a service singleton via its type.
+     * If multiple implementations for the very serviceType exist then
+     * the one with the highest {@link javax.annotation.Priority} will be used.
+     *
+     * @param <T> the type of the service type.
+     * @param serviceType the service type.
+     * @return The instance to be used, or {@code null}
+     * @throws IllegalArgumentException if there are multiple service implementations with the maximum priority.
+     */
+    default <T> T getService(Class<T> serviceType){
+        return getService(serviceType, defaultClassLoader());
+    }
+
+    /**
+     * Access a service singleton via its type.
+     * If multiple implementations for the very serviceType exist then
+     * the one with the highest {@link javax.annotation.Priority} will be used.
+     *
+     * @param <T> the type of the service type.
+     * @param serviceType the service type.
+     * @param classLoader the class loader to be considered.
+     * @return The instance to be used, or {@code null}
+     * @throws IllegalArgumentException if there are multiple service implementations with the maximum priority.
+     */
+    <T> T getService(Class<T> serviceType, ClassLoader classLoader);
+
+    /**
+     * Factory method to create a type, hereby a new instance is created on each access.
+     * If multiple implementations for the very serviceType exist then
+     * the one with the highest {@link javax.annotation.Priority} will be used as the base
+     * for creating subsequent instances.
+     *
+     * @param <T> the type of the service type.
+     * @param serviceType the service type.
+     * @return The new instance to be used, or {@code null}
+     * @throws IllegalArgumentException if there are multiple service implementations with the maximum priority.
+     */
+    default <T> T create(Class<T> serviceType){
+        return create(serviceType, defaultClassLoader());
+    }
+
+    /**
+     * Factory method to create a type, hereby a new instance is created on each access.
+     * If multiple implementations for the very serviceType exist then
+     * the one with the highest {@link javax.annotation.Priority} will be used as the base
+     * for creating subsequent instances.
+     *
+     * @param <T> the type of the service type.
+     * @param serviceType the service type.
+     * @param classLoader the class loader to be considered.
+     * @return The new instance to be used, or {@code null}
+     * @throws IllegalArgumentException if there are multiple service implementations with the maximum priority.
+     */
+    <T> T create(Class<T> serviceType, ClassLoader classLoader);
+
+
+    /**
+     * Access a list current services, given its type. The bootstrap mechanism should
+     * order the instance for precedence, hereby the most significant should be
+     * first in order.
+     *
+     * @param serviceType
+     *            the service type.
+     * @param <T> the type of the list element returned by this method
+     * @return The instance to be used, never {@code null}
+     */
+     default <T> List<T> getServices(Class<T> serviceType){
+         return getServices(serviceType, defaultClassLoader());
+     }
+
+    /**
+     * Access a list current services, given its type. The bootstrap mechanism should
+     * order the instance for precedence, hereby the most significant should be
+     * first in order.
+     *
+     * @param serviceType
+     *            the service type.
+     * @param <T> the type of the list element returned by this method
+     * @return The instance to be used, never {@code null}
+     */
+    <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader);
+
+    /**
+     * Loads resources from the current runtime context. This method allows to use runtime
+     * specific code to load resources, e.g. within OSGI environments.
+     * @param resource the resource, not {@code null}.
+     * @param cl the desired classloader context, if null, the current thread context classloader is used.
+     * @return the resources found
+     * @throws IOException if load fails.
+     */
+    Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException;
+
+    /**
+     * Loads a resource from the current runtime context. This method allows to use runtime
+     * specific code to load a resource, e.g. within OSGI environments.
+     * @param resource the resource, not {@code null}.
+     * @param cl the desired classloader context, if null, the current thread context classloader is used.
+     * @return the resource found, or {@code null}.
+     */
+    URL getResource(String resource, ClassLoader cl);
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java b/code/base/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
new file mode 100644
index 0000000..ddfd425
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.util.Objects;
+import java.util.ServiceLoader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * This singleton provides access to the services available in the current {@link ServiceContext}. The
+ * behaviour can be adapted, by calling {@link ServiceContextManager#set(ServiceContext)} before accessing any
+ * services.
+ */
+public final class ServiceContextManager {
+
+    /**
+     * The logger used.
+     */
+    private static final Logger LOG = Logger.getLogger(ServiceContextManager.class.getName());
+
+    /**
+     * The ServiceProvider used.
+     */
+    private static volatile ServiceContext serviceContextProviderDelegate;
+
+    /**
+     * Private singletons constructor.
+     */
+    private ServiceContextManager() {
+    }
+
+    /**
+     * Load the {@link ServiceContext} to be used.
+     *
+     * @return {@link ServiceContext} to be used for loading the services.
+     */
+    private static ServiceContext loadDefaultServiceProvider() {
+        ServiceContext highestServiceContext = null;
+        try {
+            int highestOrdinal = 0;
+            for (ServiceContext serviceContext : ServiceLoader.load(ServiceContext.class)) {
+                if (highestServiceContext == null) {
+                    highestServiceContext = serviceContext;
+                } else if (serviceContext.ordinal() > highestOrdinal) {
+                    highestServiceContext = serviceContext;
+                    highestOrdinal = serviceContext.ordinal();
+                }
+            }
+        } catch (Exception e) {
+            throw new IllegalStateException("ServiceContext not loadable", e);
+        }
+        if (highestServiceContext == null) {
+            throw new IllegalStateException("No ServiceContext found");
+        }
+        LOG.info("Using Service Context of type: " + highestServiceContext.getClass().getName());
+        return highestServiceContext;
+    }
+
+    /**
+     * Replace the current {@link ServiceContext} in use.
+     *
+     * @param serviceContextProvider the new {@link ServiceContext}, not {@code null}.
+     * @return the currently used context after setting it.
+     */
+    public static ServiceContext set(ServiceContext serviceContextProvider) {
+        Objects.requireNonNull(serviceContextProvider);
+        ServiceContext currentContext = ServiceContextManager.serviceContextProviderDelegate;
+
+        synchronized (ServiceContextManager.class) {
+            if (ServiceContextManager.serviceContextProviderDelegate == null) {
+                ServiceContextManager.serviceContextProviderDelegate = serviceContextProvider;
+                LOG.log(Level.INFO, "Using ServiceProvider: " + serviceContextProvider.getClass().getName());
+            } else {
+                LOG.log(Level.WARNING, "Replacing ServiceProvider " +
+                        ServiceContextManager.serviceContextProviderDelegate.getClass().getName() +
+                        " with: " + serviceContextProvider.getClass().getName());
+                ServiceContextManager.serviceContextProviderDelegate = serviceContextProvider;
+            }
+        }
+
+        return currentContext;
+    }
+
+    /**
+     * Ge {@link ServiceContext}. If necessary the {@link ServiceContext} will be laziliy loaded.
+     *
+     * @return the {@link ServiceContext} used.
+     */
+    public static ServiceContext getServiceContext(){
+        if (serviceContextProviderDelegate == null) {
+            synchronized (ServiceContextManager.class) {
+                if (serviceContextProviderDelegate == null) {
+                    serviceContextProviderDelegate = loadDefaultServiceProvider();
+                }
+            }
+        }
+        return serviceContextProviderDelegate;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/StandaloneConfigContextBuilder.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/StandaloneConfigContextBuilder.java b/code/base/src/main/java/org/apache/tamaya/spi/StandaloneConfigContextBuilder.java
new file mode 100644
index 0000000..f8cd841
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/StandaloneConfigContextBuilder.java
@@ -0,0 +1,407 @@
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one
+// *  or more contributor license agreements.  See the NOTICE file
+// *  distributed with this work for additional information
+// *  regarding copyright ownership.  The ASF licenses this file
+// *  to you under the Apache License, Version 2.0 (the
+// *  "License"); you may not use this file except in compliance
+// *  with the License.  You may obtain a copy of the License at
+// *
+// *     http://www.apache.org/licenses/LICENSE-2.0
+// *
+// *  Unless required by applicable law or agreed to in writing,
+// *  software distributed under the License is distributed on an
+// *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// *  KIND, either express or implied.  See the License for the
+// *  specific language governing permissions and limitations
+// *  under the License.
+// */
+//package org.apache.tamaya.spi;
+//
+//import org.apache.tamaya.base.configsource.ConfigSourceComparator;
+//import org.apache.tamaya.base.configsource.CLIConfigSource;
+//import org.apache.tamaya.base.configsource.EnvironmentConfigSource;
+//import org.apache.tamaya.base.configsource.JavaConfigurationConfigSource;
+//import org.apache.tamaya.base.configsource.SystemConfigSource;
+//
+//import javax.config.spi.ConfigSource;
+//import javax.config.spi.ConfigSourceProvider;
+//import javax.config.spi.Converter;
+//import java.lang.reflect.ParameterizedType;
+//import java.lang.reflect.Type;
+//import java.util.*;
+//import java.util.logging.Logger;
+//
+///**
+// * Default implementation of {@link StandaloneConfigContextBuilder}.
+// */
+//public final class StandaloneConfigContextBuilder {
+//
+//    private static final Logger LOG = Logger.getLogger(StandaloneConfigContextBuilder.class.getName());
+//
+//    protected List<Filter> filters = new ArrayList<>();
+//    protected List<ConfigSource> propertySources = new ArrayList<>();
+//    protected ConfigValueCombinationPolicy combinationPolicy = ConfigValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY;
+//    protected Map<Type, Collection<Converter>> propertyConverters = new HashMap<>();
+//
+//    /**
+//     * Flag if the config has already been built.
+//     * Configuration can be built only once
+//     */
+//    private boolean built;
+//    private ClassLoader classLoader;
+//
+//    /**
+//     * Creates a new builder instance.
+//     */
+//    public StandaloneConfigContextBuilder() {
+//    }
+//
+//    /**
+//     * Creates a new builder instance initializing it with the given context.
+//     * @param context the context to be used, not null.
+//     */
+//    public StandaloneConfigContextBuilder(ConfigContext context) {
+//        this.propertyConverters.putAll(context.getConverters());
+//        this.filters.addAll(context.getFilters());
+//        for(ConfigSource ps:context.getSources()) {
+//            withSources(ps);
+//        }
+//        this.combinationPolicy = context.getConfigValueCombinationPolicy();
+//    }
+//
+//    /**
+//     * Allows to reset configuration context during unit tests.
+//     */
+//    public final StandaloneConfigContextBuilder reset() {
+//        checkBuilderState();
+//        this.filters.clear();
+//        this.propertySources.clear();
+//        this.propertyConverters.clear();
+//        this.combinationPolicy = ConfigValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY;
+//        return this;
+//    }
+//
+//
+//    public StandaloneConfigContextBuilder withContext(ConfigContext context) {
+//        checkBuilderState();
+//        this.propertyConverters.putAll(context.getConverters());
+//        for(ConfigSource ps:context.getSources()){
+//            this.propertySources.add(ps);
+//        }
+//        this.filters.addAll(context.getFilters());
+//        this.combinationPolicy = context.getConfigValueCombinationPolicy();
+//        return this;
+//    }
+//
+//    public final StandaloneConfigContextBuilder withSources(ConfigSource... sources){
+//        return withSources(Arrays.asList(sources));
+//    }
+//
+//    public StandaloneConfigContextBuilder withSources(Collection<ConfigSource> sources){
+//        checkBuilderState();
+//        for(ConfigSource source:sources) {
+//            if (!this.propertySources.contains(source)) {
+//                this.propertySources.add(source);
+//            }
+//        }
+//        return this;
+//    }
+//
+//
+//    public StandaloneConfigContextBuilder addDiscoveredSources() {
+//        checkBuilderState();
+//        List<ConfigSource> propertySources = new ArrayList<>();
+////        addDiscoveredSources(propertySources);
+//        for(ConfigSource ps: ServiceContextManager.getServiceContext().getServices(ConfigSource.class, classLoader)) {
+//            if(!propertySources.contains(ps)){
+//                propertySources.add(ps);
+//            }
+//        }
+//
+//        for(ConfigSourceProvider provider:
+//                ServiceContextManager.getServiceContext().getServices(ConfigSourceProvider.class, classLoader)){
+//                for(ConfigSource src: provider.getConfigSources(classLoader)){
+//                    propertySources.add(src);
+//                }
+//        }
+//        Collections.sort(propertySources, ConfigSourceComparator.getInstance());
+//        return withSources(propertySources);
+//    }
+//
+//    private StandaloneConfigContextBuilder addDiscoveredSources(List<ConfigSource> propertySources) {
+//        for(ConfigSource ps: new ConfigSource[]{
+//                new EnvironmentConfigSource(),
+//                new JavaConfigurationConfigSource(),
+//                new CLIConfigSource(),
+//                new SystemConfigSource()
+//        }){
+//            if(!propertySources.contains(ps)){
+//                propertySources.add(ps);
+//            }
+//        }
+//        return this;
+//    }
+//
+//    public StandaloneConfigContextBuilder addDiscoveredPropertyFilters() {
+//        checkBuilderState();
+//        for(Filter pf:ServiceContextManager.getServiceContext().getServices(Filter.class, classLoader)){
+//            withFilters(pf);
+//        }
+//        return this;
+//    }
+//
+//    public StandaloneConfigContextBuilder addDiscoveredConverters() {
+//        checkBuilderState();
+//        addDiscoveredConverters();
+//        for(Map.Entry<Type, Collection<Converter>> en: getDefaultConverters().entrySet()){
+//            for(Converter pc: en.getValue()) {
+//                withConverters(en.getKey(), pc);
+//            }
+//        }
+//        return this;
+//    }
+//
+//    @SuppressWarnings("unchecked")
+//    public void addDiscoveredConverters() {
+//        // should be overridden by subclasses.
+//    }
+//
+//    public final StandaloneConfigContextBuilder removeSources(ConfigSource... propertySources) {
+//        return removeSources(Arrays.asList(propertySources));
+//    }
+//
+//    public StandaloneConfigContextBuilder removeSources(Collection<ConfigSource> propertySources) {
+//        checkBuilderState();
+//        this.propertySources.removeAll(propertySources);
+//        return this;
+//    }
+//
+//    protected ConfigSource getSource(String name) {
+//        for(ConfigSource ps:propertySources){
+//            if(ps.getName().equals(name)){
+//                return ps;
+//            }
+//        }
+//        throw new IllegalArgumentException("No such PropertySource: "+name);
+//    }
+//
+//    public List<ConfigSource> getSources() {
+//        return Collections.unmodifiableList(this.propertySources);
+//    }
+//
+//    public StandaloneConfigContextBuilder increasePriority(ConfigSource propertySource) {
+//        checkBuilderState();
+//        int index = propertySources.indexOf(propertySource);
+//        if(index<0){
+//            throw new IllegalArgumentException("No such PropertySource: " + propertySource);
+//        }
+//        if(index<(propertySources.size()-1)){
+//            propertySources.remove(propertySource);
+//            propertySources.add(index+1, propertySource);
+//        }
+//        return this;
+//    }
+//
+//    public StandaloneConfigContextBuilder decreasePriority(ConfigSource propertySource) {
+//        checkBuilderState();
+//        int index = propertySources.indexOf(propertySource);
+//        if(index<0){
+//            throw new IllegalArgumentException("No such PropertySource: " + propertySource);
+//        }
+//        if(index>0){
+//            propertySources.remove(propertySource);
+//            propertySources.add(index-1, propertySource);
+//        }
+//        return this;
+//    }
+//
+//    public StandaloneConfigContextBuilder highestPriority(ConfigSource propertySource) {
+//        checkBuilderState();
+//        int index = propertySources.indexOf(propertySource);
+//        if(index<0){
+//            throw new IllegalArgumentException("No such PropertySource: " + propertySource);
+//        }
+//        if(index<(propertySources.size()-1)){
+//            propertySources.remove(propertySource);
+//            propertySources.add(propertySource);
+//        }
+//        return this;
+//    }
+//
+//    public StandaloneConfigContextBuilder lowestPriority(ConfigSource propertySource) {
+//        checkBuilderState();
+//        int index = propertySources.indexOf(propertySource);
+//        if(index<0){
+//            throw new IllegalArgumentException("No such PropertySource: " + propertySource);
+//        }
+//        if(index>0){
+//            propertySources.remove(propertySource);
+//            propertySources.add(0, propertySource);
+//        }
+//        return this;
+//    }
+//
+//    public final StandaloneConfigContextBuilder withFilters(Filter... filters){
+//        return withFilters(Arrays.asList(filters));
+//    }
+//
+//    public final StandaloneConfigContextBuilder withFilters(Collection<Filter> filters){
+//        checkBuilderState();
+//        for(Filter f:filters) {
+//            if (!this.filters.contains(f)) {
+//                this.filters.add(f);
+//            }
+//        }
+//        return this;
+//    }
+//
+//    public final StandaloneConfigContextBuilder removeFilters(Filter... filters) {
+//        return removeFilters(Arrays.asList(filters));
+//    }
+//
+//    public final StandaloneConfigContextBuilder removeFilters(Collection<Filter> filters) {
+//        checkBuilderState();
+//        this.filters.removeAll(filters);
+//        return this;
+//    }
+//
+//
+//    public final <T> StandaloneConfigContextBuilder removeConverters(Type typeToConvert,
+//                                                                     @SuppressWarnings("unchecked") Converter<T>... converters) {
+//        return removeConverters(typeToConvert, Arrays.asList(converters));
+//    }
+//
+//    public final <T> StandaloneConfigContextBuilder removeConverters(Type typeToConvert,
+//                                                                     Collection<Converter<T>> converters) {
+//        Collection<Converter> subConverters = this.propertyConverters.get(typeToConvert);
+//        if(subConverters!=null) {
+//            subConverters.removeAll(converters);
+//        }
+//        return this;
+//    }
+//
+//    public final StandaloneConfigContextBuilder removeConverters(TypeLiteral<?> typeToConvert) {
+//        this.propertyConverters.remove(typeToConvert);
+//        return this;
+//    }
+//
+//
+//    public final StandaloneConfigContextBuilder withPropertyValueCombinationPolicy(ConfigValueCombinationPolicy combinationPolicy){
+//        checkBuilderState();
+//        this.combinationPolicy = Objects.requireNonNull(combinationPolicy);
+//        return this;
+//    }
+//
+//
+//    public <T> StandaloneConfigContextBuilder withConverters(Type type, Converter<T>... propertyConverters){
+//        checkBuilderState();
+//        Objects.requireNonNull(type);
+//        Objects.requireNonNull(propertyConverters);
+//        Collection<Converter> converters = this.propertyConverters.get(type);
+//        if(converters==null){
+//            converters = new ArrayList<>();
+//            this.propertyConverters.put(type, converters);
+//        }
+//        for(Converter<T> propertyConverter:propertyConverters) {
+//            if (!converters.contains(propertyConverter)) {
+//                converters.add(propertyConverter);
+//            } else {
+//                LOG.warning("Converter ignored, already registered: " + propertyConverter);
+//            }
+//        }
+//        return this;
+//    }
+//
+//    public <T> StandaloneConfigContextBuilder withConverters(Type type, Collection<Converter<T>> propertyConverters){
+//        checkBuilderState();
+//        Objects.requireNonNull(type);
+//        Objects.requireNonNull(propertyConverters);
+//        Collection<Converter> converters = this.propertyConverters.get(type);
+//        if(converters==null){
+//            converters = new ArrayList<>();
+//            this.propertyConverters.put(type, converters);
+//        }
+//        for(Converter<T> propertyConverter:propertyConverters) {
+//            if (!converters.contains(propertyConverter)) {
+//                converters.add(propertyConverter);
+//            } else {
+//                LOG.warning("Converter ignored, already registered: " + propertyConverter);
+//            }
+//        }
+//        return this;
+//    }
+//
+//    protected StandaloneConfigContextBuilder loadDefaults() {
+//        checkBuilderState();
+//        this.combinationPolicy = ConfigValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+//        addDiscoveredSources();
+//        addDiscoveredPropertyFilters();
+//        addDiscoveredConverters();
+//        return this;
+//    }
+//
+//
+//    protected Map<Type, Collection<Converter>> getDefaultConverters() {
+//        Map<Type, Collection<Converter>> result = new HashMap<>();
+//        for (Converter conv : ServiceContextManager.getServiceContext().getServices(
+//                Converter.class, classLoader)) {
+//            for(Type type:conv.getClass().getGenericInterfaces()){
+//                if(type instanceof ParameterizedType){
+//                    ParameterizedType pt = (ParameterizedType)type;
+//                    if(Converter.class.equals(((ParameterizedType) type).getRawType())){
+//                        Type target = pt.getActualTypeArguments()[0];
+//                        Collection<Converter> convList = result.get(target);
+//                        if (convList == null) {
+//                            convList = new ArrayList<>();
+//                            result.put(target, convList);
+//                        }
+//                        convList.add(conv);
+//                    }
+//                }
+//            }
+//        }
+//        return result;
+//    }
+//
+//
+//    /**
+//     * Builds a new configuration based on the configuration of this builder instance.
+//     *
+//     * @return a new {@link javax.config.Config configuration instance},
+//     *         never {@code null}.
+//     */
+//    public ConfigContext build() {
+//        checkBuilderState();
+//        built = true;
+//        return new StandaloneConfigContext(this);
+//    }
+//
+//    public StandaloneConfigContextBuilder sortFilter(Comparator<Filter> comparator) {
+//        Collections.sort(filters, comparator);
+//        return this;
+//    }
+//
+//    public StandaloneConfigContextBuilder sortSources(Comparator<ConfigSource> comparator) {
+//        Collections.sort(propertySources, comparator);
+//        return this;
+//    }
+//
+//    private void checkBuilderState() {
+//        if (built) {
+//            throw new IllegalStateException("Configuration has already been build.");
+//        }
+//    }
+//
+//    public List<Filter> getFilters() {
+//        return filters;
+//    }
+//
+//    public Map<Type, Collection<Converter>> getConverter() {
+//        return Collections.unmodifiableMap(this.propertyConverters);
+//    }
+//
+//    public void setClassLoader(ClassLoader classLoader) {
+//        this.classLoader = classLoader;
+//    }
+//}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/TamayaConfigBuilder.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/TamayaConfigBuilder.java b/code/base/src/main/java/org/apache/tamaya/spi/TamayaConfigBuilder.java
new file mode 100644
index 0000000..e48a6bd
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/TamayaConfigBuilder.java
@@ -0,0 +1,333 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import org.apache.tamaya.base.DefaultConfigBuilder;
+
+import javax.config.spi.ConfigBuilder;
+import javax.config.spi.ConfigSource;
+import javax.config.spi.Converter;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A builder for creating new or adapting instances of {@link javax.config.Config}.
+ * Builders can be obtained in exactly two ways:
+ * <ol>
+ *     <li>By accessing an empty builder instance from
+ *     {@link javax.config.spi.ConfigProviderResolver#getBuilder()}.</li>
+ * </ol>
+ */
+public interface TamayaConfigBuilder extends ConfigBuilder, ConfigContextSupplier{
+
+    /**
+     * Create a new empty configuration builder.
+     * @return
+     */
+    static TamayaConfigBuilder create() {
+        return new DefaultConfigBuilder();
+    }
+
+    static TamayaConfigBuilder create(ConfigContextSupplier contextSupplier){
+        return new DefaultConfigBuilder(contextSupplier.getConfigContext());
+    }
+
+    static TamayaConfigBuilder from(ConfigBuilder configBuilder){
+        if(configBuilder instanceof TamayaConfigBuilder) {
+            return (TamayaConfigBuilder) configBuilder;
+        }else if(configBuilder instanceof ConfigContextSupplier){
+            return create((ConfigContextSupplier)configBuilder);
+        }
+        throw new IllegalArgumentException("Builder must implement ConfigContextSupplier.");
+    }
+
+    /**
+     * This method can be used for programmatically adding {@link ConfigSource}s.
+     * Hereby the property source is added to the tail of property sources with
+     * lowest priority regardless of its current ordinal value. To sort the property
+     * sources based on their ordinals call {@link #sortSources}.
+     *
+     * @param propertySources the PropertySources to add
+     * @return this builder, for chaining, never null.
+     * @throws IllegalArgumentException If a property source with a given name already
+     * exists.
+     */
+    TamayaConfigBuilder withSources(Collection<ConfigSource> propertySources);
+
+    /**
+     * Removes the given property sources, if existing. The existing order of property
+     * sources is preserved.
+     *
+     * @param propertySources the property sources to remove, not {@code null}.
+     * @return the builder for chaining.
+     */
+    TamayaConfigBuilder removeSources(ConfigSource... propertySources);
+
+    /**
+     * Removes the given property sources, if existing. The existing order of property
+     * sources is preserved.
+     *
+     * @param propertySources the property sources to remove, not {@code null}.
+     * @return the builder for chaining.
+     */
+    TamayaConfigBuilder removeSources(Collection<ConfigSource> propertySources);
+
+    /**
+     * Increases the priority of the given property source, by moving it towards the end
+     * of the chain of property sources. If the property source given is already at the end
+     * this method has no effect. This operation does not change any ordinal values.
+     *
+     * @param propertySource the property source to be incresed regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    TamayaConfigBuilder increasePriority(ConfigSource propertySource);
+
+    /**
+     * Decreases the priority of the given property source, by moving it towards the start
+     * of the chain of property sources. If the property source given is already the first
+     * this method has no effect. This operation does not change any ordinal values.
+     *
+     * @param propertySource the property source to be decresed regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    TamayaConfigBuilder decreasePriority(ConfigSource propertySource);
+
+    /**
+     * Increases the priority of the given property source to be maximal, by moving it to
+     * the tail of the of property source chain. If the property source given is
+     * already the last item this method has no effect. This operation does not change
+     * any ordinal values.
+     *
+     * @param propertySource the property source to be maximized regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    TamayaConfigBuilder highestPriority(ConfigSource propertySource);
+
+    /**
+     * Decreases the priority of the given property source to be minimal, by moving it to
+     * the start of the chain of property source chain. If the property source given is
+     * already the first item this method has no effect. This operation does not change
+     * any ordinal values.
+     *
+     * @param propertySource the property source to be minimized regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    TamayaConfigBuilder lowestPriority(ConfigSource propertySource);
+
+    /**
+     * Access the current chain of property sources. Items at the end of the list have
+     * precedence/more significance.
+     *
+     * @return the property source chain, never {@code null}.
+     */
+    List<ConfigSource> getSources();
+
+    /**
+     * Sorts the current registered property sources using the given comparator.
+     *
+     * NOTE: property sources at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not {@code null}.
+     * @return this instance for chaining.
+     */
+    TamayaConfigBuilder sortSources(Comparator<ConfigSource> comparator);
+
+    /**
+     * Adds the given PropertyFilter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the property
+     * filters call {@link #sortFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    TamayaConfigBuilder withFilters(Filter... filters);
+
+    /**
+     * Adds the given PropertyFilter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the property
+     * filters call {@link #sortFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    TamayaConfigBuilder withFilters(Collection<Filter> filters);
+
+    /**
+     * Add all registered (default) property filters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    TamayaConfigBuilder addDiscoveredFilters();
+
+    /**
+     * Removes the given PropertyFilter instances, if existing. The order of the remaining
+     * filters is preserved.
+     *
+     * @param filters the filter to remove
+     * @return this builder, for chaining, never null.
+     */
+    TamayaConfigBuilder removeFilters(Filter... filters);
+
+    /**
+     * Removes the given PropertyFilter instances, if existing. The order of the remaining
+     * filters is preserved.
+     *
+     * @param filters the filter to remove
+     * @return this builder, for chaining, never null.
+     */
+    TamayaConfigBuilder removeFilters(Collection<Filter> filters);
+
+    /**
+     * Access the current chain of property filters. Items at the end of the list have
+     * precedence/more significance.
+     *
+     * @return the property source chain, never {@code null}.
+     */
+    List<Filter> getFilters();
+
+    /**
+     * This method can be used for adding {@link Converter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param converters the converters to add for this type
+     * @return this builder, for chaining, never null.
+     */
+    TamayaConfigBuilder withConverters(Collection<Converter<?>> converters);
+
+    /**
+     * This method can be used for adding {@link Converter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converters is for
+     * @param converters the converters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> TamayaConfigBuilder withConverters(Class<T> typeToConvert, Converter<T>... converters);
+
+    /**
+     * This method can be used for adding {@link Converter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converters is for
+     * @param converters the converters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> TamayaConfigBuilder withConverters(Class<T> typeToConvert, Collection<Converter<T>> converters);
+
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param converters    the converters to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> TamayaConfigBuilder removeConverters(Class<T> typeToConvert, Converter<T>... converters);
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param converters    the converters to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> TamayaConfigBuilder removeConverters(Class<T> typeToConvert, Collection<Converter<T>> converters);
+
+    /**
+     * Removes all converters for the given type, which actually renders a given type
+     * unsupported for type conversion.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @return this builder, for chaining, never null.
+     */
+    <T> TamayaConfigBuilder removeConverters(Class<T> typeToConvert);
+
+    /**
+     * Access the current registered property converters.
+     *
+     * @return the current registered property converters.
+     */
+    Map<Type, List<Converter>> getConverter();
+
+    /**
+     * Sets the {@link ConfigValueCombinationPolicy} used to evaluate the final
+     * property values.
+     *
+     * @param policy the {@link ConfigValueCombinationPolicy} used, not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    TamayaConfigBuilder withPropertyValueCombinationPolicy(ConfigValueCombinationPolicy policy);
+
+    /**
+     * Sorts the current registered property filters using the given comparator.
+     *
+     * NOTE: property filters at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not {@code null}.
+     * @return this instance for chaining.
+     */
+    TamayaConfigBuilder sortFilter(Comparator<Filter> comparator);
+
+    @Override
+    TamayaConfigBuilder addDefaultSources();
+
+    @Override
+    TamayaConfigBuilder addDiscoveredSources();
+
+    @Override
+    TamayaConfigBuilder addDiscoveredConverters();
+
+    @Override
+    TamayaConfigBuilder forClassLoader(ClassLoader loader);
+
+    @Override
+    TamayaConfigBuilder withSources(ConfigSource... sources);
+
+    @Override
+    TamayaConfigBuilder withConverters(Converter<?>... converters);
+
+    @Override
+    <T> TamayaConfigBuilder withConverter(Class<T> type, Converter<T> converter);
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/spi/TypeLiteral.java
----------------------------------------------------------------------
diff --git a/code/base/src/main/java/org/apache/tamaya/spi/TypeLiteral.java b/code/base/src/main/java/org/apache/tamaya/spi/TypeLiteral.java
new file mode 100644
index 0000000..0139e85
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/spi/TypeLiteral.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.io.Serializable;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Objects;
+
+
+/**
+ * <p>Class for instantiation of objects that represent parameterized types
+ * with current parameters.</p>
+ *
+ * <p>An object that represents a parameterized type may be obtained by
+ * subclassing <tt>TypeLiteral</tt>.</p>
+ *
+ * <pre>
+ * TypeLiteral&lt;List&lt;Integer&gt;&gt; stringListType = new TypeLiteral&lt;List&lt;Integer&gt;&gt;() {};
+ * </pre>
+ *
+ * @param <T> the type, including all type parameters
+ */
+public class TypeLiteral<T> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private static final Type[] EMPTY_TYPE_ARRAY = new Type[0];
+    /** The current defined type. */
+    private final Type definedType;
+
+    /**
+     * Constructor.
+     * @param definedType the defined type.
+     */
+    public TypeLiteral(Type definedType) {
+        Objects.requireNonNull(definedType, "Type must be given");
+
+        this.definedType = definedType;
+    }
+
+    /**
+     * Constructor only for directly implemeting a TypeLiteral hereby dynamically implementing a generic interface.
+     */
+    public TypeLiteral() {
+        this.definedType = getDefinedType(this.getClass());
+    }
+
+    /**
+     * Creates a new TypeLiteral based on a given type.
+     *
+     * @param type the type , not {@code null}.
+     * @param <R>  the literal generic type.
+     * @return the corresponding TypeLiteral, never {@code null}.
+     */
+    public static <R> TypeLiteral<R> of(Type type) {
+        Objects.requireNonNull(type, "Type must be given.");
+
+        return new TypeLiteral<R>(type);
+    }
+
+    /**
+     * Checks the current implemented generic interfaces and evaluates the given single type parameter.
+     *
+     * @param clazz         the class to check, not  {@code null}.
+     * @param interfaceType the interface type to be checked, not {@code null}.
+     * @return the generic type parameters, or an empty array, if it cannot be evaluated.
+     */
+    public static Type[] getGenericInterfaceTypeParameters(Class<?> clazz, Class<?> interfaceType) {
+        Objects.requireNonNull(clazz, "Class parameter must be given.");
+        Objects.requireNonNull(interfaceType, "Interface parameter must be given.");
+
+        for (Type type : clazz.getGenericInterfaces()) {
+            if (type instanceof ParameterizedType) {
+                ParameterizedType parameterizedType = (ParameterizedType) type;
+                if(parameterizedType.getRawType().equals(interfaceType)){
+                    return parameterizedType.getActualTypeArguments();
+                }
+            }
+        }
+        return EMPTY_TYPE_ARRAY;
+    }
+
+    /**
+     * Method that checks the class's type for a generic interface implementation type.
+     *
+     * @param type         the type, not {@code null}.
+     * @return the generic type parameter of the given single type generic interfaceType, or an empty array.
+     */
+    public static Type[] getTypeParameters(Type type) {
+        Objects.requireNonNull(type, "Type must be given.");
+
+        if (type instanceof ParameterizedType) {
+            ParameterizedType parameterizedType = (ParameterizedType) type;
+            return parameterizedType.getActualTypeArguments();
+        }
+        return EMPTY_TYPE_ARRAY;
+    }
+
+    public final Type getType() {
+        return definedType;
+    }
+
+    /**
+     * Returns basic raw Java type.
+     *
+     * @return the actual type represented by this object
+     */
+    @SuppressWarnings("unchecked")
+	public final Class<T> getRawType() {
+        Class<T> rawType;
+
+        if (this.definedType instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) this.definedType;
+            rawType = (Class<T>) pt.getRawType();
+        } else if (this.definedType instanceof GenericArrayType) {
+            rawType = (Class<T>) Object[].class;
+        } else if (this.definedType instanceof Class) {
+            rawType = (Class<T>) this.definedType;
+        } else {
+            throw new RuntimeException("Illegal type for the Type Literal Class");
+        }
+
+        return rawType;
+    }
+
+    /**
+     * Returns actual type arguments, if present.
+     *
+     * @return the actual type represented by defined class, or an empty array.
+     */
+    public final Type[] getActualTypeArguments() {
+        if (this.definedType instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) this.definedType;
+            return pt.getActualTypeArguments();
+        }
+        return new Type[0];
+    }
+
+
+    protected Type getDefinedType(Class<?> clazz) {
+        Type type;
+
+        if (clazz == null) {
+            throw new RuntimeException("Class parameter clazz can not be null");
+        }
+
+        Type superClazz = clazz.getGenericSuperclass();
+
+        if (superClazz instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) superClazz;
+            Type[] actualArgs = pt.getActualTypeArguments();
+
+            if (actualArgs.length == 1) {
+                type = actualArgs[0];
+
+            } else {
+                throw new RuntimeException("More than one parametric type");
+            }
+
+        } else if (superClazz.equals(Object.class)) {
+            throw new RuntimeException("Super class must be parametrized type");
+        } else {
+            type = getDefinedType((Class<?>) superClazz);
+        }
+
+        return type;
+    }
+
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((definedType == null) ? 0 : definedType.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        TypeLiteral<?> other = (TypeLiteral<?>) obj;
+        if (definedType == null) {
+            if (other.definedType != null) {
+                return false;
+            }
+        } else if (!definedType.equals(other.definedType)) {
+            return false;
+        }
+        return true;
+    }
+
+
+    @Override
+    public String toString() {
+        return "TypeLiteral{" +
+                "type=" + definedType +
+                '}';
+    }
+
+}



[2/6] incubator-tamaya git commit: Added full JSR implementation.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/base/services/DefaultServiceContext.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/base/services/DefaultServiceContext.java b/code/base/src/test/java/org/apache/tamaya/base/services/DefaultServiceContext.java
new file mode 100644
index 0000000..3c91f12
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/base/services/DefaultServiceContext.java
@@ -0,0 +1,204 @@
+/*
+ * 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.base.services;
+
+import org.apache.tamaya.base.PriorityServiceComparator;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.io.IOException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link ServiceContext} interface and hereby uses the JDK
+ * {@link ServiceLoader} to load the services required.
+ */
+public final class DefaultServiceContext implements ServiceContext {
+    private static final Logger LOG = Logger.getLogger(DefaultServiceContext.class.getName());
+    /**
+     * List current services loaded, per class.
+     */
+    private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+    /**
+     * Singletons.
+     */
+    private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+    @SuppressWarnings("rawtypes")
+	private Map<Class, Class> factoryTypes = new ConcurrentHashMap<>();
+
+    @Override
+    public <T> T getService(Class<T> serviceType, ClassLoader cl) {
+        Object cached = singletons.get(serviceType);
+        if (cached == null) {
+            cached = create(serviceType);
+            if(cached!=null) {
+                singletons.put(serviceType, cached);
+            }
+        }
+        return serviceType.cast(cached);
+    }
+
+    @Override
+    public <T> T create(Class<T> serviceType, ClassLoader cl) {
+        @SuppressWarnings("unchecked")
+		Class<? extends T> implType = factoryTypes.get(serviceType);
+        if(implType==null) {
+            Collection<T> services = getServices(serviceType);
+            if (services.isEmpty()) {
+                return null;
+            } else {
+                return getServiceWithHighestPriority(services, serviceType);
+            }
+        }
+        try {
+            return implType.newInstance();
+        } catch (Exception e) {
+            LOG.log(Level.SEVERE, "Failed to create instance of " + implType.getName(), e);
+            return  null;
+        }
+    }
+
+    /**
+     * Loads and registers services.
+     *
+     * @param <T>         the concrete type.
+     * @param serviceType The service type.
+     * @return the items found, never {@code null}.
+     */
+    @Override
+    public <T> List<T> getServices(final Class<T> serviceType, ClassLoader cl) {
+        @SuppressWarnings("unchecked")
+		List<T> found = (List<T>) servicesLoaded.get(serviceType);
+        if (found != null) {
+            return found;
+        }
+        List<T> services = new ArrayList<>();
+        try {
+            for (T t : ServiceLoader.load(serviceType)) {
+                services.add(t);
+            }
+            if(services.isEmpty()) {
+                for (T t : ServiceLoader.load(serviceType, serviceType.getClassLoader())) {
+                    services.add(t);
+                }
+            }
+            Collections.sort(services, PriorityServiceComparator.getInstance());
+            services = Collections.unmodifiableList(services);
+        } catch (ServiceConfigurationError e) {
+            LOG.log(Level.WARNING,
+                    "Error loading services current type " + serviceType, e);
+            if(services==null){
+                services = Collections.emptyList();
+            }
+        }
+        @SuppressWarnings("unchecked")
+		final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services));
+        return previousServices != null ? previousServices : services;
+    }
+
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value is evaluated. If no such
+     * annotation is present, a default priority of {@code 1} is returned.
+     * @param o the instance, not {@code null}.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o){
+        int prio = 1; //X TODO discuss default priority
+        Priority priority = o.getClass().getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
+
+    /**
+     * @param services to scan
+     * @param <T>      type of the service
+     *
+     * @return the service with the highest {@link Priority#value()}
+     *
+     * @throws IllegalStateException if there are multiple service implementations with the maximum priority
+     */
+    private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) {
+        T highestService = null;
+        // we do not need the priority stuff if the list contains only one element
+        if (services.size() == 1) {
+            highestService = services.iterator().next();
+            this.factoryTypes.put(serviceType, highestService.getClass());
+            return highestService;
+        }
+
+        Integer highestPriority = null;
+        int highestPriorityServiceCount = 0;
+
+        for (T service : services) {
+            int prio = getPriority(service);
+            if (highestPriority == null || highestPriority < prio) {
+                highestService = service;
+                highestPriorityServiceCount = 1;
+                highestPriority = prio;
+            } else if (highestPriority == prio) {
+                highestPriorityServiceCount++;
+            }
+        }
+
+        if (highestPriorityServiceCount > 1) {
+            throw new IllegalStateException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}",
+                                                           highestPriorityServiceCount,
+                                                           serviceType.getName(),
+                                                           highestPriority,
+                                                           services));
+        }
+        this.factoryTypes.put(serviceType, highestService.getClass());
+        return highestService;
+    }
+
+    @Override
+    public int ordinal() {
+        return 1;
+    }
+
+    @Override
+    public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException {
+        if(cl==null){
+            cl = Thread.currentThread().getContextClassLoader();
+        }
+        if(cl==null){
+            cl = getClass().getClassLoader();
+        }
+        return cl.getResources(resource);
+    }
+
+    @Override
+    public URL getResource(String resource, ClassLoader cl) {
+        if(cl==null){
+            cl = Thread.currentThread().getContextClassLoader();
+        }
+        if(cl==null){
+            cl = getClass().getClassLoader();
+        }
+        return cl.getResource(resource);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/java/org/apache/tamaya/filter/FilterComparatorTest.java
----------------------------------------------------------------------
diff --git a/code/base/src/test/java/org/apache/tamaya/filter/FilterComparatorTest.java b/code/base/src/test/java/org/apache/tamaya/filter/FilterComparatorTest.java
new file mode 100644
index 0000000..f43cfa1
--- /dev/null
+++ b/code/base/src/test/java/org/apache/tamaya/filter/FilterComparatorTest.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.filter;
+
+import org.apache.tamaya.base.filter.FilterComparator;
+import org.apache.tamaya.spi.ConfigValue;
+import org.apache.tamaya.spi.Filter;
+import org.junit.Test;
+
+import javax.annotation.Priority;
+
+import java.util.Comparator;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class FilterComparatorTest {
+
+    @Test
+    public void comparationOfFiltersWithSamePriorityIsCorrect() {
+        Comparator<Filter> comparator = FilterComparator.getInstance();
+
+        int result = comparator.compare(new FilterA(), new FilterA());
+
+        assertThat(result).isEqualTo(0);
+    }
+
+    @Test
+    public void comparationOfFiltersFirstHigherThenSecondWorksCorrectly() {
+        Comparator<Filter> comparator = FilterComparator.getInstance();
+
+        int result = comparator.compare(new FilterB(), new FilterA());
+
+        assertThat(result).isGreaterThan(0);
+    }
+
+    @Test
+    public void comparationOfFiltersSecondHigherThenFirstWorksCorrectly() {
+        Comparator<Filter> comparator = FilterComparator.getInstance();
+
+        int result = comparator.compare(new FilterA(), new FilterB());
+
+        assertThat(result).isLessThan(0);
+    }
+
+
+    @Priority(1)
+    private static class FilterA implements Filter {
+        public ConfigValue filterProperty(ConfigValue value) {
+            throw new RuntimeException("Not implemented or look at me!");
+        }
+    }
+
+    @Priority(2)
+    private static class FilterB implements Filter {
+        public ConfigValue filterProperty(ConfigValue value) {
+            throw new RuntimeException("Not implemented or look at me!");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/META-INF/javaconfig.properties
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/META-INF/javaconfig.properties b/code/base/src/test/resources/META-INF/javaconfig.properties
new file mode 100644
index 0000000..33beabb
--- /dev/null
+++ b/code/base/src/test/resources/META-INF/javaconfig.properties
@@ -0,0 +1,22 @@
+# 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.
+
+confkey1=javaconf-value1
+confkey2=javaconf-value2
+confkey3=javaconf-value3
+confkey4=javaconf-value4
+confkey5=javaconf-value5

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/META-INF/javaconfig.xml
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/META-INF/javaconfig.xml b/code/base/src/test/resources/META-INF/javaconfig.xml
new file mode 100644
index 0000000..f6cdc97
--- /dev/null
+++ b/code/base/src/test/resources/META-INF/javaconfig.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+    <entry key="aaeehh">ä</entry>
+    <entry key="ö">o</entry>
+</properties>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/META-INF/services/javax.config.spi.ConfigProviderResolver
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/META-INF/services/javax.config.spi.ConfigProviderResolver b/code/base/src/test/resources/META-INF/services/javax.config.spi.ConfigProviderResolver
new file mode 100644
index 0000000..e5ee483
--- /dev/null
+++ b/code/base/src/test/resources/META-INF/services/javax.config.spi.ConfigProviderResolver
@@ -0,0 +1,18 @@
+# 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.
+
+org.apache.tamaya.base.TestConfigurationProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter b/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter
new file mode 100644
index 0000000..30fb5d6
--- /dev/null
+++ b/code/base/src/test/resources/META-INF/services/javax.config.spi.Converter
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.base.convert.CTestConverter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/META-INF/services/org.apache.tamaya.base.DefaultServiceContextTest$InvalidPriorityInterface
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/META-INF/services/org.apache.tamaya.base.DefaultServiceContextTest$InvalidPriorityInterface b/code/base/src/test/resources/META-INF/services/org.apache.tamaya.base.DefaultServiceContextTest$InvalidPriorityInterface
new file mode 100644
index 0000000..56f57a6
--- /dev/null
+++ b/code/base/src/test/resources/META-INF/services/org.apache.tamaya.base.DefaultServiceContextTest$InvalidPriorityInterface
@@ -0,0 +1,18 @@
+# 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.
+org.apache.tamaya.base.DefaultServiceContextTest$InvalidPriorityImpl1
+org.apache.tamaya.base.DefaultServiceContextTest$InvalidPriorityImpl2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/META-INF/services/org.apache.tamaya.base.DefaultServiceContextTest$MultiImplsInterface
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/META-INF/services/org.apache.tamaya.base.DefaultServiceContextTest$MultiImplsInterface b/code/base/src/test/resources/META-INF/services/org.apache.tamaya.base.DefaultServiceContextTest$MultiImplsInterface
new file mode 100644
index 0000000..e9ee034
--- /dev/null
+++ b/code/base/src/test/resources/META-INF/services/org.apache.tamaya.base.DefaultServiceContextTest$MultiImplsInterface
@@ -0,0 +1,20 @@
+# 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.
+
+org.apache.tamaya.base.DefaultServiceContextTest$MultiImpl1
+org.apache.tamaya.base.DefaultServiceContextTest$MultiImpl2
+org.apache.tamaya.base.DefaultServiceContextTest$MultiImpl3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/code/base/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
new file mode 100644
index 0000000..7b8a81d
--- /dev/null
+++ b/code/base/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.base.DefaultServiceContext
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/invalid-properties.xml
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/invalid-properties.xml b/code/base/src/test/resources/invalid-properties.xml
new file mode 100644
index 0000000..d8b10b7
--- /dev/null
+++ b/code/base/src/test/resources/invalid-properties.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+    <entry key="a">
+    <entry key="b">1</entry>
+</properties>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/non-xml-properties.xml
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/non-xml-properties.xml b/code/base/src/test/resources/non-xml-properties.xml
new file mode 100644
index 0000000..8de819a
--- /dev/null
+++ b/code/base/src/test/resources/non-xml-properties.xml
@@ -0,0 +1,18 @@
+<!--
+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.
+-->

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/overrideOrdinal.properties
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/overrideOrdinal.properties b/code/base/src/test/resources/overrideOrdinal.properties
new file mode 100644
index 0000000..1d02488
--- /dev/null
+++ b/code/base/src/test/resources/overrideOrdinal.properties
@@ -0,0 +1,25 @@
+# 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.
+
+#overrideValue ordinal
+config_ordinal=16784
+
+mykey1=myval1
+mykey2=myval2
+mykey3=myval3
+mykey4=myval4
+mykey5=myval5
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/testfile.properties
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/testfile.properties b/code/base/src/test/resources/testfile.properties
new file mode 100644
index 0000000..abd7ee8
--- /dev/null
+++ b/code/base/src/test/resources/testfile.properties
@@ -0,0 +1,22 @@
+# 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.
+
+key1=val1
+key2=val2
+key3=val3
+key4=val4
+key5=val5
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/test/resources/valid-properties.xml
----------------------------------------------------------------------
diff --git a/code/base/src/test/resources/valid-properties.xml b/code/base/src/test/resources/valid-properties.xml
new file mode 100644
index 0000000..7eb51d9
--- /dev/null
+++ b/code/base/src/test/resources/valid-properties.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+    <entry key="a">b</entry>
+    <entry key="b">1</entry>
+</properties>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/Main.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/Main.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/Main.java
new file mode 100644
index 0000000..0c865cb
--- /dev/null
+++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/Main.java
@@ -0,0 +1,91 @@
+/*
+ * 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.examples.customconfigsource;
+
+import javax.config.Config;
+import javax.config.ConfigProvider;
+import java.io.PrintStream;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+import static java.lang.String.format;
+
+/**
+ * Small example demonstrating the usage of a self-written {@link javax.config.spi.ConfigSource}
+ * and {@link javax.config.spi.ConfigSourceProvider}.
+ *
+ * <p>
+ *  {@link org.apache.tamaya.base.configsource.SimpleConfigSource} is a custom implementation of a
+ *  {@link javax.config.spi.ConfigSource}. It reads its properties from a
+ *  flexibly configurable location. As it is an implementation
+ *  of {@code PropertySource} and it is listed as service implementation
+ *  in {@code META-INF/services/javax.config.spi.ConfigSource} Tamaya is able
+ *  to find and to use it through the Service Provider Interface service of Java.
+ * </p>
+ *
+ * <p>
+ *  The same applies to {@link SimpleConfigSourceProvider} which is an implementation
+ *  of {@link javax.config.spi.ConfigSourceProvider}. Tamaya finds implementations
+ *  of a {@link javax.config.spi.ConfigSourceProvider} also through the
+ *  Service Provider Interface service of Java. Therefore it is listed in
+ *  {@code META-INF/services/javax.config.spi.ConfigSourceProvider} file.
+ * </p>
+ */
+public class Main {
+    /*
+     * Turns off all logging.
+     */
+    static {
+        LogManager.getLogManager().reset();
+        Logger globalLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+        globalLogger.setLevel(java.util.logging.Level.OFF);
+    }
+
+    private Main() {
+    }
+
+    public static void main(String[] args) {
+        Config cfg = ConfigProvider.getConfig();
+
+        System.out.println("*****************************************************");
+        System.out.println("Simple Example (with a PropertySource and a Provider)");
+        System.out.println("*****************************************************");
+        System.out.println();
+        System.out.println("Example Metadata:");
+        System.out.println("\tType        :  " + cfg.getValue("example.type", String.class));
+        System.out.println("\tName        :  " + cfg.getValue("example.name", String.class));
+        System.out.println("\tDescription :  " + cfg.getValue("example.description", String.class));
+        System.out.println("\tVersion     :  " + cfg.getValue("example.version", String.class));
+        System.out.println("\tAuthor      :  " + cfg.getValue("example.author", String.class));
+        System.out.println();
+        System.out.println("\tPath        :  " + cfg.getValue("Path", String.class));
+        System.out.println("\taProp       :  " + cfg.getValue("aProp", String.class));
+        System.out.println();
+
+        dump(cfg.getPropertyNames(), System.out, cfg);
+    }
+
+    private static void dump(Iterable<String> properties, PrintStream stream, Config config) {
+        stream.println("FULL DUMP:\n\n");
+
+        for (String en : properties) {
+            stream.println(format("\t%s = %s", en, config.getValue(en, String.class)));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/SimpleConfigSource.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/SimpleConfigSource.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/SimpleConfigSource.java
new file mode 100644
index 0000000..0ae96e7
--- /dev/null
+++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/SimpleConfigSource.java
@@ -0,0 +1,65 @@
+/*
+ * 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.examples.customconfigsource;
+
+import org.apache.tamaya.base.configsource.BaseConfigSource;
+
+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;
+
+public class SimpleConfigSource extends BaseConfigSource {
+
+    public static final String CONFIG_PROPERTIES_LOCATION = "META-INF/MyOtherConfigProperties.properties";
+    private Map<String,String> props = new HashMap<>();
+
+    public SimpleConfigSource() throws IOException {
+        this(ClassLoader.getSystemClassLoader().getResource(CONFIG_PROPERTIES_LOCATION));
+    }
+
+    public SimpleConfigSource(URL url) throws IOException {
+        Properties properties = new Properties();
+
+        try(InputStream is = url.openStream()){
+            properties.load(is);
+
+            for(Map.Entry en: properties.entrySet()){
+                props.put(en.getKey().toString(),
+                        en.getValue().toString());
+            }
+        }
+        finally{
+            props = Collections.unmodifiableMap(props);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return CONFIG_PROPERTIES_LOCATION;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return props;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/SimpleConfigSourceProvider.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/SimpleConfigSourceProvider.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/SimpleConfigSourceProvider.java
new file mode 100644
index 0000000..8a565f2
--- /dev/null
+++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/SimpleConfigSourceProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.examples.customconfigsource;
+
+import javax.config.spi.ConfigSource;
+import javax.config.spi.ConfigSourceProvider;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class SimpleConfigSourceProvider implements ConfigSourceProvider {
+    private static final String[] RESOURCES = {
+        "cfgOther/a.properties", "cfgOther/b.properties", "cfgOther/c.properties"
+    };
+
+    @Override
+    public Collection<ConfigSource> getConfigSources(ClassLoader cl) {
+        List<ConfigSource> propertySources = new ArrayList<>();
+
+        for (String res : RESOURCES) {
+            URL url = ClassLoader.getSystemClassLoader().getResource(res);
+            try {
+                propertySources.add(new SimpleConfigSource(url));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return propertySources;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/package-info.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/package-info.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/package-info.java
new file mode 100644
index 0000000..edc3ea8
--- /dev/null
+++ b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/customconfigsource/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.examples.customconfigsource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java
deleted file mode 100644
index 1c285b2..0000000
--- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/Main.java
+++ /dev/null
@@ -1,91 +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.examples.custompropertysource;
-
-import javax.config.Config;
-import javax.config.ConfigProvider;
-import java.io.PrintStream;
-import java.util.logging.LogManager;
-import java.util.logging.Logger;
-
-import static java.lang.String.format;
-
-/**
- * Small example demonstrating the usage of a self-written {@link javax.config.spi.ConfigSource}
- * and {@link javax.config.spi.ConfigSourceProvider}.
- *
- * <p>
- *  {@link org.apache.tamaya.base.configsource.SimpleConfigSource} is a custom implementation of a
- *  {@link javax.config.spi.ConfigSource}. It reads its properties from a
- *  flexibly configurable location. As it is an implementation
- *  of {@code PropertySource} and it is listed as service implementation
- *  in {@code META-INF/services/org.apache.tamaya.spi.PropertySource} Tamaya is able
- *  to find and to use it through the Service Provider Interface service of Java.
- * </p>
- *
- * <p>
- *  The same applies to {@link SimplePropertySourceProvider} which is an implementation
- *  of {@link javax.config.spi.ConfigSourceProvider}. Tamaya finds implementations
- *  of a {@link javax.config.spi.ConfigSourceProvider} also through the
- *  Service Provider Interface service of Java. Therefore it is listed in
- *  {@code META-INF/services/org.apache.tamaya.spi.PropertySourceProvider} file.
- * </p>
- */
-public class Main {
-    /*
-     * Turns off all logging.
-     */
-    static {
-        LogManager.getLogManager().reset();
-        Logger globalLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
-        globalLogger.setLevel(java.util.logging.Level.OFF);
-    }
-
-    private Main() {
-    }
-
-    public static void main(String[] args) {
-        Config cfg = ConfigProvider.getConfig();
-
-        System.out.println("*****************************************************");
-        System.out.println("Simple Example (with a PropertySource and a Provider)");
-        System.out.println("*****************************************************");
-        System.out.println();
-        System.out.println("Example Metadata:");
-        System.out.println("\tType        :  " + cfg.getValue("example.type", String.class));
-        System.out.println("\tName        :  " + cfg.getValue("example.name", String.class));
-        System.out.println("\tDescription :  " + cfg.getValue("example.description", String.class));
-        System.out.println("\tVersion     :  " + cfg.getValue("example.version", String.class));
-        System.out.println("\tAuthor      :  " + cfg.getValue("example.author", String.class));
-        System.out.println();
-        System.out.println("\tPath        :  " + cfg.getValue("Path", String.class));
-        System.out.println("\taProp       :  " + cfg.getValue("aProp", String.class));
-        System.out.println();
-
-        dump(cfg.getPropertyNames(), System.out, cfg);
-    }
-
-    private static void dump(Iterable<String> properties, PrintStream stream, Config config) {
-        stream.println("FULL DUMP:\n\n");
-
-        for (String en : properties) {
-            stream.println(format("\t%s = %s", en, config.getValue(en, String.class)));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimpleConfigSource.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimpleConfigSource.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimpleConfigSource.java
deleted file mode 100644
index 5aede5f..0000000
--- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimpleConfigSource.java
+++ /dev/null
@@ -1,64 +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.examples.custompropertysource;
-
-import org.apache.tamaya.base.configsource.BaseConfigSource;
-
-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;
-
-public class SimpleConfigSource extends BaseConfigSource {
-
-    public static final String CONFIG_PROPERTIES_LOCATION = "META-INF/MyOtherConfigProperties.properties";
-    private Map<String,String> props = new HashMap<>();
-
-    public SimpleConfigSource() throws IOException {
-        this(ClassLoader.getSystemClassLoader().getResource(CONFIG_PROPERTIES_LOCATION));
-    }
-    public SimpleConfigSource(URL url) throws IOException {
-        Properties properties = new Properties();
-
-        try(InputStream is = url.openStream()){
-            properties.load(is);
-
-            for(Map.Entry en: properties.entrySet()){
-                props.put(en.getKey().toString(),
-                        en.getValue().toString());
-            }
-        }
-        finally{
-            props = Collections.unmodifiableMap(props);
-        }
-    }
-
-    @Override
-    public String getName() {
-        return CONFIG_PROPERTIES_LOCATION;
-    }
-
-    @Override
-    public Map<String, String> getProperties() {
-        return props;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java
deleted file mode 100644
index 26a1ac8..0000000
--- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/SimplePropertySourceProvider.java
+++ /dev/null
@@ -1,49 +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.examples.custompropertysource;
-
-import javax.config.spi.ConfigSource;
-import javax.config.spi.ConfigSourceProvider;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-public class SimplePropertySourceProvider implements ConfigSourceProvider {
-    private static final String[] RESOURCES = {
-        "cfgOther/a.properties", "cfgOther/b.properties", "cfgOther/c.properties"
-    };
-
-    @Override
-    public Collection<ConfigSource> getConfigSources(ClassLoader cl) {
-        List<ConfigSource> propertySources = new ArrayList<>();
-
-        for (String res : RESOURCES) {
-            URL url = ClassLoader.getSystemClassLoader().getResource(res);
-            try {
-                propertySources.add(new SimpleConfigSource(url));
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-
-        return propertySources;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/package-info.java
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/package-info.java b/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/package-info.java
deleted file mode 100644
index 089f69c..0000000
--- a/examples/02-custom-property-source/src/main/java/org/apache/tamaya/examples/custompropertysource/package-info.java
+++ /dev/null
@@ -1,19 +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.examples.custompropertysource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/resources/META-INF/services/javax.config.spi.ConfigSource
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/resources/META-INF/services/javax.config.spi.ConfigSource b/examples/02-custom-property-source/src/main/resources/META-INF/services/javax.config.spi.ConfigSource
new file mode 100644
index 0000000..1fd14e0
--- /dev/null
+++ b/examples/02-custom-property-source/src/main/resources/META-INF/services/javax.config.spi.ConfigSource
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.examples.customconfigsource.SimpleConfigSource
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/resources/META-INF/services/javax.config.spi.ConfigSourceProvider
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/resources/META-INF/services/javax.config.spi.ConfigSourceProvider b/examples/02-custom-property-source/src/main/resources/META-INF/services/javax.config.spi.ConfigSourceProvider
new file mode 100644
index 0000000..67b910b
--- /dev/null
+++ b/examples/02-custom-property-source/src/main/resources/META-INF/services/javax.config.spi.ConfigSourceProvider
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.examples.customconfigsource.SimpleConfigSourceProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/examples/02-custom-property-source/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
deleted file mode 100644
index 219275b..0000000
--- a/examples/02-custom-property-source/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
+++ /dev/null
@@ -1,19 +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 current 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.
-#
-org.apache.tamaya.examples.custompropertysource.SimplePropertySource
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/examples/02-custom-property-source/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
----------------------------------------------------------------------
diff --git a/examples/02-custom-property-source/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider b/examples/02-custom-property-source/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
deleted file mode 100644
index 453126f..0000000
--- a/examples/02-custom-property-source/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
+++ /dev/null
@@ -1,19 +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 current 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.
-#
-org.apache.tamaya.examples.custompropertysource.SimplePropertySourceProvider
\ No newline at end of file