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/10 22:07:09 UTC

[1/7] 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 9bc56a38b -> d0e14ed70


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/ConfigContextBuilderTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/ConfigContextBuilderTest.java b/code/core/src/test/java/org/apache/tamaya/core/ConfigContextBuilderTest.java
new file mode 100644
index 0000000..11ee957
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/ConfigContextBuilderTest.java
@@ -0,0 +1,424 @@
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one
+// *  or more contributor license agreements.  See the NOTICE file
+// *  distributed with this work for additional information
+// *  regarding copyright ownership.  The ASF licenses this file
+// *  to you under the Apache License, Version 2.0 (the
+// *  "License"); you may not use this file except in compliance
+// *  with the License.  You may obtain a copy of the License at
+// *
+// *     http://www.apache.org/licenses/LICENSE-2.0
+// *
+// *  Unless required by applicable law or agreed to in writing,
+// *  software distributed under the License is distributed on an
+// *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// *  KIND, either express or implied.  See the License for the
+// *  specific language governing permissions and limitations
+// *  under the License.
+// */
+//package org.apache.tamaya.core;
+//
+//import org.apache.tamaya.TypeLiteral;
+//import org.apache.tamaya.spi.*;
+//import org.apache.tamaya.spi.Filter;
+//import org.junit.Test;
+//
+//import javax.config.ConfigProvider;
+//import javax.config.spi.ConfigSource;
+//import javax.config.spi.Converter;
+//import java.util.Arrays;
+//import java.util.Comparator;
+//
+//import static org.junit.Assert.*;
+//
+///**
+// * Tests for {@link ConfigContextBuilder} by atsticks on 06.09.16.
+// */
+//public class ConfigContextBuilderTest {
+//
+//    private TestConfigSource TestConfigSource = new TestConfigSource(){};
+//
+//    @Test
+//    public void setContext() throws Exception {
+//        ConfigContext context = ConfigContext.of(ConfigProvider.getConfig());
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withContext(context);
+//        assertEquals(context, b.build());
+//    }
+//
+//    @Test
+//    public void withSources_Array() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("withSources_Array", 1);
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withSources(TestConfigSource, testPS2);
+//        ConfigContext ctx = b.build();
+//        assertEquals(2, ctx.getSources().size());
+//        assertTrue(ctx.getSources().contains(TestConfigSource));
+//        assertTrue(ctx.getSources().contains(testPS2));
+//        // Ensure no sorting happens during add, so switch ordinals!
+//        testPS2 = new TestConfigSource("withSources_Array", 1);
+//        b = new ConfigContextBuilder()
+//                .withSources(testPS2, TestConfigSource);
+//        ctx = b.build();
+//        assertEquals(2, ctx.getSources().size());
+//        assertTrue(ctx.getSources().contains(TestConfigSource));
+//        assertTrue(ctx.getSources().contains(testPS2));
+//        assertEquals(ctx.getSources().get(1).getName(), "TestConfigSource");
+//        assertEquals(ctx.getSources().get(0).getName(), "withSources_Array");
+//    }
+//
+//    @Test
+//    public void withSources_Collection() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("withSources_Collection", 1);
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withSources(Arrays.asList(new ConfigSource[]{TestConfigSource, testPS2}));
+//        ConfigContext ctx = b.build();
+//        assertEquals(2, ctx.getSources().size());
+//        assertTrue(ctx.getSources().contains(TestConfigSource));
+//        assertTrue(ctx.getSources().contains(testPS2));
+//        assertEquals(ctx.getSources().get(0).getName(), "TestConfigSource");
+//        assertEquals(ctx.getSources().get(1).getName(), "withSources_Collection");
+//        // Ensure no sorting happens during add, so switch ordinals!
+//        testPS2 = new TestConfigSource("withSources_Collection", 1);
+//        b = new ConfigContextBuilder()
+//                .withSources(Arrays.asList(new ConfigSource[]{testPS2, TestConfigSource}));
+//        ctx = b.build();
+//        assertEquals(2, ctx.getSources().size());
+//        assertTrue(ctx.getSources().contains(TestConfigSource));
+//        assertTrue(ctx.getSources().contains(testPS2));
+//        assertEquals(ctx.getSources().get(1).getName(), "TestConfigSource");
+//        assertEquals(ctx.getSources().get(0).getName(), "withSources_Collection");
+//    }
+//
+//    @Test
+//    public void removeConfigSources_Array() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("removeConfigSources_Array", 1);
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withSources(TestConfigSource, testPS2);
+//        ConfigContext ctx = b.build();
+//        assertEquals(2, ctx.getSources().size());
+//        assertTrue(ctx.getSources().contains(TestConfigSource));
+//        assertTrue(ctx.getSources().contains(testPS2));
+//        b = new ConfigContextBuilder()
+//                .withSources(TestConfigSource, testPS2);
+//        b.removeSources(TestConfigSource);
+//        ctx = b.build();
+//        assertFalse(ctx.getSources().contains(TestConfigSource));
+//        assertTrue(ctx.getSources().contains(testPS2));
+//        assertEquals(1, ctx.getSources().size());
+//    }
+//
+//    @Test
+//    public void removeConfigSources_Collection() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("removeConfigSources_Array", 1);
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withSources(TestConfigSource, testPS2);
+//        ConfigContext ctx = b.build();
+//        assertEquals(2, ctx.getSources().size());
+//        assertTrue(ctx.getSources().contains(TestConfigSource));
+//        assertTrue(ctx.getSources().contains(testPS2));
+//        b = new ConfigContextBuilder()
+//                .withSources(TestConfigSource, testPS2);
+//        b.removeSources(TestConfigSource);
+//        ctx = b.build();
+//        assertEquals(1, ctx.getSources().size());
+//        assertFalse(ctx.getSources().contains(TestConfigSource));
+//        assertTrue(ctx.getSources().contains(testPS2));
+//    }
+//
+//    @Test
+//    public void addPropertyFilters_Array() throws Exception {
+//        Filter filter1 = (value) -> value;
+//        Filter filter2 = (value) -> value;
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        b.withFilters(filter1, filter2);
+//        ConfigContext ctx = b.build();
+//        assertTrue(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//        b = new ConfigContextBuilder();
+//        b.withFilters(filter1, filter2);
+//        b.withFilters(filter1, filter2);
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//    }
+//
+//    @Test
+//    public void addPropertyFilters_Collection() throws Exception {
+//        Filter filter1 = (value) -> value;
+//        Filter filter2 = (value) -> value;
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        b.withFilters(Arrays.asList(new Filter[]{filter1, filter2}));
+//        ConfigContext ctx = b.build();
+//        assertTrue(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//        b = new ConfigContextBuilder();
+//        b.withFilters(filter1, filter2);
+//        b.withFilters(filter1, filter2);
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//    }
+//
+//    @Test
+//    public void removePropertyFilters_Array() throws Exception {
+//        Filter filter1 = (value) -> value;
+//        Filter filter2 = (value) -> value;
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withFilters(filter1, filter2);
+//        ConfigContext ctx = b.build();
+//        assertTrue(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//        b = new ConfigContextBuilder()
+//                .withFilters(filter1, filter2);
+//        b.removeFilters(filter1);
+//        ctx = b.build();
+//        assertEquals(1, ctx.getPropertyFilters().size());
+//        assertFalse(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//    }
+//
+//    @Test
+//    public void removePropertyFilters_Collection() throws Exception {
+//        Filter filter1 = (value) -> value;
+//        Filter filter2 = (value) -> value;
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withFilters(Arrays.asList(new Filter[]{filter1, filter2}));
+//        ConfigContext ctx = b.build();
+//        assertTrue(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//        b = new ConfigContextBuilder()
+//                .withFilters(Arrays.asList(new Filter[]{filter1, filter2}));
+//        b.removeFilters(filter1);
+//        ctx = b.build();
+//        assertEquals(1, ctx.getPropertyFilters().size());
+//        assertFalse(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//    }
+//
+//    @Test
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//    public void addConverters_Array() throws Exception {
+//		Converter converter = (value) -> value.toLowerCase();
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withConverters(TypeLiteral.of(String.class), converter);
+//        ConfigContext ctx = b.build();
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(1, ctx.getConverters().size());
+//        b = new ConfigContextBuilder()
+//                .withConverters(TypeLiteral.of(String.class), converter);
+//        b.withConverters(TypeLiteral.of(String.class), converter);
+//        assertEquals(1, ctx.getConverters().size());
+//    }
+//
+//    @Test
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//    public void addConverters_Collection() throws Exception {
+//		Converter converter = (value) -> value.toLowerCase();
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withConverters(TypeLiteral.of(String.class),
+//                        Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        ConfigContext ctx = b.build();
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(ctx.getConverters().size(), 1);
+//        b = new ConfigContextBuilder()
+//                .withConverters(TypeLiteral.of(String.class),
+//                        Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        b.withConverters(TypeLiteral.of(String.class), converter);
+//        assertEquals(ctx.getConverters().size(), 1);
+//    }
+//
+//    @Test
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//    public void removeConverters_Array() throws Exception {
+//        Converter converter = (value) -> value.toLowerCase();
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withConverters(TypeLiteral.of(String.class), converter);
+//        ConfigContext ctx = b.build();
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(1, ctx.getConverters(TypeLiteral.of(String.class)).size());
+//        b = new ConfigContextBuilder()
+//                .withConverters(TypeLiteral.of(String.class), converter);
+//        b.removeConverters(TypeLiteral.of(String.class), converter);
+//        ctx = b.build();
+//        assertFalse(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).isEmpty());
+//    }
+//
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//	@Test
+//    public void removeConverters_Collection() throws Exception {
+//        Converter converter = (value) -> value.toLowerCase();
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withConverters(TypeLiteral.of(String.class), Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        ConfigContext ctx = b.build();
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(1, ctx.getConverters(TypeLiteral.of(String.class)).size());
+//        b = new ConfigContextBuilder()
+//                .withConverters(TypeLiteral.of(String.class), Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        b.removeConverters(TypeLiteral.of(String.class), Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        ctx = b.build();
+//        assertFalse(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).isEmpty());
+//    }
+//
+//    @Test
+//    public void setPropertyValueCombinationPolicy() throws Exception {
+//        ConfigValueCombinationPolicy combPol = (currentValue, key, ConfigSource) -> currentValue;
+//        ConfigContextBuilder b = new ConfigContextBuilder()
+//                .withPropertyValueCombinationPolicy(combPol);
+//        ConfigContext ctx = b.build();
+//        assertEquals(ctx.getConfigValueCombinationPolicy(), combPol);
+//    }
+//
+//    @Test
+//    public void increasePriority(){
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        b.increasePriority(ConfigSources[ConfigSources.length-1]);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        b.increasePriority(ConfigSources[ConfigSources.length-2]);
+//        for(int i=0;i<ConfigSources.length-2;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        assertEquals(ConfigSources[ConfigSources.length-1], b.getSources().get(ConfigSources.length-2));
+//        assertEquals(ConfigSources[ConfigSources.length-2], b.getSources().get(ConfigSources.length-1));
+//    }
+//
+//    @Test
+//    public void decreasePriority(){
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        b.decreasePriority(ConfigSources[0]);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        b.decreasePriority(ConfigSources[1]);
+//        for(int i=2;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        assertEquals(ConfigSources[0], b.getSources().get(1));
+//        assertEquals(ConfigSources[1], b.getSources().get(0));
+//    }
+//
+//    @Test
+//    public void lowestPriority(){
+//        // setup
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        // test
+//        b.lowestPriority(ConfigSources[0]);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        b.lowestPriority(ConfigSources[1]);
+//        for(int i=2;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        assertEquals(ConfigSources[0], b.getSources().get(1));
+//        assertEquals(ConfigSources[1], b.getSources().get(0));
+//        b.lowestPriority(ConfigSources[5]);
+//        assertEquals(ConfigSources[5], b.getSources().get(0));
+//    }
+//
+//    @Test
+//    public void highestPriority(){
+//        // setup
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        // test
+//        b.highestPriority(ConfigSources[ConfigSources.length-1]);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        b.highestPriority(ConfigSources[ConfigSources.length-2]);
+//        for(int i=0;i<ConfigSources.length-2;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        assertEquals(ConfigSources[ConfigSources.length-2], b.getSources().get(ConfigSources.length-1));
+//        assertEquals(ConfigSources[ConfigSources.length-1], b.getSources().get(ConfigSources.length-2));
+//        b.highestPriority(ConfigSources[5]);
+//        assertEquals(ConfigSources[5], b.getSources().get(ConfigSources.length-1));
+//    }
+//
+//    @Test
+//    public void sortConfigSources(){
+//        // setup
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        Comparator<ConfigSource> psComp = (o1, o2) -> o1.toString().compareTo(o2.toString());
+//        // test
+//        b.sortSources(psComp);
+//        Arrays.sort(ConfigSources, psComp);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//    }
+//
+//    @Test
+//    public void sortPropertyFilter(){
+//        // setup
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        Filter[] filters = new Filter[10];
+//        for(int i = 0; i< filters.length; i++){
+//            filters[i] = (value) -> value.toBuilder().setValue(toString() + " - ").build();
+//        }
+//        b.withFilters(filters);
+//        Comparator<Filter> pfComp = (o1, o2) -> o1.toString().compareTo(o2.toString());
+//        // test
+//        b.sortFilter(pfComp);
+//        Arrays.sort(filters, pfComp);
+//        for(int i = 0; i< filters.length; i++){
+//            assertEquals(filters[i], b.getFilters().get(i));
+//        }
+//    }
+//
+//    @Test
+//    public void build() throws Exception {
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        ConfigContext ctx = b.build();
+//        assertNotNull(ctx);
+//        assertTrue(ctx.getSources().isEmpty());
+//        assertTrue(ctx.getPropertyFilters().isEmpty());
+//    }
+//
+//    @Test
+//    public void testRemoveAllFilters() throws Exception {
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        b.withFilters((value) -> value.toBuilder().setValue(toString() + " - ").build());
+//        assertFalse(b.getFilters().isEmpty());
+//        b.removeFilters(b.getFilters());
+//        assertTrue(b.getFilters().isEmpty());
+//    }
+//
+//    @Test
+//    public void testRemoveAllSources() throws Exception {
+//        ConfigContextBuilder b = new ConfigContextBuilder();
+//        b.withSources(new TestConfigSource());
+//        assertFalse(b.getSources().isEmpty());
+//        b.removeSources(b.getSources());
+//        assertTrue(b.getFilters().isEmpty());
+//    }
+//}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/ExtConfigBuilderTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/ExtConfigBuilderTest.java b/code/core/src/test/java/org/apache/tamaya/core/ExtConfigBuilderTest.java
new file mode 100644
index 0000000..178d6a6
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/ExtConfigBuilderTest.java
@@ -0,0 +1,447 @@
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one
+// *  or more contributor license agreements.  See the NOTICE file
+// *  distributed with this work for additional information
+// *  regarding copyright ownership.  The ASF licenses this file
+// *  to you under the Apache License, Version 2.0 (the
+// *  "License"); you may not use this file except in compliance
+// *  with the License.  You may obtain a copy of the License at
+// *
+// *     http://www.apache.org/licenses/LICENSE-2.0
+// *
+// *  Unless required by applicable law or agreed to in writing,
+// *  software distributed under the License is distributed on an
+// *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// *  KIND, either express or implied.  See the License for the
+// *  specific language governing permissions and limitations
+// *  under the License.
+// */
+//package org.apache.tamaya.core;
+//
+//import org.apache.tamaya.TypeLiteral;
+//import org.apache.tamaya.spi.*;
+//import org.apache.tamaya.spi.Filter;
+//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.Arrays;
+//import java.util.Comparator;
+//
+//import static org.junit.Assert.*;
+//
+///**
+// * Tests for {@link ConfigBuilder} by atsticks on 06.09.16.
+// */
+//public class ExtConfigBuilderTest {
+//
+//    private TestConfigSource testConfigSource = new TestConfigSource(){};
+//
+//    @Test
+//    public void fromConfig() throws Exception {
+//        Config cfg = ConfigProvider.getConfig();
+//        ConfigBuilder b = ExtConfigBuilder.create(cfg);
+//        assertEquals(cfg, b.build());
+//    }
+//
+//    @Test
+//    public void fromConfigBuilder() throws Exception {
+//        ConfigBuilder b = ExtConfigBuilder.from(ConfigProviderResolver.instance().getBuilder());
+//        assertNotNull(b);
+//    }
+//
+//    @Test
+//    public void addConfigSources_Array() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("addConfigSources_Array", 1);
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withSources(testConfigSource, testPS2);
+//        Config cfg = b.build();
+//        assertEquals(2, ConfigContext.of(cfg).getSources().size());
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        // Ensure no sorting happens during add, so switch ordinals!
+//        testPS2 = new TestConfigSource("addConfigSources_Array", 1);
+//        b = ExtConfigBuilder.create()
+//                .withSources(testPS2, testConfigSource);
+//        cfg = b.build();
+//        assertEquals(2, ConfigContext.of(cfg).getSources().size());
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        assertEquals(ConfigContext.of(cfg).getSources().get(1).getName(), "TestConfigSource");
+//        assertEquals(ConfigContext.of(cfg).getSources().get(0).getName(), "addConfigSources_Array");
+//    }
+//
+//    @Test
+//    public void addConfigSources_Collection() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("addConfigSources_Collection", 1);
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withSources(Arrays.asList(new ConfigSource[]{testConfigSource, testPS2}));
+//        Config cfg = b.build();
+//        assertEquals(2, ConfigContext.of(cfg).getSources().size());
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        assertEquals(ConfigContext.of(cfg).getSources().get(0).getName(), "TestConfigSource");
+//        assertEquals(ConfigContext.of(cfg).getSources().get(1).getName(), "addConfigSources_Collection");
+//        // Ensure no sorting happens during add, so switch ordinals!
+//        testPS2 = new TestConfigSource("addConfigSources_Collection", 1);
+//        b = ExtConfigBuilder.create()
+//                .withSources(testPS2, testConfigSource);
+//        cfg = b.build();
+//        assertEquals(2, ConfigContext.of(cfg).getSources().size());
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        assertEquals(ConfigContext.of(cfg).getSources().get(1).getName(), "TestConfigSource");
+//        assertEquals(ConfigContext.of(cfg).getSources().get(0).getName(), "addConfigSources_Collection");
+//    }
+//
+//    @Test
+//    public void removeConfigSources_Array() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("removeConfigSources_Array", 1);
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withSources(testConfigSource, testPS2);
+//        Config cfg = b.build();
+//        assertEquals(2, ConfigContext.of(cfg).getSources().size());
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        b = ExtConfigBuilder.from(ConfigProviderResolver.instance().getBuilder()
+//                .withSources(testConfigSource, testPS2));
+//        b.removeSources(testConfigSource);
+//        cfg = b.build();
+//        assertFalse(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        assertEquals(1, ConfigContext.of(cfg).getSources().size());
+//    }
+//
+//    @Test
+//    public void removeConfigSources_Collection() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("removeConfigSources_Array", 1);
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withSources(testConfigSource, testPS2);
+//        Config cfg = b.build();
+//        assertEquals(2, ConfigContext.of(cfg).getSources().size());
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        b = ExtConfigBuilder.from(ConfigProviderResolver.instance().getBuilder())
+//                .withSources(testConfigSource, testPS2);
+//        b.removeSources(testConfigSource);
+//        cfg = b.build();
+//        assertEquals(1, ConfigContext.of(cfg).getSources().size());
+//        assertFalse(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//    }
+//
+//    @Test
+//    public void addPropertyFilters_Array() throws Exception {
+//        Filter filter1 = (value) -> value;
+//        Filter filter2 = (value) -> value;
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        b.withFilters(filter1, filter2);
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//        b = ExtConfigBuilder.create();
+//        b.withFilters(filter1, filter2);
+//        b.withFilters(filter1, filter2);
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//    }
+//
+//    @Test
+//    public void addPropertyFilters_Collection() throws Exception {
+//        Filter filter1 = (value) -> value;
+//        Filter filter2 = (value) -> value;
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        b.withFilters(Arrays.asList(new Filter[]{filter1, filter2}));
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//        b = ExtConfigBuilder.create();
+//        b.withFilters(filter1, filter2);
+//        b.withFilters(filter1, filter2);
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//    }
+//
+//    @Test
+//    public void removePropertyFilters_Array() throws Exception {
+//        Filter filter1 = (value) -> value;
+//        Filter filter2 = (value) -> value;
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withFilters(filter1, filter2);
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//        b = ExtConfigBuilder.create()
+//                .withFilters(filter1, filter2);
+//        b.removeFilters(filter1);
+//        cfg = b.build();
+//        ctx = ConfigContext.of(cfg);
+//        assertEquals(1, ctx.getPropertyFilters().size());
+//        assertFalse(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//    }
+//
+//    @Test
+//    public void removePropertyFilters_Collection() throws Exception {
+//        Filter filter1 = (value) -> value;
+//        Filter filter2 = (value) -> value;
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withFilters(Arrays.asList(new Filter[]{filter1, filter2}));
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//        assertEquals(2, ctx.getPropertyFilters().size());
+//        b = ExtConfigBuilder.create()
+//                .withFilters(Arrays.asList(new Filter[]{filter1, filter2}));
+//        b.removeFilters(filter1);
+//        cfg = b.build();
+//        ctx = ConfigContext.of(cfg);
+//        assertEquals(1, ctx.getPropertyFilters().size());
+//        assertFalse(ctx.getPropertyFilters().contains(filter1));
+//        assertTrue(ctx.getPropertyFilters().contains(filter2));
+//    }
+//
+//    @Test
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//    public void addPropertyConverters_Array() throws Exception {
+//		Converter converter = (value) -> value.toLowerCase();
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withConverters(TypeLiteral.of(String.class), converter);
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(1, ctx.getConverters().size());
+//        b = ExtConfigBuilder.create()
+//                .withConverters(TypeLiteral.of(String.class), converter);
+//        b.withConverters(TypeLiteral.of(String.class), converter);
+//        assertEquals(1, ctx.getConverters().size());
+//    }
+//
+//    @Test
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//    public void addPropertyConverters_Collection() throws Exception {
+//		Converter converter = (value) -> value.toLowerCase();
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withConverters(TypeLiteral.of(String.class),
+//                        Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(ctx.getConverters().size(), 1);
+//        b = ExtConfigBuilder.create()
+//                .withConverters(TypeLiteral.of(String.class),
+//                        Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        b.withConverters(TypeLiteral.of(String.class), converter);
+//        assertEquals(ctx.getConverters().size(), 1);
+//    }
+//
+//    @Test
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//    public void removePropertyConverters_Array() throws Exception {
+//        Converter converter = (value) -> value.toLowerCase();
+//        ExtConfigBuilder b = b = ExtConfigBuilder.create()
+//                .withConverters(TypeLiteral.of(String.class), converter);
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(1, ctx.getConverters(TypeLiteral.of(String.class)).size());
+//        b = ExtConfigBuilder.create()
+//                .withConverters(TypeLiteral.of(String.class), converter);
+//        b.removeConverters(TypeLiteral.of(String.class), converter);
+//        cfg = b.build();
+//        ctx = ConfigContext.of(cfg);
+//        assertFalse(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).isEmpty());
+//    }
+//
+//
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//	@Test
+//    public void removePropertyConverters_Collection() throws Exception {
+//        Converter converter = (value) -> value.toLowerCase();
+//        ExtConfigBuilder b = ExtConfigBuilder.create()
+//                .withConverters(TypeLiteral.of(String.class), Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(1, ctx.getConverters(TypeLiteral.of(String.class)).size());
+//        b = b = ExtConfigBuilder.create()
+//                .withConverters(TypeLiteral.of(String.class), Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        b.removeConverters(TypeLiteral.of(String.class), Arrays.<Converter<Object>>asList(new Converter[]{converter}));
+//        cfg = b.build();
+//        ctx = ConfigContext.of(cfg);
+//        assertFalse(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).isEmpty());
+//    }
+//
+//    @Test
+//    public void setPropertyValueCombinationPolicy() throws Exception {
+//        ConfigValueCombinationPolicy combPol = (currentValue, key, ConfigSource) -> currentValue;
+//        ExtConfigBuilder b = b = ExtConfigBuilder.create()
+//                .withPropertyValueCombinationPolicy(combPol);
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertEquals(ctx.getConfigValueCombinationPolicy(), combPol);
+//    }
+//
+//    @Test
+//    public void increasePriority(){
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        b.increasePriority(ConfigSources[ConfigSources.length-1]);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        b.increasePriority(ConfigSources[ConfigSources.length-2]);
+//        for(int i=0;i<ConfigSources.length-2;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        assertEquals(ConfigSources[ConfigSources.length-1], b.getSources().get(ConfigSources.length-2));
+//        assertEquals(ConfigSources[ConfigSources.length-2], b.getSources().get(ConfigSources.length-1));
+//    }
+//
+//    @Test
+//    public void decreasePriority(){
+//        ExtConfigBuilder b = b = ExtConfigBuilder.create();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        b.decreasePriority(ConfigSources[0]);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        b.decreasePriority(ConfigSources[1]);
+//        for(int i=2;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        assertEquals(ConfigSources[0], b.getSources().get(1));
+//        assertEquals(ConfigSources[1], b.getSources().get(0));
+//    }
+//
+//    @Test
+//    public void lowestPriority(){
+//        // setup
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        // test
+//        b.lowestPriority(ConfigSources[0]);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        b.lowestPriority(ConfigSources[1]);
+//        for(int i=2;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        assertEquals(ConfigSources[0], b.getSources().get(1));
+//        assertEquals(ConfigSources[1], b.getSources().get(0));
+//        b.lowestPriority(ConfigSources[5]);
+//        assertEquals(ConfigSources[5], b.getSources().get(0));
+//    }
+//
+//    @Test
+//    public void highestPriority(){
+//        // setup
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        // test
+//        b.highestPriority(ConfigSources[ConfigSources.length-1]);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        b.highestPriority(ConfigSources[ConfigSources.length-2]);
+//        for(int i=0;i<ConfigSources.length-2;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//        assertEquals(ConfigSources[ConfigSources.length-2], b.getSources().get(ConfigSources.length-1));
+//        assertEquals(ConfigSources[ConfigSources.length-1], b.getSources().get(ConfigSources.length-2));
+//        b.highestPriority(ConfigSources[5]);
+//        assertEquals(ConfigSources[5], b.getSources().get(ConfigSources.length-1));
+//    }
+//
+//    @Test
+//    public void sortConfigSources(){
+//        // setup
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        TestConfigSource[] ConfigSources = new TestConfigSource[10];
+//        for(int i=0;i<ConfigSources.length;i++){
+//            ConfigSources[i] = new TestConfigSource("ps"+i,i);
+//        }
+//        b.withSources(ConfigSources);
+//        Comparator<ConfigSource> psComp = (o1, o2) -> o1.toString().compareTo(o2.toString());
+//        // test
+//        b.sortSources(psComp);
+//        Arrays.sort(ConfigSources, psComp);
+//        for(int i=0;i<ConfigSources.length;i++){
+//            assertEquals(ConfigSources[i], b.getSources().get(i));
+//        }
+//    }
+//
+//    @Test
+//    public void sortPropertyFilter(){
+//        // setup
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        Filter[] filters = new Filter[10];
+//        for(int i = 0; i< filters.length; i++){
+//            filters[i] = (value) -> value.toBuilder().setValue(toString() + " - ").build();
+//        }
+//        b.withFilters(filters);
+//        Comparator<Filter> pfComp = (o1, o2) -> o1.toString().compareTo(o2.toString());
+//        // test
+//        b.sortFilter(pfComp);
+//        Arrays.sort(filters, pfComp);
+//        for(int i = 0; i< filters.length; i++){
+//            assertEquals(filters[i], b.getFilters().get(i));
+//        }
+//    }
+//
+//    @Test
+//    public void build() throws Exception {
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertNotNull(ctx);
+//        assertTrue(ctx.getSources().isEmpty());
+//        assertTrue(ctx.getPropertyFilters().isEmpty());
+//    }
+//
+//    @Test
+//    public void testRemoveAllFilters() throws Exception {
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        b.withFilters((value) -> value.toBuilder().setValue(toString() + " - ").build());
+//        assertFalse(b.getFilters().isEmpty());
+//        b.removeFilters(b.getFilters());
+//        assertTrue(b.getFilters().isEmpty());
+//    }
+//
+//    @Test
+//    public void testRemoveAllSources() throws Exception {
+//        ExtConfigBuilder b = ExtConfigBuilder.create();
+//        b.withSources(new TestConfigSource());
+//        assertFalse(b.getSources().isEmpty());
+//        b.removeSources(b.getSources());
+//        assertTrue(b.getSources().isEmpty());
+//    }
+//}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/TamayaConfigProviderResolverTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/TamayaConfigProviderResolverTest.java b/code/core/src/test/java/org/apache/tamaya/core/TamayaConfigProviderResolverTest.java
new file mode 100644
index 0000000..dafe7a3
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/TamayaConfigProviderResolverTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.core;
+
+import org.apache.tamaya.core.TamayaConfigProviderResolver;
+import org.apache.tamaya.spi.ConfigContext;
+import org.apache.tamaya.spi.ConfigContextSupplier;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 11.09.16.
+ */
+public class TamayaConfigProviderResolverTest {
+
+    @Test
+    public void testInstantiation() throws Exception {
+        new TamayaConfigProviderResolver();
+    }
+
+    @Test
+    public void getConfiguration() throws Exception {
+        assertNotNull(new TamayaConfigProviderResolver().getConfig());
+    }
+
+    @Test
+    public void configIsConfigContextSupplier() throws Exception {
+        assertTrue(new TamayaConfigProviderResolver().getConfig() instanceof ConfigContextSupplier);
+    }
+
+    @Test
+    public void getBuilder() throws Exception {
+        assertNotNull(new TamayaConfigProviderResolver().getBuilder());
+    }
+
+    @SuppressWarnings("deprecation")
+	@Test
+    public void registerConfig_CL() throws Exception {
+        new TamayaConfigProviderResolver()
+                .registerConfig(new TamayaConfigProviderResolver().getConfig(),
+                        ClassLoader.getSystemClassLoader());
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test
+    public void registerConfig_Null() throws Exception {
+        new TamayaConfigProviderResolver()
+                .registerConfig(new TamayaConfigProviderResolver().getConfig(), null);
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/TestConfigSource.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/TestConfigSource.java b/code/core/src/test/java/org/apache/tamaya/core/TestConfigSource.java
new file mode 100644
index 0000000..35f380b
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/TestConfigSource.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tamaya.core;
+
+import javax.config.spi.ConfigSource;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * Created by atsticks on 18.10.16.
+ */
+public class TestConfigSource implements ConfigSource {
+
+    private String id;
+    private int ordinal;
+
+    public TestConfigSource() {
+        this("TestConfigSource", 0);
+    }
+
+    public TestConfigSource(String id, int ordinal) {
+        this.id = id;
+        this.ordinal = ordinal;
+    }
+
+    public int getOrdinal() {
+        return ordinal;
+    }
+
+    @Override
+    public String getName() {
+        return id != null ? id : "TestConfigSource";
+    }
+
+    @Override
+    public String getValue(String key) {
+        if(key.endsWith("[meta]")){
+            return "ordinal=" + String.valueOf(getOrdinal()) + '\n'+
+                    "createdAt=" + String.valueOf(new Date());
+        }
+        return key + "Value";
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return Collections.emptyMap();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/testdata/TestConfigNamesSource.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestConfigNamesSource.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestConfigNamesSource.java
new file mode 100644
index 0000000..eba5bb9
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestConfigNamesSource.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.testdata;
+
+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 TestConfigNamesSource extends BaseConfigSource {
+
+    private Map<String,String> properties = new HashMap<>();
+
+    public TestConfigNamesSource() {
+        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/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/testdata/TestFilter.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestFilter.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestFilter.java
new file mode 100644
index 0000000..9ffe868
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestFilter.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.core.testdata;
+
+import org.apache.tamaya.base.filter.FilterContext;
+import org.apache.tamaya.spi.Filter;
+import org.apache.tamaya.spi.ConfigValue;
+
+import javax.annotation.Priority;
+
+/**
+ * Simple PropertyFilter that filters exact one value, registered using ServiceLoader.
+ */
+@Priority(100)
+public class TestFilter implements Filter {
+    @Override
+    public ConfigValue filterProperty(ConfigValue valueToBeFiltered) {
+        FilterContext context = FilterContext.getContext();
+        if("name4".equals(valueToBeFiltered.getKey())){
+            return valueToBeFiltered.toBuilder()
+                    .setValue(valueToBeFiltered.getValue() + "(filtered)")
+                    .build();
+        }
+        return valueToBeFiltered;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingFilter.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingFilter.java b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingFilter.java
new file mode 100644
index 0000000..4bead15
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/testdata/TestRemovingFilter.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.testdata;
+
+import org.apache.tamaya.base.filter.FilterContext;
+import org.apache.tamaya.spi.Filter;
+import org.apache.tamaya.spi.ConfigValue;
+
+import javax.annotation.Priority;
+import javax.config.ConfigProvider;
+
+/**
+ * Simple PropertyFilter that filters exact one value, registered using ServiceLoader.
+ */
+@Priority(200)
+public class TestRemovingFilter implements Filter {
+    @Override
+    public ConfigValue filterProperty(ConfigValue valueToBeFiltered) {
+        FilterContext context = FilterContext.getContext();
+
+        if("name5".equals(valueToBeFiltered.getKey())){
+            return null;
+        }
+        else if("name3".equals(valueToBeFiltered.getKey())){
+            return valueToBeFiltered.toBuilder().setValue(
+                    "Mapped to name: " + ConfigProvider.getConfig().getValue("name", String.class))
+                    .build();
+        }
+        return valueToBeFiltered;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/resources/META-INF/javaconfig.properties
----------------------------------------------------------------------
diff --git a/code/core/src/test/resources/META-INF/javaconfig.properties b/code/core/src/test/resources/META-INF/javaconfig.properties
new file mode 100644
index 0000000..33beabb
--- /dev/null
+++ b/code/core/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/d0e14ed7/code/core/src/test/resources/META-INF/javaconfig.xml
----------------------------------------------------------------------
diff --git a/code/core/src/test/resources/META-INF/javaconfig.xml b/code/core/src/test/resources/META-INF/javaconfig.xml
new file mode 100644
index 0000000..f6cdc97
--- /dev/null
+++ b/code/core/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/d0e14ed7/code/core/src/test/resources/META-INF/services/javax.config.spi.ConfigSource
----------------------------------------------------------------------
diff --git a/code/core/src/test/resources/META-INF/services/javax.config.spi.ConfigSource b/code/core/src/test/resources/META-INF/services/javax.config.spi.ConfigSource
new file mode 100644
index 0000000..74d685e
--- /dev/null
+++ b/code/core/src/test/resources/META-INF/services/javax.config.spi.ConfigSource
@@ -0,0 +1,21 @@
+#
+# 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.core.testdata.TestConfigNamesSource
+org.apache.tamaya.core.internal.converters.ConverterTestsPropertySource
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/resources/META-INF/services/javax.config.spi.ConfigSourceProvider
----------------------------------------------------------------------
diff --git a/code/core/src/test/resources/META-INF/services/javax.config.spi.ConfigSourceProvider b/code/core/src/test/resources/META-INF/services/javax.config.spi.ConfigSourceProvider
new file mode 100644
index 0000000..c9f255a
--- /dev/null
+++ b/code/core/src/test/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.core.testdata.TestPropertySourceProvider

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/resources/META-INF/services/javax.config.spi.Converter
----------------------------------------------------------------------
diff --git a/code/core/src/test/resources/META-INF/services/javax.config.spi.Converter b/code/core/src/test/resources/META-INF/services/javax.config.spi.Converter
new file mode 100644
index 0000000..d039696
--- /dev/null
+++ b/code/core/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.core.internal.CTestConverter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.Filter
----------------------------------------------------------------------
diff --git a/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.Filter b/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.Filter
new file mode 100644
index 0000000..d727173
--- /dev/null
+++ b/code/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.Filter
@@ -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 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.core.testdata.TestFilter
+org.apache.tamaya.core.testdata.TestRemovingFilter


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

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
new file mode 100644
index 0000000..2c300ad
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContext.java
@@ -0,0 +1,277 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.TypeLiteral;
+import org.apache.tamaya.spi.*;
+
+import java.util.*;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+/**
+ * Default implementation of a simple ConfigurationContext.
+ */
+public class DefaultConfigurationContext implements ConfigurationContext {
+
+    /** The logger used. */
+    private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName());
+
+    /**
+     * Subcomponent handling {@link PropertyConverter} instances.
+     */
+    private final PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
+
+    /**
+     * The current unmodifiable list of loaded {@link PropertySource} instances.
+     */
+    private List<PropertySource> immutablePropertySources;
+
+    /**
+     * The current unmodifiable list of loaded {@link PropertyFilter} instances.
+     */
+    private List<PropertyFilter> immutablePropertyFilters;
+
+    /**
+     * The overriding policy used when combining PropertySources registered to evalute the final configuration
+     * values.
+     */
+    private PropertyValueCombinationPolicy propertyValueCombinationPolicy;
+
+    /**
+     * Lock for internal synchronization.
+     */
+    private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
+
+    @SuppressWarnings("unchecked")
+	protected DefaultConfigurationContext(DefaultConfigurationContextBuilder builder) {
+        List<PropertySource> propertySources = new ArrayList<>();
+        // first we load all PropertySources which got registered via java.util.ServiceLoader
+        propertySources.addAll(builder.propertySources);
+        // now sort them according to their ordinal values
+        immutablePropertySources = Collections.unmodifiableList(propertySources);
+
+        // as next step we pick up the PropertyFilters pretty much the same way
+        List<PropertyFilter> propertyFilters = new ArrayList<>(builder.getPropertyFilters());
+        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+
+        // Finally add the converters
+        for(Map.Entry<TypeLiteral<?>, Collection<PropertyConverter<?>>> en:builder.getPropertyConverter().entrySet()) {
+            for (@SuppressWarnings("rawtypes") PropertyConverter converter : en.getValue()) {
+                this.propertyConverterManager.register(en.getKey(), converter);
+            }
+        }
+        LOG.info("Registered " + propertyConverterManager.getPropertyConverters().size() + " property converters: " +
+                propertyConverterManager.getPropertyConverters());
+
+        propertyValueCombinationPolicy = builder.combinationPolicy;
+        if(propertyValueCombinationPolicy==null){
+            propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+        }
+        if(propertyValueCombinationPolicy==null){
+            propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+        }
+        LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+    }
+
+
+    @Deprecated
+    @Override
+    public void addPropertySources(PropertySource... propertySourcesToAdd) {
+        Lock writeLock = propertySourceLock.writeLock();
+        try {
+            writeLock.lock();
+            List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources);
+            newPropertySources.addAll(Arrays.asList(propertySourcesToAdd));
+            Collections.sort(newPropertySources, PropertySourceComparator.getInstance());
+
+            this.immutablePropertySources = Collections.unmodifiableList(newPropertySources);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof DefaultConfigurationContext)){
+            return false;
+        }
+
+        DefaultConfigurationContext that = (DefaultConfigurationContext) o;
+
+        if (!propertyConverterManager.equals(that.propertyConverterManager)) {
+            return false;
+        }
+        if (!immutablePropertySources.equals(that.immutablePropertySources)) {
+            return false;
+        }
+        if (!immutablePropertyFilters.equals(that.immutablePropertyFilters)) {
+            return false;
+        }
+        return getPropertyValueCombinationPolicy().equals(that.getPropertyValueCombinationPolicy());
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = propertyConverterManager.hashCode();
+        result = 31 * result + immutablePropertySources.hashCode();
+        result = 31 * result + immutablePropertyFilters.hashCode();
+        result = 31 * result + getPropertyValueCombinationPolicy().hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder("ConfigurationContext{\n");
+        b.append("  Property Sources\n");
+        b.append("  ----------------\n");
+        if(immutablePropertySources.isEmpty()){
+            b.append("  No property sources loaded.\n\n");
+        }else {
+            b.append("  CLASS                         NAME                                                                  ORDINAL SCANNABLE SIZE    STATE     ERROR\n\n");
+            for (PropertySource ps : immutablePropertySources) {
+                b.append("  ");
+                appendFormatted(b, ps.getClass().getSimpleName(), 30);
+                appendFormatted(b, ps.getName(), 70);
+                appendFormatted(b, String.valueOf(PropertySourceComparator.getOrdinal(ps)), 8);
+                appendFormatted(b, String.valueOf(ps.isScannable()), 10);
+                if (ps.isScannable()) {
+                    appendFormatted(b, String.valueOf(ps.getProperties().size()), 8);
+                } else {
+                    appendFormatted(b, "-", 8);
+                }
+                PropertyValue state = ps.get("_state");
+                if(state==null){
+                    appendFormatted(b, "OK", 10);
+                }else {
+                    appendFormatted(b, state.getValue(), 10);
+                    if("ERROR".equals(state.getValue())){
+                        PropertyValue val = ps.get("_exception");
+                        if(val!=null) {
+                            appendFormatted(b, val.getValue(), 30);
+                        }
+                    }
+                }
+                b.append('\n');
+            }
+            b.append("\n");
+        }
+        b.append("  Property Filters\n");
+        b.append("  ----------------\n");
+        if(immutablePropertyFilters.isEmpty()){
+            b.append("  No property filters loaded.\n\n");
+        }else {
+            b.append("  CLASS                         INFO\n\n");
+            for (PropertyFilter filter : getPropertyFilters()) {
+                b.append("  ");
+                appendFormatted(b, filter.getClass().getSimpleName(), 30);
+                b.append(removeNewLines(filter.toString()));
+                b.append('\n');
+            }
+            b.append("\n\n");
+        }
+        b.append("  Property Converters\n");
+        b.append("  -------------------\n");
+        b.append("  CLASS                         TYPE                          INFO\n\n");
+        for(Map.Entry<TypeLiteral<?>, List<PropertyConverter<?>>> converterEntry:getPropertyConverters().entrySet()){
+            for(PropertyConverter converter: converterEntry.getValue()){
+                b.append("  ");
+                appendFormatted(b, converter.getClass().getSimpleName(), 30);
+                appendFormatted(b, converterEntry.getKey().getRawType().getSimpleName(), 30);
+                b.append(removeNewLines(converter.toString()));
+                b.append('\n');
+            }
+        }
+        b.append("\n\n");
+        b.append("  PropertyValueCombinationPolicy: " + getPropertyValueCombinationPolicy().getClass().getName()).append('\n');
+        b.append('}');
+        return b.toString();
+    }
+
+    private void appendFormatted(StringBuilder b, String text, int length) {
+        int padding;
+        if(text.length() <= (length)){
+            b.append(text);
+            padding = length - text.length();
+        }else{
+            b.append(text.substring(0, length-1));
+            padding = 1;
+        }
+        for(int i=0;i<padding;i++){
+            b.append(' ');
+        }
+    }
+
+    private String removeNewLines(String s) {
+        return s.replace('\n', ' ').replace('\r', ' ');
+    }
+
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return immutablePropertySources;
+    }
+
+    @Override
+    public PropertySource getPropertySource(String name) {
+        for(PropertySource ps:getPropertySources()){
+            if(name.equals(ps.getName())){
+                return ps;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+        propertyConverterManager.register(typeToConvert, propertyConverter);
+        LOG.info("Added PropertyConverter: " + propertyConverter.getClass().getName());
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+        return propertyConverterManager.getPropertyConverters();
+    }
+
+    @Override
+    public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+        return propertyConverterManager.getPropertyConverters(targetType);
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return immutablePropertyFilters;
+    }
+
+    @Override
+    public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+        return propertyValueCombinationPolicy;
+    }
+
+    @Override
+    public ConfigurationContextBuilder toBuilder() {
+        return new DefaultConfigurationContextBuilder(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java
new file mode 100644
index 0000000..0ee54da
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationContextBuilder.java
@@ -0,0 +1,431 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.TypeLiteral;
+import org.apache.tamaya.spi.*;
+import org.apache.tamaya.spisupport.propertysource.CLIPropertySource;
+import org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource;
+import org.apache.tamaya.spisupport.propertysource.JavaConfigurationPropertySource;
+import org.apache.tamaya.spisupport.propertysource.SystemPropertySource;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * Default implementation of {@link ConfigurationContextBuilder}.
+ */
+public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder {
+
+    private static final Logger LOG = Logger.getLogger(DefaultConfigurationContextBuilder.class.getName());
+
+    protected List<PropertyFilter> propertyFilters = new ArrayList<>();
+    protected List<PropertySource> propertySources = new ArrayList<>();
+    protected PropertyValueCombinationPolicy combinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_POLICY;
+    protected Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> propertyConverters = new HashMap<>();
+
+    /**
+     * Flag if the config has already been built.
+     * Configuration can be built only once
+     */
+    private boolean built;
+
+
+
+    /**
+     * Creates a new builder instance.
+     */
+    public DefaultConfigurationContextBuilder() {
+    }
+
+    /**
+     * Creates a new builder instance initializing it with the given context.
+     * @param context the context to be used, not null.
+     */
+    public DefaultConfigurationContextBuilder(ConfigurationContext context) {
+        this.propertyConverters.putAll(context.getPropertyConverters());
+        this.propertyFilters.addAll(context.getPropertyFilters());
+        for(PropertySource ps:context.getPropertySources()) {
+            addPropertySources(ps);
+        }
+        this.combinationPolicy = context.getPropertyValueCombinationPolicy();
+    }
+
+    /**
+     * Allows to reset configuration context during unit tests.
+     */
+    public final ConfigurationContextBuilder resetWithConfigurationContext(ConfigurationContext configurationContext) {
+        checkBuilderState();
+        //noinspection deprecation
+        this.propertyFilters.clear();
+        this.propertyFilters.addAll(configurationContext.getPropertyFilters());
+        this.propertySources.clear();
+        for(PropertySource ps:configurationContext.getPropertySources()) {
+            addPropertySources(ps);
+        }
+        this.propertyConverters.clear();
+        this.propertyConverters.putAll(configurationContext.getPropertyConverters());
+        this.combinationPolicy = configurationContext.getPropertyValueCombinationPolicy();
+        return this;
+    }
+
+
+    @Override
+    public ConfigurationContextBuilder setContext(ConfigurationContext context) {
+        checkBuilderState();
+        this.propertyConverters.putAll(context.getPropertyConverters());
+        for(PropertySource ps:context.getPropertySources()){
+            this.propertySources.add(ps);
+        }
+        this.propertyFilters.addAll(context.getPropertyFilters());
+        this.combinationPolicy = context.getPropertyValueCombinationPolicy();
+        return this;
+    }
+
+    @Override
+    public final ConfigurationContextBuilder addPropertySources(PropertySource... sources){
+        return addPropertySources(Arrays.asList(sources));
+    }
+
+    @Override
+    public ConfigurationContextBuilder addPropertySources(Collection<PropertySource> sources){
+        checkBuilderState();
+        for(PropertySource source:sources) {
+            if (!this.propertySources.contains(source)) {
+                this.propertySources.add(source);
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder addDefaultPropertySources() {
+        checkBuilderState();
+        List<PropertySource> propertySources = new ArrayList<>();
+        addCorePropertyResources(propertySources);
+        for(PropertySource ps: ServiceContextManager.getServiceContext().getServices(PropertySource.class)) {
+            if(!propertySources.contains(ps)){
+                propertySources.add(ps);
+            }
+        }
+        for(PropertySourceProvider provider:
+                ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class)){
+                propertySources.addAll(provider.getPropertySources());
+        }
+        Collections.sort(propertySources, PropertySourceComparator.getInstance());
+        return addPropertySources(propertySources);
+    }
+
+    protected void addCorePropertyResources(List<PropertySource> propertySources) {
+        for(PropertySource ps: new PropertySource[]{
+                new EnvironmentPropertySource(),
+                new JavaConfigurationPropertySource(),
+                new CLIPropertySource(),
+                new SystemPropertySource()
+        }){
+            if(!propertySources.contains(ps)){
+                propertySources.add(ps);
+            }
+        }
+    }
+
+    @Override
+    public ConfigurationContextBuilder addDefaultPropertyFilters() {
+        checkBuilderState();
+        for(PropertyFilter pf:ServiceContextManager.getServiceContext().getServices(PropertyFilter.class)){
+            addPropertyFilters(pf);
+        }
+        return this;
+    }
+
+    @Override
+    public DefaultConfigurationContextBuilder addDefaultPropertyConverters() {
+        checkBuilderState();
+        addCorePropertyConverters();
+        for(Map.Entry<TypeLiteral, Collection<PropertyConverter>> en:getDefaultPropertyConverters().entrySet()){
+            for(PropertyConverter pc: en.getValue()) {
+                addPropertyConverters(en.getKey(), pc);
+            }
+        }
+        return this;
+    }
+
+    @SuppressWarnings("unchecked")
+	protected void addCorePropertyConverters() {
+        // should be overridden by subclasses.
+    }
+
+    @Override
+    public final ConfigurationContextBuilder removePropertySources(PropertySource... propertySources) {
+        return removePropertySources(Arrays.asList(propertySources));
+    }
+
+    @Override
+    public ConfigurationContextBuilder removePropertySources(Collection<PropertySource> propertySources) {
+        checkBuilderState();
+        this.propertySources.removeAll(propertySources);
+        return this;
+    }
+
+    protected PropertySource getPropertySource(String name) {
+        for(PropertySource ps:propertySources){
+            if(ps.getName().equals(name)){
+                return ps;
+            }
+        }
+        throw new IllegalArgumentException("No such PropertySource: "+name);
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return Collections.unmodifiableList(this.propertySources);
+    }
+
+    @Override
+    public ConfigurationContextBuilder increasePriority(PropertySource 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;
+    }
+
+    @Override
+    public ConfigurationContextBuilder decreasePriority(PropertySource 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;
+    }
+
+    @Override
+    public ConfigurationContextBuilder highestPriority(PropertySource 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;
+    }
+
+    @Override
+    public ConfigurationContextBuilder lowestPriority(PropertySource 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;
+    }
+
+    @Override
+    public final ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters){
+        return addPropertyFilters(Arrays.asList(filters));
+    }
+
+    @Override
+    public final ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters){
+        checkBuilderState();
+        for(PropertyFilter f:filters) {
+            if (!this.propertyFilters.contains(f)) {
+                this.propertyFilters.add(f);
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public final ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters) {
+        return removePropertyFilters(Arrays.asList(filters));
+    }
+
+    @Override
+    public final ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+        checkBuilderState();
+        this.propertyFilters.removeAll(filters);
+        return this;
+    }
+
+
+    @Override
+    public final <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                    @SuppressWarnings("unchecked") PropertyConverter<T>... converters) {
+        return removePropertyConverters(typeToConvert, Arrays.asList(converters));
+    }
+
+    @Override
+    public final <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                    Collection<PropertyConverter<T>> converters) {
+        Collection<PropertyConverter<?>> subConverters = this.propertyConverters.get(typeToConvert);
+        if(subConverters!=null) {
+            subConverters.removeAll(converters);
+        }
+        return this;
+    }
+
+    @Override
+    public final ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert) {
+        this.propertyConverters.remove(typeToConvert);
+        return this;
+    }
+
+
+    @Override
+    public final ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy combinationPolicy){
+        checkBuilderState();
+        this.combinationPolicy = Objects.requireNonNull(combinationPolicy);
+        return this;
+    }
+
+
+    @Override
+    public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> type, PropertyConverter<T>... propertyConverters){
+        checkBuilderState();
+        Objects.requireNonNull(type);
+        Objects.requireNonNull(propertyConverters);
+        Collection<PropertyConverter<?>> converters = this.propertyConverters.get(type);
+        if(converters==null){
+            converters = new ArrayList<>();
+            this.propertyConverters.put(type, converters);
+        }
+        for(PropertyConverter<T> propertyConverter:propertyConverters) {
+            if (!converters.contains(propertyConverter)) {
+                converters.add(propertyConverter);
+            } else {
+                LOG.warning("Converter ignored, already registered: " + propertyConverter);
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> type, Collection<PropertyConverter<T>> propertyConverters){
+        checkBuilderState();
+        Objects.requireNonNull(type);
+        Objects.requireNonNull(propertyConverters);
+        Collection<PropertyConverter<?>> converters = this.propertyConverters.get(type);
+        if(converters==null){
+            converters = new ArrayList<>();
+            this.propertyConverters.put(type, converters);
+        }
+        for(PropertyConverter<T> propertyConverter:propertyConverters) {
+            if (!converters.contains(propertyConverter)) {
+                converters.add(propertyConverter);
+            } else {
+                LOG.warning("Converter ignored, already registered: " + propertyConverter);
+            }
+        }
+        return this;
+    }
+
+    protected ConfigurationContextBuilder loadDefaults() {
+        checkBuilderState();
+        this.combinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+        addDefaultPropertySources();
+        addDefaultPropertyFilters();
+        addDefaultPropertyConverters();
+        return this;
+    }
+
+
+    protected Map<TypeLiteral, Collection<PropertyConverter>> getDefaultPropertyConverters() {
+        Map<TypeLiteral, Collection<PropertyConverter>> result = new HashMap<>();
+        for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(
+                PropertyConverter.class)) {
+            for(Type type:conv.getClass().getGenericInterfaces()){
+                if(type instanceof ParameterizedType){
+                    ParameterizedType pt = (ParameterizedType)type;
+                    if(PropertyConverter.class.equals(((ParameterizedType) type).getRawType())){
+                        TypeLiteral target = TypeLiteral.of(pt.getActualTypeArguments()[0]);
+                        Collection<PropertyConverter> 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 org.apache.tamaya.Configuration configuration instance},
+     *         never {@code null}.
+     */
+    @Override
+    public ConfigurationContext build() {
+        checkBuilderState();
+        built = true;
+        return new DefaultConfigurationContext(this);
+    }
+
+    @Override
+    public ConfigurationContextBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator) {
+        Collections.sort(propertyFilters, comparator);
+        return this;
+    }
+
+    @Override
+    public ConfigurationContextBuilder sortPropertySources(Comparator<PropertySource> comparator) {
+        Collections.sort(propertySources, comparator);
+        return this;
+    }
+
+    private void checkBuilderState() {
+        if (built) {
+            throw new IllegalStateException("Configuration has already been build.");
+        }
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return propertyFilters;
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter() {
+        return Collections.unmodifiableMap(this.propertyConverters);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java
new file mode 100644
index 0000000..1dd00c0
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/EnumConverter.java
@@ -0,0 +1,39 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+/**
+ * Converter, converting from String to tge given enum type.
+ */
+public class EnumConverter<T extends Enum> implements PropertyConverter<T>{
+
+    private org.apache.tamaya.base.convert.EnumConverter<T> converter;
+
+    public EnumConverter(Class<T> enumType){
+        converter = new org.apache.tamaya.base.convert.EnumConverter<>(enumType);
+    }
+
+    @Override
+    public T convert(String value, ConversionContext context) {
+        return converter.convert(value);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/PriorityServiceComparator.java
new file mode 100644
index 0000000..dbef51f
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/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.spisupport;
+
+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/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
new file mode 100644
index 0000000..7bc8d26
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyConverterManager.java
@@ -0,0 +1,472 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.spisupport;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.TypeLiteral;
+import org.apache.tamaya.base.PriorityServiceComparator;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Manager that deals with {@link PropertyConverter} instances.
+ * This class is thread-safe.
+ */
+public class PropertyConverterManager {
+    /**
+     * The logger used.
+     */
+    private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName());
+    /**
+     * The registered converters.
+     */
+    private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>();
+    /**
+     * The transitive converters.
+     */
+    private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>();
+    /**
+     * The lock used.
+     */
+    private final ReadWriteLock lock = new ReentrantReadWriteLock();
+
+    private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() {
+
+        @Override
+        public int compare(Object o1, Object o2) {
+            int prio = org.apache.tamaya.base.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());
+            }
+        }
+    };
+
+    /**
+     * Constructor.
+     */
+    public PropertyConverterManager() {
+        this(false);
+    }
+
+    public PropertyConverterManager(boolean init) {
+        if (init) {
+            initConverters();
+        }
+    }
+
+    /**
+     * Registers the default converters provided out of the box.
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    protected void initConverters() {
+        for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(PropertyConverter.class)) {
+            Type type = TypeLiteral.getGenericInterfaceTypeParameters(conv.getClass(), PropertyConverter.class)[0];
+            register(TypeLiteral.of(type), conv);
+        }
+    }
+
+    /**
+     * Registers a new converters instance.
+     *
+     * @param targetType the target type, not {@code null}.
+     * @param converter  the converters, not {@code null}.
+     * @param <T>        the type.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> void register(TypeLiteral<T> targetType, PropertyConverter<T> converter) {
+        Objects.requireNonNull(converter);
+        Lock writeLock = lock.writeLock();
+        try {
+            writeLock.lock();
+			List<PropertyConverter<?>> converters = List.class.cast(this.converters.get(targetType));
+            if(converters!=null && converters.contains(converter)){
+                return;
+            }
+            List<PropertyConverter<?>> newConverters = new ArrayList<>();
+            if (converters != null) {
+                newConverters.addAll(converters);
+            }
+            if(!newConverters.contains(converter)) {
+                newConverters.add(converter);
+            }
+            Collections.sort(newConverters, PRIORITY_COMPARATOR);
+            this.converters.put(targetType, Collections.unmodifiableList(newConverters));
+            // evaluate transitive closure for all inherited supertypes and implemented interfaces
+            // direct implemented interfaces
+            for (Class<?> ifaceType : targetType.getRawType().getInterfaces()) {
+                converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType)));
+                newConverters = new ArrayList<>();
+                if (converters != null) {
+                    newConverters.addAll(converters);
+                }
+                newConverters.add(converter);
+                Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+            }
+            Class<?> superClass = targetType.getRawType().getSuperclass();
+            while (superClass != null && !superClass.equals(Object.class)) {
+                converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(superClass)));
+                newConverters = new ArrayList<>();
+                if (converters != null) {
+                    newConverters.addAll(converters);
+                }
+                newConverters.add(converter);
+                Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(TypeLiteral.of(superClass), Collections.unmodifiableList(newConverters));
+                for (Class<?> ifaceType : superClass.getInterfaces()) {
+                    converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType)));
+                    newConverters = new ArrayList<>();
+                    if (converters != null) {
+                        newConverters.addAll(converters);
+                    }
+                    newConverters.add(converter);
+                    Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                    this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+                }
+                superClass = superClass.getSuperclass();
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * 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(TypeLiteral<?> 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(TypeLiteral)
+     */
+    public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+        Lock readLock = lock.readLock();
+        try {
+            readLock.lock();
+            return new HashMap<>(this.converters);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * 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}.
+     * @param <T>        the type class
+     * @return the ordered list of converters (may be empty for not convertible types).
+     * @see #createDefaultPropertyConverter(TypeLiteral)
+     */
+    public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+        Lock readLock = lock.readLock();
+        List<PropertyConverter<T>> converterList = new ArrayList<>();
+        // direct mapped converters
+        try {
+            readLock.lock();
+            addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
+            addConvertersToList(List.class.cast(this.transitiveConverters.get(targetType)), converterList);
+        } finally {
+            readLock.unlock();
+        }
+        // handling of java.lang wrapper classes
+        TypeLiteral<T> boxedType = mapBoxedType(targetType);
+        if (boxedType != null) {
+            try {
+                readLock.lock();
+                addConvertersToList(List.class.cast(this.converters.get(boxedType)), converterList);
+            } finally {
+                readLock.unlock();
+            }
+        }
+        if (converterList.isEmpty() && !TypeLiteral.of(String.class).equals(targetType)) {
+            // adding any converters created on the fly, e.g. for enum types.
+            PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
+            if (defaultConverter != null) {
+                register(targetType, defaultConverter);
+                try {
+                    readLock.lock();
+                    addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
+                } finally {
+                    readLock.unlock();
+                }
+            }
+        }
+        // check for parametrized types, ignoring param type
+        // direct mapped converters
+        if(targetType.getType()!=null) {
+            try {
+                readLock.lock();
+                addConvertersToList(List.class.cast(this.converters.get(
+                        TypeLiteral.of(targetType.getRawType()))), converterList);
+            } finally {
+                readLock.unlock();
+            }
+        }
+        return converterList;
+    }
+
+    private <T> void addConvertersToList(Collection<PropertyConverter<T>> converters, List<PropertyConverter<T>> converterList) {
+        if (converters != null) {
+            for(PropertyConverter<T> conv:converters) {
+                if(!converterList.contains(conv)) {
+                    converterList.add(conv);
+                }
+            }
+        }
+    }
+
+    /**
+     * Maps native types to the corresponding boxed types.
+     *
+     * @param targetType the native type.
+     * @param <T>        the type
+     * @return the boxed type, or null.
+     */
+    @SuppressWarnings("unchecked")
+	private <T> TypeLiteral<T> mapBoxedType(TypeLiteral<T> targetType) {
+        Type parameterType = targetType.getType();
+        if (parameterType == int.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Integer.class));
+        }
+        if (parameterType == short.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Short.class));
+        }
+        if (parameterType == byte.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Byte.class));
+        }
+        if (parameterType == long.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Long.class));
+        }
+        if (parameterType == boolean.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
+        }
+        if (parameterType == char.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Character.class));
+        }
+        if (parameterType == float.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Float.class));
+        }
+        if (parameterType == double.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Double.class));
+        }
+        if (parameterType == int[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Integer[].class));
+        }
+        if (parameterType == short[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Short[].class));
+        }
+        if (parameterType == byte[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Byte[].class));
+        }
+        if (parameterType == long[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Long[].class));
+        }
+        if (parameterType == boolean.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
+        }
+        if (parameterType == char[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Character[].class));
+        }
+        if (parameterType == float[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Float[].class));
+        }
+        if (parameterType == double[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Double[].class));
+        }
+        return null;
+    }
+
+    /**
+     * Creates a dynamic PropertyConverter for the given target type.
+     *
+     * @param targetType the target type
+     * @param <T>        the type class
+     * @return a new converters, or null.
+     */
+    protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) {
+        if (Enum.class.isAssignableFrom(targetType.getRawType())) {
+            return new EnumConverter(targetType.getRawType());
+        }
+        PropertyConverter<T> converter = null;
+        final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse");
+        if (factoryMethod != null) {
+            converter = new DefaultPropertyConverter<>(factoryMethod, targetType.getRawType());
+        }
+        if (converter == null) {
+            final Constructor<T> constr;
+            try {
+                constr = targetType.getRawType().getDeclaredConstructor(String.class);
+            } catch (NoSuchMethodException e) {
+                LOG.log(Level.FINEST, "No matching constrctor for " + targetType, e);
+                return null;
+            }
+            converter = new PropertyConverter<T>() {
+                    @Override
+                    public T convert(String value, ConversionContext context) {
+                        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 PropertyConverterManager)) {
+            return false;
+        }
+        PropertyConverterManager that = (PropertyConverterManager) 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 PropertyConverter<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 context) {
+            context.addSupportedFormats(getClass(), "<String -> "+factoryMethod.toGenericString());
+
+            if (!Modifier.isStatic(factoryMethod.getModifiers())) {
+                throw new ConfigException(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 ConfigException("Failed to decode '" + value + "'", e);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.java
new file mode 100644
index 0000000..20eef63
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyFilterComparator.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.spisupport;
+
+import org.apache.tamaya.spi.PropertyFilter;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Comparator for PropertyFilters based on their priority annotations.
+ */
+public final class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final PropertyFilterComparator INSTANCE = new PropertyFilterComparator();
+
+    /**
+     * Get the shared instance of the comparator.
+     * @return the shared instance, never null.
+     */
+    public static PropertyFilterComparator getInstance(){
+        return INSTANCE;
+    }
+
+    private PropertyFilterComparator(){}
+
+    /**
+     * 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(PropertyFilter filter1, PropertyFilter 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(PropertyFilter filter1, PropertyFilter filter2) {
+        return comparePropertyFilters(filter1, filter2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java
new file mode 100644
index 0000000..af69899
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertyFiltering.java
@@ -0,0 +1,123 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
+ * chain of {@link org.apache.tamaya.spi.PropertySource} and {@link PropertyFilter}
+ * instance to evaluate the current Configuration.
+ */
+public final class PropertyFiltering{
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(PropertyFiltering.class.getName());
+    /**
+     * The maximal number of filter cycles performed before aborting.
+     */
+    private static final int MAX_FILTER_LOOPS = 10;
+
+    /**
+     * Private singleton constructor.
+     */
+    private PropertyFiltering(){}
+
+    /**
+     * Filters a single value.
+     * @param value the raw value, not {@code null}.
+     * @param context the context
+     * @return the filtered value, including {@code null}.
+     */
+    public static PropertyValue applyFilter(PropertyValue value, ConfigurationContext context) {
+        FilterContext filterContext = new FilterContext(value, context);
+        return filterValue(filterContext);
+    }
+
+    /**
+     * Filters all properties.
+     * @param rawProperties the unfiltered properties, not {@code null}.
+     * @param context the context
+     * @return the filtered value, inclusing null.
+     */
+    public static Map<String, PropertyValue> applyFilters(Map<String, PropertyValue> rawProperties, ConfigurationContext context) {
+        Map<String, PropertyValue> result = new HashMap<>();
+        // Apply filters to values, prevent values filtered to null!
+        for (Map.Entry<String, PropertyValue> entry : rawProperties.entrySet()) {
+            FilterContext filterContext = new FilterContext(entry.getValue(), rawProperties, context);
+            PropertyValue filtered = filterValue(filterContext);
+            if(filtered!=null){
+                result.put(filtered.getKey(), filtered);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Basic filter logic.
+     * @param context the filter context, not {@code null}.
+     * @return the filtered value.
+     */
+    private static PropertyValue filterValue(FilterContext context) {
+        PropertyValue inputValue = context.getProperty();
+        PropertyValue filteredValue = inputValue;
+
+        for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
+            int changes = 0;
+            for (PropertyFilter filter : context.getContext().getPropertyFilters()) {
+                filteredValue = filter.filterProperty(inputValue, context);
+                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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java
new file mode 100644
index 0000000..e9511b5
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/PropertySourceComparator.java
@@ -0,0 +1,120 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import javax.annotation.Priority;
+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 PropertySourceComparator implements Comparator<PropertySource>, Serializable {
+    /** serial version UID. */
+    private static final long serialVersionUID = 1L;
+
+    private static final Logger LOG = Logger.getLogger(PropertySourceComparator.class.getName());
+
+    private static final PropertySourceComparator INSTANCE = new PropertySourceComparator();
+
+    private String alternativeOrdinalKey;
+
+    /** Singleton constructor. */
+    private PropertySourceComparator(){}
+
+    /**
+     * Get the shared instance of the comparator.
+     * @return the shared instance, never null.
+     */
+    public static PropertySourceComparator 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 comparePropertySources(PropertySource source1, PropertySource 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 PropertySource}, Hereby the ordinal of type {@code int}
+     * is evaluated as follows:
+     * <ol>
+     *     <li>It evaluates the {@code String} value for {@link PropertySource#TAMAYA_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 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(PropertySource propertySource) {
+        return getOrdinal(propertySource, null);
+    }
+
+    public static int getOrdinal(PropertySource propertySource, String alternativeOrdinalKey) {
+        if(alternativeOrdinalKey!=null) {
+            PropertyValue ordinalValue = propertySource.get(alternativeOrdinalKey);
+            if (ordinalValue != null) {
+                try {
+                    return Integer.parseInt(ordinalValue.getValue().trim());
+                } catch (Exception e) {
+                    LOG.finest("Failed to parse ordinal from " + alternativeOrdinalKey +
+                            " in " + propertySource.getName() + ": " + ordinalValue.getValue());
+                }
+            }
+        }
+        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 PropertySourceComparator setOrdinalKey(String ordinalKey) {
+        this.alternativeOrdinalKey = ordinalKey;
+        return this;
+    }
+
+    @Override
+    public int compare(PropertySource source1, PropertySource source2) {
+        return comparePropertySources(source1, source2);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/RegexPropertyFilter.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/RegexPropertyFilter.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/RegexPropertyFilter.java
new file mode 100644
index 0000000..9be444f
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/RegexPropertyFilter.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.spisupport;
+
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Predicate filtering using a regex expression operating on the key. It allows either
+ * to define the target keys to be selected (includes), or to be excluded (excludes).
+ */
+public final class RegexPropertyFilter implements PropertyFilter {
+    /** The expression used to include entries that match. */
+    private List<String> includes;
+    /** The expression used to exclude entries that match. */
+    private List<String> excludes;
+
+    /**
+     * Sets the regex expression to be applied on the key to filter the corresponding entry
+     * if matching.
+     * @param expressions the regular expression for inclusion, not null.
+     */
+    public void setIncludes(String... expressions){
+        this.includes = Arrays.asList(expressions);
+    }
+
+    /**
+     * Sets the regex expression to be applied on the key to remove the corresponding entries
+     * if matching.
+     * @param expressions the regular expressions for exclusion, not null.
+     */
+    public void setExcludes(String... expressions){
+        this.excludes= Arrays.asList(expressions);
+    }
+
+    @Override
+    public PropertyValue filterProperty(PropertyValue valueToBeFiltered, FilterContext context) {
+        if(includes!=null){
+            for(String expression:includes){
+                if(context.getProperty().getKey().matches(expression)){
+                    return valueToBeFiltered;
+                }
+            }
+            return null;
+        }
+        if(excludes!=null){
+            for(String expression:excludes){
+                if(context.getProperty().getKey().matches(expression)){
+                    return null;
+                }
+            }
+        }
+        return valueToBeFiltered;
+    }
+
+    @Override
+    public String toString() {
+        return "RegexPropertyFilter{" +
+                "includes='" + includes + '\'' +
+                "excludes='" + excludes + '\'' +
+                '}';
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java
new file mode 100644
index 0000000..6126b68
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BasePropertySource.java
@@ -0,0 +1,172 @@
+/*
+ * 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.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Abstract {@link org.apache.tamaya.spi.PropertySource} that allows to set a default ordinal that will be used, if no
+ * ordinal is provided with the config.
+ */
+public abstract class BasePropertySource implements PropertySource{
+    /** 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 BasePropertySource(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 BasePropertySource(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 BasePropertySource(String name, int defaultOrdinal){
+        this.name = Objects.requireNonNull(name);
+        this.defaultOrdinal = defaultOrdinal;
+    }
+
+
+    /**
+     * Constructor, using a default ordinal of 0.
+     */
+    protected BasePropertySource(){
+        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;
+        }
+        PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
+        if(configuredOrdinal!=null){
+            try {
+                return Integer.parseInt(configuredOrdinal.getValue());
+            } 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 PropertyValue get(String key) {
+        Map<String,PropertyValue> properties = getProperties();
+        PropertyValue 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;
+
+        BasePropertySource that = (BasePropertySource) 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/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java
new file mode 100644
index 0000000..fbea188
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySource.java
@@ -0,0 +1,231 @@
+/*
+ * 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.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.*;
+
+/**
+ * A Buildable property source.
+ */
+public class BuildablePropertySource implements PropertySource{
+
+    private int ordinal;
+    private String name = "PropertySource-"+UUID.randomUUID().toString();
+    private Map<String,PropertyValue> properties = new HashMap<>();
+
+    @Override
+    public int getOrdinal() {
+        return ordinal;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public PropertyValue get(String key) {
+        return properties.get(key);
+    }
+
+    @Override
+    public Map<String, PropertyValue> getProperties() {
+        return Collections.unmodifiableMap(properties);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BuildablePropertySource that = (BuildablePropertySource) o;
+
+        return name.equals(that.name);
+    }
+
+    @Override
+    public boolean isScannable() {
+        return true;
+    }
+
+    @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 = "<on-the-fly-build>";
+        private String name = "PropertySource-"+ UUID.randomUUID().toString();
+        private Map<String,PropertyValue> 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 withSimpleProperty(String key, String value) {
+            return withProperties(PropertyValue.of(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 withSimpleProperty(String key, String value, String source) {
+            return withProperties(PropertyValue.of(key, value, source));
+        }
+
+        /**
+         * With properties builder.
+         *
+         * @param values the values
+         * @return the builder
+         */
+        public Builder withProperties(PropertyValue... values) {
+            for(PropertyValue val:values){
+                this.properties.put(val.getKey(), val);
+            }
+            return this;
+        }
+
+        /**
+         * With properties builder.
+         *
+         * @param properties the properties
+         * @return the builder
+         */
+        public Builder withProperties(Map<String, PropertyValue> properties) {
+            this.properties =  Objects.requireNonNull(properties);
+            return this;
+        }
+
+        /**
+         * With properties builder.
+         *
+         * @param properties the properties
+         * @param source     the source
+         * @return the builder
+         */
+        public Builder withProperties(Map<String, String> properties, String source) {
+            this.properties.putAll(PropertyValue.map(properties, source));
+            return this;
+        }
+
+        /**
+         * With simple properties builder.
+         *
+         * @param properties the properties
+         * @return the builder
+         */
+        public Builder withSimpleProperties(Map<String, String> properties) {
+            this.properties.putAll(PropertyValue.map(properties, this.source));
+            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 BuildablePropertySource build() {
+            BuildablePropertySource buildablePropertySource = new BuildablePropertySource();
+            buildablePropertySource.name = this.name;
+            buildablePropertySource.properties = this.properties;
+            buildablePropertySource.ordinal = this.ordinal;
+            return buildablePropertySource;
+        }
+    }
+}


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

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java
new file mode 100644
index 0000000..eb5b717
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/DoubleConverter.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Double, using the Java number syntax:
+ * (-)?[0-9]*\.[0-9]*. In case of error the value given also is tried being parsed as integral number using
+ * {@link LongConverter}. Additionally the following values are supported:
+ * <ul>
+ * <li>NaN (ignoring case)</li>
+ * <li>POSITIVE_INFINITY (ignoring case)</li>
+ * <li>NEGATIVE_INFINITY (ignoring case)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class DoubleConverter implements Converter<Double> {
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(DoubleConverter.class.getName());
+    /**
+     * The converter used, when floating point parse failed.
+     */
+    private final LongConverter integerConverter = new LongConverter();
+
+    @Override
+    public Double convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "<double>", "MIN", "MIN_VALUE", "MAX", "MAX_VALUE", "POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NAN");
+        String trimmed = Objects.requireNonNull(value).trim();
+        switch (trimmed.toUpperCase(Locale.ENGLISH)) {
+            case "POSITIVE_INFINITY":
+                return Double.POSITIVE_INFINITY;
+            case "NEGATIVE_INFINITY":
+                return Double.NEGATIVE_INFINITY;
+            case "NAN":
+                return Double.NaN;
+            case "MIN_VALUE":
+            case "MIN":
+                return Double.MIN_VALUE;
+            case "MAX_VALUE":
+            case "MAX":
+                return Double.MAX_VALUE;
+            default:
+                try {
+                    return Double.valueOf(trimmed);
+                } catch (Exception e) {
+                    // OK perhaps we have an integral number that must be converted to the double type...
+                    LOG.finest("Parsing of double as floating number failed, trying parsing integral" +
+                            " number/hex instead...");
+                }
+                Long val = integerConverter.convert(trimmed);
+                if(val!=null){
+                    return val.doubleValue();
+                }
+                return null;
+        }
+
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/DurationConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/DurationConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/DurationConverter.java
new file mode 100644
index 0000000..eb05097
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/DurationConverter.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.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class DurationConverter implements Converter<Duration> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public Duration convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(),
+                Duration.of(1234, ChronoUnit.SECONDS).toString());
+        try {
+            return Duration.parse(value);
+        }catch(Exception e){
+            LOG.log(Level.FINEST, e, () -> "Cannot parse Duration: " + value);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.java
new file mode 100644
index 0000000..38badd4
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/FileConverter.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.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.io.File;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to URI, using new URL(value).
+ */
+@Component(service = Converter.class)
+public class FileConverter implements Converter<File> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public File convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        if(value==null || value.isEmpty()){
+            return null;
+        }
+        context.addSupportedFormats(getClass(),"<File>");
+        String trimmed = Objects.requireNonNull(value).trim();
+        try {
+            return new File(trimmed);
+        } catch (Exception e) {
+            LOG.log(Level.FINE, "Unparseable File Name: " + trimmed, e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/FloatConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/FloatConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/FloatConverter.java
new file mode 100644
index 0000000..b66a8e1
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/FloatConverter.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Float, using the Java number syntax:
+ * (-)?[0-9]*\.[0-9]*. In case of error the value given also is tried being parsed as integral number using
+ * {@link LongConverter}. Additionally the following values are supported:
+ * <ul>
+ * <li>NaN (ignoring case)</li>
+ * <li>POSITIVE_INFINITY (ignoring case)</li>
+ * <li>NEGATIVE_INFINITY (ignoring case)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class FloatConverter implements Converter<Float> {
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(FloatConverter.class.getName());
+    /**
+     * The converter used, when floating point parse failed.
+     */
+    private final IntegerConverter integerConverter = new IntegerConverter();
+
+    @Override
+    public Float convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "<float>", "MIN", "MIN_VALUE", "MAX", "MAX_VALUE", "POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NAN");
+        String trimmed = Objects.requireNonNull(value).trim();
+        switch(trimmed.toUpperCase(Locale.ENGLISH)){
+            case "POSITIVE_INFINITY":
+                return Float.POSITIVE_INFINITY;
+            case "NEGATIVE_INFINITY":
+                return Float.NEGATIVE_INFINITY;
+            case "NAN":
+                return Float.NaN;
+            case "MIN_VALUE":
+            case "MIN":
+                return Float.MIN_VALUE;
+            case "MAX_VALUE":
+            case "MAX":
+                return Float.MAX_VALUE;
+            default:
+                try {
+                    return Float.valueOf(trimmed);
+                } catch(Exception e){
+                    // OK perhaps we have an integral number that must be converted to the double type...
+                    LOG.finest("Parsing of float as floating number failed, trying parsing integral" +
+                            " number/hex instead...");
+                }
+                Integer val = integerConverter.convert(trimmed);
+                if(val!=null) {
+                    return val.floatValue();
+                }
+                LOG.finest("Unparseable float value: " + trimmed);
+                return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/InstantConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/InstantConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/InstantConverter.java
new file mode 100644
index 0000000..b6d485f
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/InstantConverter.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.time.Instant;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class InstantConverter implements Converter<Instant> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public Instant convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), Instant.now().toString());
+        try{
+            return Instant.parse(value);
+        }catch(Exception e){
+            LOG.log(Level.FINEST, e, () -> "Cannot parse Instant: " + value);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/IntegerConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/IntegerConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/IntegerConverter.java
new file mode 100644
index 0000000..5a62a23
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/IntegerConverter.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Integer, the supported format is one of the following:
+ * <ul>
+ *     <li>123 (byte value)</li>
+ *     <li>0xFF (byte value)</li>
+ *     <li>0XDF (byte value)</li>
+ *     <li>0D1 (byte value)</li>
+ *     <li>-123 (byte value)</li>
+ *     <li>-0xFF (byte value)</li>
+ *     <li>-0XDF (byte value)</li>
+ *     <li>-0D1 (byte value)</li>
+ *     <li>MIN_VALUE (ignoring case)</li>
+ *     <li>MIN (ignoring case)</li>
+ *     <li>MAX_VALUE (ignoring case)</li>
+ *     <li>MAX (ignoring case)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class IntegerConverter implements Converter<Integer> {
+
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(IntegerConverter.class.getName());
+
+    @Override
+    public Integer convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "<int>", "MIN_VALUE", "MIN", "MAX_VALUE", "MAX");
+        String trimmed = Objects.requireNonNull(value).trim();
+        switch(trimmed.toUpperCase(Locale.ENGLISH)){
+            case "MIN_VALUE":
+            case "MIN":
+                return Integer.MIN_VALUE;
+            case "MAX_VALUE":
+            case "MAX":
+                return Integer.MAX_VALUE;
+            default:
+                try{
+                    return Integer.decode(trimmed);
+                }
+                catch(Exception e){
+                    LOG.finest("Unparseable Integer value: " + trimmed);
+                    return null;
+                }
+        }
+
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/LocalDateConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/LocalDateConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/LocalDateConverter.java
new file mode 100644
index 0000000..edfaa3a
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/LocalDateConverter.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.time.LocalDate;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class LocalDateConverter implements Converter<LocalDate> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public LocalDate convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), LocalDate.now().toString());
+        try{
+            return LocalDate.parse(value);
+        }catch(Exception e){
+            LOG.log(Level.FINEST, e, () -> "Cannot parse LocalDate: " + value);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/LocalDateTimeConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/LocalDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/LocalDateTimeConverter.java
new file mode 100644
index 0000000..9450e30
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/LocalDateTimeConverter.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.time.LocalDateTime;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class LocalDateTimeConverter implements Converter<LocalDateTime> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public LocalDateTime convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), LocalDateTime.now().toString());
+        try{
+            return LocalDateTime.parse(value);
+        }catch(Exception e){
+            LOG.log(Level.FINEST, e, () -> "Cannot parse LocalDateTime: " + value);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/LocalTimeConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/LocalTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/LocalTimeConverter.java
new file mode 100644
index 0000000..dde2214
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/LocalTimeConverter.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.time.LocalTime;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class LocalTimeConverter implements Converter<LocalTime> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public LocalTime convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), LocalTime.now().toString());
+        try{
+            return LocalTime.parse(value);
+        }catch(Exception e){
+            LOG.log(Level.FINEST, e, () -> "Cannot parse LocalTime: " + value);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java
new file mode 100644
index 0000000..8861c09
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/LongConverter.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Long, the supported format is one of the following:
+ * <ul>
+ *     <li>123 (byte value)</li>
+ *     <li>0xFF (byte value)</li>
+ *     <li>0XDF (byte value)</li>
+ *     <li>0D1 (byte value)</li>
+ *     <li>-123 (byte value)</li>
+ *     <li>-0xFF (byte value)</li>
+ *     <li>-0XDF (byte value)</li>
+ *     <li>-0D1 (byte value)</li>
+ *     <li>MIN_VALUE (ignoring case)</li>
+ *     <li>MIN (ignoring case)</li>
+ *     <li>MAX_VALUE (ignoring case)</li>
+ *     <li>MAX (ignoring case)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class LongConverter implements Converter<Long> {
+
+    private static final Logger LOGGER = Logger.getLogger(LongConverter.class.getName());
+
+    @Override
+    public Long convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "<long>", "MIN", "MIN_VALUE", "MAX", "MAX_VALUE");
+
+        String trimmed = Objects.requireNonNull(value).trim();
+            switch (trimmed.toUpperCase(Locale.ENGLISH)) {
+                case "MIN_VALUE":
+                case "MIN":
+                    return Long.MIN_VALUE;
+                case "MAX_VALUE":
+                case "MAX":
+                    return Long.MAX_VALUE;
+                default:
+                    try {
+                        return Long.decode(trimmed);
+                    }
+                    catch(Exception e){
+                        LOGGER.finest("Unable to parse Long value: " + value);
+                        return null;
+                    }
+            }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java
new file mode 100644
index 0000000..2f2893d
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/NumberConverter.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.math.BigDecimal;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Number. Valid inputs are:
+ * <pre>
+ *     POSITIVE_INFINITY -&gt; Double.POSITIVE_INFINITY
+ *     NEGATIVE_INFINITY -&gt; Double.NEGATIVE_INFINITY
+ *     NaN &gt; Double.NaN
+ *     0xFFDCD3D2 -&gt; Long
+ *     1234566789.23642327352735273752 -&gt; new BigDecimal(input)
+ * </pre>
+ */
+@Component(service = Converter.class)
+public class NumberConverter implements Converter<Number> {
+    /** the logger. */
+    private static final Logger LOGGER = Logger.getLogger(NumberConverter.class.getName());
+    /** Converter used for trying to parse as an integral value. */
+    private final LongConverter longConverter = new LongConverter();
+
+    @Override
+    public Number convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "<double>, <long>", "0x (hex)", "0X... (hex)", "POSITIVE_INFINITY",
+                "NEGATIVE_INFINITY", "NAN");
+
+        String trimmed = Objects.requireNonNull(value).trim();
+        switch(trimmed.toUpperCase(Locale.ENGLISH)) {
+            case "POSITIVE_INFINITY":
+                return Double.POSITIVE_INFINITY;
+            case "NEGATIVE_INFINITY":
+                return Double.NEGATIVE_INFINITY;
+            case "NAN":
+                return Double.NaN;
+            default:
+                Long lVal = longConverter.convert(trimmed);
+                if (lVal != null) {
+                    return lVal;
+                }
+                try{
+                    return new BigDecimal(trimmed);
+                }
+                catch(Exception e){
+                    LOGGER.finest("Unparseable Number: " + trimmed);
+                    return null;
+                }
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/OffsetDateTimeConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/OffsetDateTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/OffsetDateTimeConverter.java
new file mode 100644
index 0000000..8b78814
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/OffsetDateTimeConverter.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.time.OffsetDateTime;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class OffsetDateTimeConverter implements Converter<OffsetDateTime> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public OffsetDateTime convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), OffsetDateTime.now().toString());
+        try{
+            return OffsetDateTime.parse(value);
+        }catch(Exception e){
+            LOG.log(Level.FINEST, e, () -> "Cannot parse OffsetDateTime: " + value);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/OffsetTimeConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/OffsetTimeConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/OffsetTimeConverter.java
new file mode 100644
index 0000000..8186ac0
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/OffsetTimeConverter.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.time.OffsetTime;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class OffsetTimeConverter implements Converter<OffsetTime> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public OffsetTime convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), OffsetTime.now().toString());
+        try{
+            return OffsetTime.parse(value);
+        }catch(Exception e){
+            LOG.log(Level.FINEST, e, () -> "Cannot parse OffsetTime: " + value);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/OptionalConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/OptionalConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/OptionalConverter.java
new file mode 100644
index 0000000..ef307cc
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/OptionalConverter.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Optional;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class OptionalConverter implements Converter<Optional> {
+
+    @Override
+    public Optional convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        if(value==null){
+            return Optional.empty();
+        }
+        try{
+            if(context==null){
+                throw new IllegalStateException("Failed to evaluate target type, context == null.");
+            }
+            Type targetType = context.getTargetType();
+            if(Optional.class.equals(targetType)){
+                ParameterizedType pt = (ParameterizedType) targetType;
+                if(String.class.equals(pt.getActualTypeArguments()[0])){
+                    return Optional.of(value);
+                }
+                else{
+                    targetType = pt.getActualTypeArguments()[0];
+                }
+            }
+            if(context.getConfiguration()==null){
+                throw new IllegalStateException("Parametrized converters require a configuration for accessing the converters of their" +
+                        "child elements.");
+            }
+            ConvertQuery converter = new ConvertQuery(value, targetType);
+            return Optional.ofNullable(converter.apply(context.getConfiguration()));
+        }catch (IllegalStateException ise){
+            throw ise;
+        }catch(Exception e){
+            throw new IllegalArgumentException("Error evaluating config value.", e);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/PathConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/PathConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/PathConverter.java
new file mode 100644
index 0000000..6bc9fc3
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/PathConverter.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.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to URI, using new URL(value).
+ */
+@Component(service = Converter.class)
+public class PathConverter implements Converter<Path> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public Path convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        if(value==null || value.isEmpty()){
+            return null;
+        }
+        context.addSupportedFormats(getClass(),"<File>");
+        String trimmed = Objects.requireNonNull(value).trim();
+        try {
+            return FileSystems.getDefault().getPath(value);
+        } catch (Exception e) {
+            LOG.log(Level.FINE, "Unparseable Path: " + trimmed, e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/ShortConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/ShortConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/ShortConverter.java
new file mode 100644
index 0000000..19c5f77
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/ShortConverter.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Short, the supported format is one of the following:
+ * <ul>
+ *     <li>123 (byte value)</li>
+ *     <li>0xFF (byte value)</li>
+ *     <li>0XDF (byte value)</li>
+ *     <li>0D1 (byte value)</li>
+ *     <li>-123 (byte value)</li>
+ *     <li>-0xFF (byte value)</li>
+ *     <li>-0XDF (byte value)</li>
+ *     <li>-0D1 (byte value)</li>
+ *     <li>MIN_VALUE (ignoring case)</li>
+ *     <li>MIN (ignoring case)</li>
+ *     <li>MAX_VALUE (ignoring case)</li>
+ *     <li>MAX (ignoring case)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class ShortConverter implements Converter<Short> {
+
+    /** the logger. */
+    private static final Logger LOG = Logger.getLogger(ShortConverter.class.getName());
+
+    @Override
+    public Short convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "short", "MIN", "MIN_VALUE", "MAX", "MAX_VALUE");
+        String trimmed = Objects.requireNonNull(value).trim();
+        switch(trimmed.toUpperCase(Locale.ENGLISH)){
+            case "MIN_VALUE":
+            case "MIN":
+                return Short.MIN_VALUE;
+            case "MAX_VALUE":
+            case "MAX":
+                return Short.MAX_VALUE;
+            default:
+                try{
+                    return Short.decode(trimmed);
+                }
+                catch(Exception e){
+                    LOG.finest("Unparseable Short: " + trimmed);
+                    return null;
+                }
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/SupplierConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/SupplierConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/SupplierConverter.java
new file mode 100644
index 0000000..e39f93a
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/SupplierConverter.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.function.Supplier;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class SupplierConverter implements Converter<Supplier> {
+
+    private static final Logger LOG = Logger.getLogger(SupplierConverter.class.getName());
+
+    @Override
+    public Supplier convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        return () -> {
+            try{
+                Type targetType = context.getTargetType();
+                ParameterizedType pt = (ParameterizedType) targetType;
+                if(String.class.equals(pt.getActualTypeArguments()[0])){
+                    return value;
+                }
+                ConvertQuery converter = new ConvertQuery(value, pt.getActualTypeArguments()[0]);
+                Object o = converter.apply(context.getConfiguration());
+                if(o==null){
+                    throw new IllegalArgumentException("No such value: " + context.getKey());
+                }
+                return o;
+            }catch(Exception e){
+                throw new IllegalArgumentException("Error evaluating config value.", e);
+            }
+        };
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/URIConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/URIConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/URIConverter.java
new file mode 100644
index 0000000..d63103a
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/URIConverter.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.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.net.URI;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to URI, using new URI(value).
+ */
+@Component(service = Converter.class)
+public class URIConverter implements Converter<URI> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public URI convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        if(value==null || value.isEmpty()){
+            return null;
+        }
+        context.addSupportedFormats(getClass(), "<uri> -> new URI(uri)");
+        String trimmed = Objects.requireNonNull(value).trim();
+        try {
+            return new URI(trimmed);
+        } catch (Exception e) {
+            LOG.log(Level.FINE, "Unparseable URI: " + trimmed, e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/URLConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/URLConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/URLConverter.java
new file mode 100644
index 0000000..27c69b1
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/URLConverter.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.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.net.URL;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to URI, using new URL(value).
+ */
+@Component(service = Converter.class)
+public class URLConverter implements Converter<URL> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public URL convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        if(value==null || value.isEmpty()){
+            return null;
+        }
+        context.addSupportedFormats(getClass(),"<URL>");
+        String trimmed = Objects.requireNonNull(value).trim();
+        try {
+            return new URL(trimmed);
+        } catch (Exception e) {
+            LOG.log(Level.FINE, "Unparseable URL: " + trimmed, e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/package-info.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/package-info.java b/code/core/src/main/java/org/apache/tamaya/core/converters/package-info.java
new file mode 100644
index 0000000..2eb5858
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/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 implementations of the converters provided by default.
+ */
+package org.apache.tamaya.core.converters;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/resources/META-INF/services/javax.config.spi.ConfigProviderResolver
----------------------------------------------------------------------
diff --git a/code/core/src/main/resources/META-INF/services/javax.config.spi.ConfigProviderResolver b/code/core/src/main/resources/META-INF/services/javax.config.spi.ConfigProviderResolver
new file mode 100644
index 0000000..7177d12
--- /dev/null
+++ b/code/core/src/main/resources/META-INF/services/javax.config.spi.ConfigProviderResolver
@@ -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.core.TamayaConfigProviderResolver

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/resources/META-INF/services/javax.config.spi.ConfigSource
----------------------------------------------------------------------
diff --git a/code/core/src/main/resources/META-INF/services/javax.config.spi.ConfigSource b/code/core/src/main/resources/META-INF/services/javax.config.spi.ConfigSource
new file mode 100644
index 0000000..ffa770a
--- /dev/null
+++ b/code/core/src/main/resources/META-INF/services/javax.config.spi.ConfigSource
@@ -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 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.configsource.CLIConfigSource
+org.apache.tamaya.base.configsource.EnvironmentConfigSource
+org.apache.tamaya.base.configsource.JavaConfigurationConfigSource
+org.apache.tamaya.base.configsource.SystemConfigSource
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/resources/META-INF/services/javax.config.spi.Converter
----------------------------------------------------------------------
diff --git a/code/core/src/main/resources/META-INF/services/javax.config.spi.Converter b/code/core/src/main/resources/META-INF/services/javax.config.spi.Converter
new file mode 100644
index 0000000..f7b9134
--- /dev/null
+++ b/code/core/src/main/resources/META-INF/services/javax.config.spi.Converter
@@ -0,0 +1,44 @@
+#
+# 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.core.converters.BooleanConverter
+org.apache.tamaya.core.converters.ByteConverter
+org.apache.tamaya.core.converters.CharConverter
+org.apache.tamaya.core.converters.ClassConverter
+org.apache.tamaya.core.converters.DoubleConverter
+org.apache.tamaya.core.converters.FloatConverter
+org.apache.tamaya.core.converters.IntegerConverter
+org.apache.tamaya.core.converters.LongConverter
+org.apache.tamaya.core.converters.ShortConverter
+org.apache.tamaya.core.converters.BigDecimalConverter
+org.apache.tamaya.core.converters.BigIntegerConverter
+org.apache.tamaya.core.converters.CurrencyConverter
+org.apache.tamaya.core.converters.NumberConverter
+org.apache.tamaya.core.converters.URIConverter
+org.apache.tamaya.core.converters.URLConverter
+org.apache.tamaya.core.converters.FileConverter
+org.apache.tamaya.core.converters.PathConverter
+org.apache.tamaya.core.converters.DurationConverter
+org.apache.tamaya.core.converters.LocalDateConverter
+org.apache.tamaya.core.converters.LocalDateTimeConverter
+org.apache.tamaya.core.converters.LocalTimeConverter
+org.apache.tamaya.core.converters.OffsetDateTimeConverter
+org.apache.tamaya.core.converters.OffsetTimeConverter
+org.apache.tamaya.core.converters.InstantConverter
+org.apache.tamaya.core.converters.OptionalConverter
+org.apache.tamaya.core.converters.SupplierConverter

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.ConfigValueEvaluator
----------------------------------------------------------------------
diff --git a/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.ConfigValueEvaluator b/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.ConfigValueEvaluator
new file mode 100644
index 0000000..26d41ab
--- /dev/null
+++ b/code/core/src/main/resources/META-INF/services/org.apache.tamaya.spi.ConfigValueEvaluator
@@ -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.DefaultConfigValueEvaluator
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/resources/tamaya-banner.txt
----------------------------------------------------------------------
diff --git a/code/core/src/main/resources/tamaya-banner.txt b/code/core/src/main/resources/tamaya-banner.txt
new file mode 100644
index 0000000..b4ceca4
--- /dev/null
+++ b/code/core/src/main/resources/tamaya-banner.txt
@@ -0,0 +1,11 @@
+
+ █████╗ ██████╗  █████╗  ██████╗██╗  ██╗███████╗    ████████╗ █████╗ ███╗   ███╗ █████╗ ██╗   ██╗ █████╗
+██╔══██╗██╔══██╗██╔══██╗██╔════╝██║  ██║██╔════╝    ╚══██╔══╝██╔══██╗████╗ ████║██╔══██╗╚██╗ ██╔╝██╔══██╗
+███████║██████╔╝███████║██║     ███████║█████╗         ██║   ███████║██╔████╔██║███████║ ╚████╔╝ ███████║
+██╔══██║██╔═══╝ ██╔══██║██║     ██╔══██║██╔══╝         ██║   ██╔══██║██║╚██╔╝██║██╔══██║  ╚██╔╝  ██╔══██║
+██║  ██║██║     ██║  ██║╚██████╗██║  ██║███████╗       ██║   ██║  ██║██║ ╚═╝ ██║██║  ██║   ██║   ██║  ██║
+╚═╝  ╚═╝╚═╝     ╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝╚══════╝       ╚═╝   ╚═╝  ╚═╝╚═╝     ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝
+
+Apache Tamaya Configuration API:  http://tamaya.incubator.apache.org
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/BannerManagerTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/BannerManagerTest.java b/code/core/src/test/java/org/apache/tamaya/core/BannerManagerTest.java
new file mode 100644
index 0000000..bb750b1
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/BannerManagerTest.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.core;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.io.PrintStream;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+
+/*
+ * Note:
+ * The tests of this class will fail PIT, our coverage tool.
+ * Therefore we excluded this class in the parent POM
+ * from the test execution.
+ * Oliver B. Fischer, 2017-09-16
+ */
+public class BannerManagerTest {
+
+    @Test
+    public void valueConsoleSendsBannerToSystemOut() {
+
+        SecurityManager sm = new SecurityManager();
+        AccessControlContext con = AccessController.getContext();
+
+        Permission p = new RuntimePermission("setIO");
+
+        /*
+         * Here we check the precondition for this unit test
+         * and the correct setup of the test environment
+         * The JVM must have been started with
+         * -Djava.security.policy=<path_to_core_module</src/test/resources/java-security.policy
+         */
+        sm.checkPermission(p, con);
+
+        PrintStream standard = System.out;
+        PrintStream printStream = Mockito.mock(PrintStream.class);
+
+        System.setOut(printStream);
+        standard.println("Changed stream for STDOUT successfully");
+
+        try {
+            BannerManager bm = new BannerManager("console");
+            bm.outputBanner();
+
+        } finally {
+            System.setOut(standard);
+        }
+        Mockito.verify(printStream, Mockito.atLeastOnce()).println(Mockito.anyString());
+    }
+
+    @Test
+    public void invalidValueAvoidsLoggingToConsonle() {
+
+        PrintStream standard = System.out;
+        PrintStream printStream = Mockito.mock(PrintStream.class);
+
+        System.setOut(printStream);
+
+        try {
+            BannerManager bm = new BannerManager("snafu");
+            bm.outputBanner();
+
+        } finally {
+            System.setOut(standard);
+        }
+
+        Mockito.verify(printStream, Mockito.never()).println(Mockito.anyString());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/test/java/org/apache/tamaya/core/ConfigBuilderTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/ConfigBuilderTest.java b/code/core/src/test/java/org/apache/tamaya/core/ConfigBuilderTest.java
new file mode 100644
index 0000000..8767621
--- /dev/null
+++ b/code/core/src/test/java/org/apache/tamaya/core/ConfigBuilderTest.java
@@ -0,0 +1,94 @@
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one
+// *  or more contributor license agreements.  See the NOTICE file
+// *  distributed with this work for additional information
+// *  regarding copyright ownership.  The ASF licenses this file
+// *  to you under the Apache License, Version 2.0 (the
+// *  "License"); you may not use this file except in compliance
+// *  with the License.  You may obtain a copy of the License at
+// *
+// *     http://www.apache.org/licenses/LICENSE-2.0
+// *
+// *  Unless required by applicable law or agreed to in writing,
+// *  software distributed under the License is distributed on an
+// *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// *  KIND, either express or implied.  See the License for the
+// *  specific language governing permissions and limitations
+// *  under the License.
+// */
+//package org.apache.tamaya.core;
+//
+//import org.apache.tamaya.TypeLiteral;
+//import org.apache.tamaya.spi.ConfigContext;
+//import org.apache.tamaya.spisupport.DefaultConfigBuilder;
+//import org.junit.Test;
+//
+//import javax.config.Config;
+//import javax.config.spi.ConfigBuilder;
+//import javax.config.spi.ConfigProviderResolver;
+//import javax.config.spi.ConfigSource;
+//import javax.config.spi.Converter;
+//
+//import static org.junit.Assert.*;
+//
+///**
+// * Tests for {@link ConfigBuilder} by atsticks on 06.09.16.
+// */
+//public class ConfigBuilderTest {
+//
+//    private TestConfigSource testConfigSource = new TestConfigSource(){};
+//
+//
+//    @Test
+//    public void addConfigSources_Array() throws Exception {
+//        ConfigSource testPS2 = new TestConfigSource("addConfigSources_Array", 1);
+//        ConfigBuilder b = new DefaultConfigBuilder()
+//                .withSources(testConfigSource, testPS2);
+//        Config cfg = b.build();
+//        assertEquals(2, ConfigContext.of(cfg).getSources().size());
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        // Ensure no sorting happens during add, so switch ordinals!
+//        testPS2 = new TestConfigSource("addConfigSources_Array", 1);
+//        b = ConfigProviderResolver.instance().getBuilder()
+//                .withSources(testPS2, testConfigSource);
+//        cfg = b.build();
+//        assertEquals(2, ConfigContext.of(cfg).getSources().size());
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testConfigSource));
+//        assertTrue(ConfigContext.of(cfg).getSources().contains(testPS2));
+//        assertEquals(ConfigContext.of(cfg).getSources().get(1).getName(), "TestConfigSource");
+//        assertEquals(ConfigContext.of(cfg).getSources().get(0).getName(), "addConfigSources_Array");
+//    }
+//
+//    @Test
+//    @SuppressWarnings({ "rawtypes", "unchecked" })
+//    public void addPropertyConverters_Array() throws Exception {
+//		Converter<String> converter = new Converter<String>(){
+//            @Override
+//            public String convert(String value) {
+//                return value;
+//            }
+//        }; //(value) -> value.toLowerCase();
+//        ConfigBuilder b = ConfigProviderResolver.instance().getBuilder()
+//                .withConverters(converter);
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertTrue(ctx.getConverters(TypeLiteral.of(String.class)).contains(converter));
+//        assertEquals(1, ctx.getConverters().size());
+//        b = ConfigProviderResolver.instance().getBuilder()
+//                .withConverters(converter);
+//        b.withConverters(converter);
+//        assertEquals(1, ctx.getConverters().size());
+//    }
+//
+//    @Test
+//    public void build() throws Exception {
+//        ConfigBuilder b = ConfigProviderResolver.instance().getBuilder();
+//        Config cfg = b.build();
+//        ConfigContext ctx = ConfigContext.of(cfg);
+//        assertNotNull(ctx);
+//        assertTrue(ctx.getSources().isEmpty());
+//        assertTrue(ctx.getPropertyFilters().isEmpty());
+//    }
+//
+//}
\ No newline at end of file


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

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConversionContext.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConversionContext.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConversionContext.java
new file mode 100644
index 0000000..22c4d5b
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConversionContext.java
@@ -0,0 +1,266 @@
+/*
+ * 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.Configuration;
+
+import java.lang.reflect.AnnotatedElement;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * 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 PropertyConverter
+ */
+public class ConversionContext {
+
+    private final Configuration configuration;
+    private final String key;
+    private final TypeLiteral<?> targetType;
+    private final AnnotatedElement annotatedElement;
+    private final List<String> supportedFormats = new ArrayList<>();
+    private final ConfigurationContext configurationContext;
+
+    /**
+     * Private constructor used from builder.
+     * @param builder the builder, not {@code null}.
+     */
+    protected ConversionContext(Builder builder){
+        this.key = builder.key;
+        this.annotatedElement = builder.annotatedElement;
+        this.targetType = builder.targetType;
+        this.supportedFormats.addAll(builder.supportedFormats);
+        this.configuration = builder.configuration;
+        this.configurationContext = builder.configurationContext;
+    }
+
+    /**
+     * 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 String getKey(){
+        return key;
+    }
+
+    /**
+     * Get the target type required.
+     * @return the target type required.
+     */
+    public TypeLiteral<?> getTargetType(){
+        return targetType;
+    }
+
+    /**
+     * Get the annotated element, if conversion is performed using injection mechanisms.
+     * @return the annotated element, or {@code null}.
+     */
+    public AnnotatedElement getAnnotatedElement(){
+        return annotatedElement;
+    }
+
+    /**
+     * Get the configuration, which is targeted.
+     * @return the configuration instance, or {@code null}.
+     */
+    public Configuration 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 void addSupportedFormats(@SuppressWarnings("rawtypes") Class<? extends PropertyConverter> 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 PropertyConverter} instances involved in a conversion.
+     * @return the supported/tried formats, never {@code null}.
+     */
+    public 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 +
+                '}';
+    }
+
+    public ConfigurationContext getConfigurationContext() {
+        return configurationContext;
+    }
+
+    /**
+     * Builder to create new instances of {@link ConversionContext}.
+     */
+    public static final class Builder{
+        /** The backing configuration. */
+        private Configuration configuration;
+        /** The configuration context. */
+        private ConfigurationContext configurationContext;
+        /** The accessed key, or null. */
+        private String key;
+        /** The target type. */
+        private TypeLiteral<?> 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 targetType the target type
+         */
+        public Builder(TypeLiteral<?> targetType) {
+            this(null, null, null, targetType);
+        }
+
+        /**
+         * Creates a new Builder instance.
+         * @param key the requested key, may be null.
+         * @param targetType the target type
+         */
+        public Builder(String key, TypeLiteral<?> targetType) {
+            this(null, null, key, targetType);
+        }
+
+        /**
+         * Creates a new Builder instance.
+         * @param configuration the configuration, not {@code null}.
+         * @param configurationContext configuration context, not {@code null}.
+         * @param key the requested key, may be {@code null}.
+         * @param targetType the target type
+         */
+        public Builder(Configuration configuration, ConfigurationContext configurationContext, String key, TypeLiteral<?> targetType){
+            this.key = key;
+            this.configuration = configuration;
+            this.configurationContext = configurationContext;
+            this.targetType = Objects.requireNonNull(targetType);
+        }
+
+        /**
+         * 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(Configuration configuration){
+            this.configuration = Objects.requireNonNull(configuration);
+            return this;
+        }
+
+        /**
+         * Sets the configuration.
+         * @param configurationContext the configuration, not {@code null}
+         * @return the builder instance, for chaining
+         */
+        public Builder setConfigurationContext(ConfigurationContext configurationContext){
+            this.configurationContext = Objects.requireNonNull(configurationContext);
+            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(@SuppressWarnings("rawtypes") TypeLiteral targetType) {
+            this.targetType = Objects.requireNonNull(targetType);
+            return this;
+        }
+
+        /**
+         * Add the formats provided by a {@link PropertyConverter}. 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 PropertyConverter> 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(){
+            return new ConversionContext(this);
+        }
+
+        @Override
+        public String toString() {
+            return "Builder{" +
+                    "configuration=" + configuration +
+                    "context=" + configurationContext +
+                    ", key='" + key + '\'' +
+                    ", targetType=" + targetType +
+                    ", annotatedElement=" + annotatedElement +
+                    ", supportedFormats=" + supportedFormats +
+                    '}';
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/FilterContext.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/FilterContext.java b/code/compat/src/main/java/org/apache/tamaya/spi/FilterContext.java
new file mode 100644
index 0000000..2851697
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/FilterContext.java
@@ -0,0 +1,140 @@
+/*
+ * 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.Configuration;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A filter context containing all the required values for implementing filtering.
+ *
+ * @see PropertyFilter
+ */
+public class FilterContext {
+    /** The key. */
+    private final PropertyValue value;
+    /** The current context. */
+    private final ConfigurationContext context;
+    @Experimental
+    private Map<String, PropertyValue> configEntries = new HashMap<>();
+    @Experimental
+    private boolean singlePropertyScoped;
+
+
+    /**
+     * Creates a new FilterContext, for filtering of a multi value access
+     * using {@link Configuration#getProperties()}.
+     *
+     * @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 context the current context, not {@code null}.
+     */
+    public FilterContext(PropertyValue value, Map<String,PropertyValue> configEntries, ConfigurationContext context) {
+        Objects.requireNonNull(value, "Value must not be null.");
+        Objects.requireNonNull(configEntries, "Initial configuration entries must be not null.");
+        Objects.requireNonNull(context, "Context must be not null.");
+
+        this.singlePropertyScoped = false;
+        this.value = Objects.requireNonNull(value);
+        this.context = Objects.requireNonNull(context);
+        this.configEntries.putAll(configEntries);
+        this.configEntries = Collections.unmodifiableMap(this.configEntries);
+    }
+
+    /**
+     * Creates a new FilterContext, for filtering of a single value access
+     * using {@link Configuration#getProperties()}.
+     * @param value the value under evaluation, not {@code null}.
+     * @param context the current context, not {@code null}.
+     */
+    public FilterContext(PropertyValue value, ConfigurationContext context) {
+        Objects.requireNonNull(value, "Value must not be null.");
+        Objects.requireNonNull(context, "Context must be not null.");
+
+        this.singlePropertyScoped = true;
+        this.context = Objects.requireNonNull(context);
+        this.value = Objects.requireNonNull(value);
+        this.configEntries = Collections.unmodifiableMap(this.configEntries);
+    }
+
+    /**
+     * Get the current context.
+     * @return the current context, not {@code null}.
+     */
+    public ConfigurationContext getContext(){
+        return context;
+    }
+
+    /**
+     * 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 PropertyValue getProperty() {
+        return value;
+    }
+
+    /**
+     * 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.
+     */
+    @Experimental
+    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 PropertySource}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.
+     */
+    @Experimental
+    public Map<String, PropertyValue> getConfigEntries() {
+        return configEntries;
+    }
+
+    @Override
+    public String toString() {
+        return "FilterContext{value='" + value + "', configEntries=" + configEntries.keySet() + '}';
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/PropertyConverter.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/PropertyConverter.java b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyConverter.java
new file mode 100644
index 0000000..ab96b6b
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyConverter.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+/**
+ * Interface for an property that converts a configured String into something else.
+ * This is used for implementing type conversion from a property (String) to a certain target
+ * type. Hereby the target type can be multi-value (e.g. collections) or complex if needed.
+ * 
+ * @param <T> the type of the type literal
+ */
+@FunctionalInterface
+public interface PropertyConverter<T>{
+
+    /**
+     * Convert the given configuration keys from its String representation into the required target type.
+     * The context instance passed also allows to add a list of supported formats, which is very handy in case a
+     * value could not be converted. This list of supported formats can then shown to the user to give some hints
+     * how a value could be configured.
+     * 
+     * @param value configuration key that needs to be converted
+     * @param context the {@link ConversionContext}, containing the String value and the requested configuration key.
+     * @return converted keys
+     * @see ConversionContext#addSupportedFormats(Class, String...)
+     */
+    T convert(String value, ConversionContext context);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/PropertyFilter.java b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
new file mode 100644
index 0000000..3054496
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.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 PropertyFilter {
+
+    /**
+     * <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.
+     * @param context the filter context, not {@code null}.
+     * @return the filtered value, or {@code null} if the value should be removed alltogether.
+     * @see PropertyValue
+     * @see PropertyValueBuilder
+     */
+    PropertyValue filterProperty(PropertyValue value, FilterContext context);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/PropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/PropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spi/PropertySource.java
new file mode 100644
index 0000000..e38e278
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/PropertySource.java
@@ -0,0 +1,174 @@
+/*
+* 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.Configuration;
+
+import java.util.Collections;
+import java.util.Map;
+
+
+/**
+ * <p>This interface models a provider that serves configuration properties. The contained
+ * properties may be read from a Map of single or several sources (composite).
+ * PropertySources are the building blocks of the final configuration. </p>
+ * <h3>Implementation Requirements</h3>
+ * <p>Implementations of this interface must be</p>
+ * <ul>
+ * <li>Thread safe.</li>
+ * </ul>
+ *
+ * <p>A PropertySourceProvider will get picked up via the
+ * {@link java.util.ServiceLoader} mechanism and can be registered via
+ * {@code META-INF/services/org.apache.tamaya.spi.PropertySource}
+ * </p>
+ * <p>
+ * If you like to addSources multiple PropertySources at the same time
+ * you can use the {@link org.apache.tamaya.spi.PropertySourceProvider}
+ * interface.
+ * </p>
+ */
+public interface PropertySource {
+
+    /**
+     * property name to override default tamaya ordinals
+     */
+    String TAMAYA_ORDINAL = "tamaya.ordinal";
+
+    /**
+     * A resusable instance of an empty PropertySource.
+     */
+    PropertySource EMPTY = new PropertySource() {
+
+        @Override
+        public int getOrdinal() {
+            return Integer.MIN_VALUE;
+        }
+
+        @Override
+        public String getName() {
+            return "<empty>";
+        }
+
+        @Override
+        public PropertyValue get(String key) {
+            return null;
+        }
+
+        @Override
+        public Map<String, PropertyValue> getProperties() {
+            return Collections.emptyMap();
+        }
+
+        @Override
+        public boolean isScannable() {
+            return false;
+        }
+
+        @Override
+        public String toString(){
+            return "PropertySource.EMPTY";
+        }
+    };
+
+
+    /**
+     * The ordinal value is the default ordering parameter which definines the default order of
+     * auto-discovered property sources. Ordering of property sources is important since values
+     * from property sources with higher ordinal values override values from less significant
+     * property sources.
+     *
+     * By default Tamaya includes the following property sources:
+     * <ol>
+     *     <li>Properties file values (/META-INF/javaconfiguration.properties) (ordinal 100)</li>
+     *     <li>JNDI values (ordinal 200, only when adding the {@code tamaya-jndi} extension module)</li>
+     *     <li>Environment properties (ordinal 300)</li>
+     *     <li>System properties (ordinal 1000)</li>
+     * </ol>
+     *
+     * <p><b>Important Hints for custom implementations</b>:</p>
+     * <p>
+     * If a custom implementation should be invoked <b>before</b> the default implementations, use a value &gt; 1000
+     * </p>
+     * <p>
+     * If a custom implementation should be invoked <b>after</b> the default implementations, use a value &lt; 100
+     * </p>
+     *
+     * <p>Reordering of the default order of the config-sources:</p>
+     * <p>Example: If the properties file/s should be used <b>before</b> the other implementations,
+     * you have to configure an ordinal &gt; 1000. That means, you have to add e.g. tamaya.ordinal=401 to
+     * /META-INF/javaconfiguration.properties . Hint: In case of property files every file is handled as independent
+     * config-source, but all of them have ordinal 400 by default (and can be reordered in a fine-grained manner.</p>
+     *
+     * In cases where it is not possible to change a config sources ordinal value, you may have several options:
+     * <ul>
+     *     <li>you can addSources an alternate implementation of {@link PropertyValueCombinationPolicy}.</li>
+     *     <li>you can use a {@link ConfigurationContextBuilder} to redefine the source order and finally use
+     *     {@link org.apache.tamaya.ConfigurationProvider#setConfiguration(Configuration)} to
+     *     change the current default {@link Configuration}.</li>
+     *     <li>finally, the imeplementor of this API may define alternate mechanism to reconfigure an ordinal
+     *     in a vendor specific way.</li>
+     * </ul>
+     * @return the 'importance' aka ordinal of the configured values. The higher, the more important.
+     */
+    int getOrdinal();
+
+
+    /**
+     * Get the name of the property source. The name should be unique for the type of source, whereas the id is used
+     * to ensure unique identity, either locally or remotely.
+     * @return the configuration's name, never {@code null}.
+     */
+    String getName();
+
+    /**
+     * Access a property.
+     *
+     * @param key the property's key, not {@code null}.
+     * @return the property value map, where {@code map.get(key) == value}, including also any metadata. In case a
+     * value is null, simply return {@code null}.
+     */
+    PropertyValue get(String key);
+
+    /**
+     * Access the current properties as Set. The resulting Map may not return all items accessible, e.g.
+     * when the underlying storage does not support iteration of its entries.
+     {@code null}
+     * @return the corresponding map, never null.
+     */
+    Map<String, PropertyValue> getProperties();
+
+    /**
+     * Determines if this config source can be scanned for its list of properties.
+     *
+     * <p>
+     * PropertySources which are not scannable might not be able to find all the
+     * configured values to provide via {@link #getProperties()}. This might happen
+     * if the underlying storage doesn't support listing.
+     * </p>
+     *
+     * @return {@code true} if this PropertySource can be scanned for its list of properties,
+     *         {@code false} if it cannot/should not be scanned.
+     */
+    default boolean isScannable(){
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java b/code/compat/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
new file mode 100644
index 0000000..aa09ad8
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
@@ -0,0 +1,61 @@
+/*
+ * 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.Collection;
+import java.util.Collections;
+
+/**
+ * <p>Implement this interfaces to provide a PropertySource provider which
+ * is able to addSources multiple PropertySources. This is e.g. needed if
+ * there are multiple property files of a given config file name.</p>
+ * 
+ * <p>If a PropertySource like JNDI only exists once, then there is no need
+ * to implement it via the PropertySourceProvider but should directly
+ * expose a {@link PropertySource}.</p>
+ *
+ * <p>A PropertySourceProvider will get picked up via the
+ * {@link java.util.ServiceLoader} mechanism and must get registered via
+ * META-INF/services/org.apache.tamaya.spi.PropertySourceProvider</p>
+ */
+@FunctionalInterface
+public interface PropertySourceProvider {
+
+    /**
+     * A resusable instance of an empty PropertySource.
+     */
+    PropertySourceProvider EMPTY = new PropertySourceProvider() {
+
+        @Override
+        public Collection<PropertySource> getPropertySources() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public String toString(){
+            return "PropertySourceProvider(empty)";
+        }
+    };
+
+    /**
+     * @return For each e.g. property file, we return a single PropertySource
+     *         or an empty list if no PropertySource exists.
+     */
+    Collection<PropertySource> getPropertySources();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValue.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValue.java b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValue.java
new file mode 100644
index 0000000..c538de7
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValue.java
@@ -0,0 +1,232 @@
+/*
+ * 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.Collections;
+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 PropertyValue implements Serializable{
+    private static final long serialVersionUID = 1L;
+    /** The requested key. */
+    private String key;
+    /** The value. */
+    private String value;
+    /** The source of the value. */
+    private String source;
+    /** Additional metadata provided by the provider. */
+    private Map<String,String> metaEntries = new HashMap<>();
+
+    PropertyValue(PropertyValueBuilder builder){
+        this.key = Objects.requireNonNull(builder.key);
+        this.value = builder.value;
+        this.source = Objects.requireNonNull(builder.source);
+        if(builder.metaEntries !=null) {
+            this.metaEntries.putAll(builder.metaEntries);
+        }
+    }
+
+    /**
+     * Creates a new instance
+     * @param key the key, not {@code null}.
+     * @param value the value, not {@code null}.
+     * @param source the source, typically the name of the {@link PropertySource} providing
+     *               the value, not {@code null}.
+     */
+    private PropertyValue(String key, String value, String source){
+        this.key = Objects.requireNonNull(key, "Key is required.");
+        this.value = Objects.requireNonNull(value, "Value is required.");
+        this.source = Objects.requireNonNull(source, "Source is required.");
+    }
+
+    /**
+     * The requested key.
+     * @return the, key never {@code null}.
+     */
+    public String getKey() {
+        return key;
+    }
+
+    /**
+     * The source.
+     * @return the source, which provided the value, not {@code null}.
+     * @see PropertySource#getName() .
+     */
+    public String getSource() {
+        return this.source;
+    }
+
+
+    /**
+     * The value.
+     * @return the value, in case a value is null it is valid to return {#code null} as result for
+     * {@link PropertySource#get(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 Map<String, String> getMetaEntries() {
+        return Collections.unmodifiableMap(metaEntries);
+    }
+
+    /**
+     * Creates a new builder instance.
+     * @param key the key, not {@code null}.
+     * @param source the source, typically the name of the {@link PropertySource}
+     *               providing the value, not {@code null}.
+     * @return a new builder instance.
+     */
+    public static PropertyValueBuilder builder(String key, String source){
+        Objects.requireNonNull(key, "Key must be given.");
+        Objects.requireNonNull(source, "Source must be given");
+
+        return new PropertyValueBuilder(key, source);
+    }
+
+    /**
+     * Creates a new builder instance.
+     * @param key the key, not {@code null}.
+     * @param value the property value, not {@code null}.
+     * @param source the source, typically the name of the {@link PropertySource}
+     *               providing the value, not {@code null}.
+     * @return a new builder instance.
+     */
+    public static PropertyValueBuilder builder(String key, String value, String source) {
+        Objects.requireNonNull(key, "Key must be given.");
+        Objects.requireNonNull(value, "Value must be given");
+        Objects.requireNonNull(source, "Source must be given.");
+
+        return new PropertyValueBuilder(key, value, source);
+    }
+
+
+    /**
+     * Creates a new PropertyValue without any metadata..
+     * @param key the key, not {@code null}.
+     * @param value the value.
+     * @param source the source, typically the name of the {@link PropertySource}
+     *               providing the value, not  {@code null}.
+     * @return a new property value instance, or {@code null},
+     *         if the value passed is {@code null}..
+     */
+    public static PropertyValue of(String key, String value, String source) {
+        if (value==null) {
+            return null;
+        }
+        return new PropertyValue(key, value, source);
+    }
+
+    /**
+     * Access the given key from this value. Valid keys are the key or any meta-context key.
+     * @param key the key, not {@code null}.
+     * @return the value found, or {@code null}.
+     */
+    public String getMetaEntry(String key) {
+        return this.metaEntries.get(Objects.requireNonNull(key));
+    }
+
+    /**
+     * Creates a new builder instance based on this item.
+     * @return a new builder, never null.
+     */
+    public PropertyValueBuilder toBuilder() {
+        return new PropertyValueBuilder(this.getKey(), this.getSource())
+                .setValue(this.getValue())
+        .setMetaEntries(this.metaEntries);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PropertyValue)) return false;
+        PropertyValue that = (PropertyValue) o;
+        return Objects.equals(getKey(), that.getKey()) &&
+                Objects.equals(getValue(), that.getValue()) &&
+                Objects.equals(getSource(), that.getSource()) &&
+                Objects.equals(getMetaEntries(), that.getMetaEntries());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getKey(), getValue(), getSource(),
+                getMetaEntries());
+    }
+
+    @Override
+    public String toString() {
+        return "PropertyValue{" +
+                "key='" + key + '\'' +
+                ", value='" + value + '\'' +
+                ", source='" + source + '\'' +
+                (metaEntries.isEmpty()?"":", metaEntries=" + metaEntries) +
+                '}';
+    }
+
+    /**
+     * 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}.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,PropertyValue> map(Map<String, String> config, String source) {
+        Map<String,PropertyValue> result = new HashMap<>(config.size());
+        for(Map.Entry<String,String> en:config.entrySet()){
+            result.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), source));
+        }
+        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,PropertyValue> 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,PropertyValue> result = new HashMap<>(config.size());
+
+        for(Map.Entry<String,String> en:config.entrySet()){
+            PropertyValue value = new PropertyValueBuilder(en.getKey(), source).setValue(en.getValue())
+                                                                               .addMetaEntries(metaData).build();
+            result.put(en.getKey(), value);
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
new file mode 100644
index 0000000..af01987
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
@@ -0,0 +1,196 @@
+/*
+ * 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.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Builder to create a {@link PropertyValue} instance.
+ */
+public class PropertyValueBuilder {
+    /** The key accessed. */
+    String key;
+    /** The property value. */
+    String value;
+    /** The property vaoue source. */
+    String source;
+    /** additional metadata entries (optional). */
+    Map<String,String> metaEntries = new HashMap<>();
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
+     * Before calling build at least a {@link #value} and its {@link #source}
+     * must be set.
+     */
+    PropertyValueBuilder(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 source property source.
+     */
+    PropertyValueBuilder(String key, String source) {
+        this.key = Objects.requireNonNull(key);
+        this.source = Objects.requireNonNull(source);
+    }
+
+    /**
+     * 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 PropertySource#get(String)} should return {@code null}.
+     * @param source property source.
+     */
+    PropertyValueBuilder(String key, String value, String source) {
+        this.key = Objects.requireNonNull(key);
+        this.value = value;
+        this.source = Objects.requireNonNull(source);
+    }
+
+    /**
+     * Replaces/sets the context data.
+     * @param metaEntries the context data to be applied, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setMetaEntries(Map<String, String> metaEntries) {
+        this.metaEntries.clear();
+        this.metaEntries.putAll(metaEntries);
+        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 PropertyValueBuilder addMetaEntry(String key, Object value) {
+        Objects.requireNonNull(key, "Meta key must be given.");
+        Objects.requireNonNull(value, "Meta value must be given.");
+
+        this.metaEntries.put(key, String.valueOf(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 PropertyValueBuilder addMetaEntries(Map<String, String> metaEntries) {
+        this.metaEntries.putAll(metaEntries);
+        return this;
+    }
+
+    /**
+     * Removes a meta entry.
+     * @param key the entry's key, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder removeMetaEntry(String key) {
+        Objects.requireNonNull(key, "Key must be given.");
+
+        this.metaEntries.remove(key);
+        return this;
+    }
+
+    /**
+     * Get the value's context data.
+     * @return the context data, not {@code null}.
+     */
+    public Map<String,String> getMetaEntries() {
+        return Collections.unmodifiableMap(this.metaEntries);
+    }
+
+    /**
+     * Changes the entry's key, mapping also corresponding context entries.
+     * @param key the new key, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder mapKey(String key) {
+        // todo obf if (1==1) throw new RuntimeException("No tests written.");
+        Map<String,String> newContext = new HashMap<>();
+        for(Map.Entry<String,String> en:this.metaEntries.entrySet()){
+            if(en.getKey().startsWith("_"+this.key)){
+                newContext.put("_"+key+'.'+ en.getKey().substring(this.key.length()+1), en.getValue());
+            }else{
+                newContext.put(en.getKey(), en.getValue());
+            }
+        }
+        this.metaEntries = newContext;
+        this.key = key;
+        return this;
+    }
+
+    /**
+     * Sets a new key.
+     * @param key the new key, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder 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 PropertyValueBuilder setValue(String value) {
+        this.value = Objects.requireNonNull(value, "Value must be given.");
+
+        return this;
+    }
+
+    /**
+     * Sets a new source.
+     * @param source the new source, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setSource(String source) {
+        // todo obf if (1==1) throw new RuntimeException("No tests written.");
+        this.source = Objects.requireNonNull(source);
+        return this;
+    }
+
+    /**
+     * Creates a new immutable {@link PropertyValue}.
+     * @return a new immutable {@link PropertyValue}, never {@code null}.
+     */
+    public PropertyValue build(){
+        return new PropertyValue(this);
+    }
+
+    @Override
+    public String toString() {
+        return "PropertyValueBuilder{" +
+                "key='" + key + '\'' +
+                "value='" + value + '\'' +
+                ", metaEntries=" + metaEntries +
+                '}';
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
new file mode 100644
index 0000000..14640e6
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+
+/**
+ * Policy that determines how the final value of a configuration entry is evaluated. An instances of this
+ * interface can be registered to get control how multiple PropertySources are combined. This is useful in cases
+ * where the default overriding policy as implemented in {@link #DEFAULT_OVERRIDING_POLICY} is not matching
+ * the need of the current application, e.g. then entries containing multiple values should be combined to new
+ * values instead of overridden.
+ */
+public interface PropertyValueCombinationPolicy {
+
+    /**
+     * Default overriding collector, where each existing entry ({@code current} is overridden by a subsequent non-null
+     * entry evaluated by {@code propertySource.get(key)}.
+     */
+    PropertyValueCombinationPolicy DEFAULT_OVERRIDING_POLICY = new PropertyValueCombinationPolicy(){
+
+        @Override
+        public PropertyValue collect(PropertyValue currentValue, String key, PropertySource propertySource) {
+            PropertyValue value = propertySource.get(key);
+            return value!=null?value:currentValue;
+        }
+    };
+
+    /**
+     * @deprecated Use {@linkplain #DEFAULT_OVERRIDING_POLICY} instead. Will be removed in 1.0.
+     */
+    @Deprecated
+    PropertyValueCombinationPolicy DEFAULT_OVERRIDING_COLLECTOR = DEFAULT_OVERRIDING_POLICY;
+
+
+        /**
+     * Method that is called for each value evaluated by a PropertySource for the given key. This method is called
+     * either when a single key is accessed, e.g. by calling {@code org.apache.tamaya.Configuration.getXXX}, but also
+     * when the full configuration property map is accessed by calling
+     * {@link org.apache.tamaya.Configuration#getProperties()}.
+     *
+     * @param currentValue the current value, including metadata entries. If no such key is present the current value
+     *                     is null.
+     *                     The collector should either combine the existing value with value from {@code currentValue}
+     *                     or replace the value in {@code currentValue} with {@code valueRead}, hereby returning the
+     *                     result to be used as new {@code currentValue}.
+     * @param key The current key to be evaluated.
+     * @param propertySource The PropertySource that may return an value for the given key. The PropertySource given
+     *                       may be evaluated for additional meta-data, how the given values are to be combined.
+     *                       Note that the value returned by a PropertySource can be null. In that case
+     *                       {@code currentValue} should be returned in almost all cases.
+     * @return the value to be used for future evaluation, including metadata entries.
+     */
+    PropertyValue collect(PropertyValue currentValue, String key, PropertySource propertySource);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/package-info.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/package-info.java b/code/compat/src/main/java/org/apache/tamaya/spi/package-info.java
new file mode 100644
index 0000000..49dbab9
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package contains the Apache Tamaya SPI artifacts.
+ */
+@org.osgi.annotation.versioning.Version("0.4")
+package org.apache.tamaya.spi;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/ConfigValueEvaluator.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/ConfigValueEvaluator.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/ConfigValueEvaluator.java
new file mode 100644
index 0000000..92fd614
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/ConfigValueEvaluator.java
@@ -0,0 +1,48 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Map;
+
+
+/**
+ * Component SPI which encapsulates the evaluation of a single or full <b>raw</b>value
+ * for a {@link ConfigurationContext}.
+ */
+public interface ConfigValueEvaluator {
+
+    /**
+     * Evaluates single value using a {@link ConfigurationContext}.
+     * @param key the config key, not null.
+     * @param context the context, not null.
+     * @return the value, or null.
+     */
+    PropertyValue evaluteRawValue(String key, ConfigurationContext context);
+
+    /**
+     * Evaluates all property values from a {@link ConfigurationContext}.
+     * @param context the context, not null.
+     * @return the value, or null.
+     */
+    Map<String, PropertyValue> evaluateRawValues(ConfigurationContext context);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigValueEvaluator.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigValueEvaluator.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigValueEvaluator.java
new file mode 100644
index 0000000..d50ed7d
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigValueEvaluator.java
@@ -0,0 +1,70 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
+ * chain of {@link PropertySource} and {@link PropertyFilter}
+ * instance to evaluate the current Configuration.
+ */
+public class DefaultConfigValueEvaluator implements ConfigValueEvaluator{
+
+    @Override
+    public PropertyValue evaluteRawValue(String key, ConfigurationContext context) {
+        PropertyValue unfilteredValue = null;
+        for (PropertySource propertySource : context.getPropertySources()) {
+            unfilteredValue = context.getPropertyValueCombinationPolicy().
+                    collect(unfilteredValue, key, propertySource);
+        }
+        if(unfilteredValue==null || unfilteredValue.getValue()==null){
+            return null;
+        }
+        return unfilteredValue;
+    }
+
+    @Override
+    public Map<String, PropertyValue> evaluateRawValues(ConfigurationContext context) {
+        Map<String, PropertyValue> result = new HashMap<>();
+        for (PropertySource propertySource : context.getPropertySources()) {
+            for (Map.Entry<String,PropertyValue> propEntry: propertySource.getProperties().entrySet()) {
+                PropertyValue unfilteredValue = result.get(propEntry.getKey());
+                unfilteredValue = context.getPropertyValueCombinationPolicy().
+                        collect(unfilteredValue, propEntry.getKey(), propertySource);
+                if(unfilteredValue!=null){
+                    result.put(unfilteredValue.getKey(), unfilteredValue);
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "DefaultConfigEvaluator{}";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.java
new file mode 100644
index 0000000..bdbd09c
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfiguration.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.spisupport;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.ConfigQuery;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigurationContext} to evaluate the
+ * chain of {@link PropertySource} and {@link org.apache.tamaya.spi.PropertyFilter}
+ * instance to evaluate the current Configuration.
+ */
+public class DefaultConfiguration implements Configuration {
+    /**
+     * The logger.
+     */
+    private static final Logger LOG = Logger.getLogger(DefaultConfiguration.class.getName());
+
+    /**
+     * The current {@link ConfigurationContext} of the current instance.
+     */
+    private final ConfigurationContext configurationContext;
+
+    /**
+     * EvaluationStrategy
+     */
+    private ConfigValueEvaluator configEvaluator = loadConfigValueEvaluator();
+
+    private ConfigValueEvaluator loadConfigValueEvaluator() {
+        ConfigValueEvaluator eval = null;
+        try{
+            eval = ServiceContextManager.getServiceContext()
+                    .getService(ConfigValueEvaluator.class);
+        }catch(Exception e){
+            LOG.log(Level.WARNING, "Failed to load ConfigValueEvaluator from ServiceContext, using default.", e);
+        }
+        if(eval==null){
+            eval = new DefaultConfigValueEvaluator();
+        }
+        return eval;
+    }
+
+
+    /**
+     * Constructor.
+     * @param configurationContext The configuration Context to be used.
+     */
+    public DefaultConfiguration(ConfigurationContext configurationContext){
+        this.configurationContext = Objects.requireNonNull(configurationContext);
+    }
+
+    /**
+     * Get a given value, filtered with the context's filters as needed.
+     * @param key the property's key, not null.
+     * @return the filtered value, or null.
+     */
+    @Override
+    public String get(String key) {
+        Objects.requireNonNull(key, "Key must not be null.");
+
+        PropertyValue value = configEvaluator.evaluteRawValue(key, configurationContext);
+        if(value==null || value.getValue()==null){
+            return null;
+        }
+        value = PropertyFiltering.applyFilter(value, configurationContext);
+        if(value!=null){
+            return value.getValue();
+        }
+        return null;
+    }
+
+    /**
+     * Evaluates the raw value using the context's PropertyValueCombinationPolicy.
+     * @param key the key, not null.
+     * @return the value, before filtering is applied.
+     */
+    protected PropertyValue evaluteRawValue(String key) {
+        List<PropertySource> propertySources = configurationContext.getPropertySources();
+        PropertyValue filteredValue = null;
+        PropertyValueCombinationPolicy combinationPolicy = this.configurationContext
+                .getPropertyValueCombinationPolicy();
+        for (PropertySource propertySource : propertySources) {
+            filteredValue = combinationPolicy.collect(filteredValue, key, propertySource);
+        }
+        return filteredValue;
+    }
+
+
+    @Override
+    public String getOrDefault(String key, String defaultValue) {
+        Objects.requireNonNull(key, "Key must not be null.");
+
+        String val = get(key);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+        Objects.requireNonNull(key, "Key must not be null.");
+        Objects.requireNonNull(type, "Target type must not be null");
+
+        T val = get(key, type);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    /**
+     * Get the current properties, composed by the loaded {@link PropertySource} and filtered
+     * by registered {@link org.apache.tamaya.spi.PropertyFilter}.
+     *
+     * @return the final properties.
+     */
+    @Override
+    public Map<String, String> getProperties() {
+        Map<String, PropertyValue> filtered = PropertyFiltering.applyFilters(
+                configEvaluator.evaluateRawValues(configurationContext),
+                configurationContext);
+        Map<String,String> result = new HashMap<>();
+        for(PropertyValue val:filtered.values()){
+            if(val.getValue()!=null) {
+                result.put(val.getKey(), val.getValue());
+                // TODO: Discuss metadata handling...
+                result.putAll(val.getMetaEntries());
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * Accesses the current String value for the given key and tries to convert it
+     * using the {@link PropertyConverter} instances provided by the current
+     * {@link ConfigurationContext}.
+     *
+     * @param key  the property's absolute, or relative path, e.g. @code
+     *             a/b/c/d.myProperty}, never {@code null}.
+     * @param type The target type required, not {@code null}.
+     * @param <T>  the value type
+     * @return the converted value, never {@code null}.
+     */
+    @Override
+    public <T> T get(String key, Class<T> type) {
+        return get(key, TypeLiteral.of(type));
+    }
+
+    /**
+     * Accesses the current String value for the given key and tries to convert it
+     * using the {@link PropertyConverter} instances provided by the current
+     * {@link ConfigurationContext}.
+     *
+     * @param key  the property's absolute, or relative path, e.g. @code
+     *             a/b/c/d.myProperty}.
+     * @param type The target type required, not null.
+     * @param <T>  the value type
+     * @return the converted value, never null.
+     */
+    @Override
+    public <T> T get(String key, TypeLiteral<T> type) {
+        Objects.requireNonNull(key, "Key must not be null.");
+        Objects.requireNonNull(type, "Target type must not be null");
+
+        return convertValue(key, get(key), type);
+    }
+
+    @SuppressWarnings("unchecked")
+	protected <T> T convertValue(String key, String value, TypeLiteral<T> type) {
+        if (value != null) {
+            List<PropertyConverter<T>> converters = configurationContext.getPropertyConverters(type);
+            ConversionContext context = new ConversionContext.Builder(this, this.configurationContext, key, type)
+                    .build();
+            for (PropertyConverter<T> converter : converters) {
+                try {
+                    T t = converter.convert(value, context);
+                    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(TypeLiteral.of(String.class))){
+                return (T)value;
+            }
+            // unsupported type, throw an exception
+            throw new ConfigException("Unparseable config value for type: " + type.getRawType().getName() + ": " + key +
+                    ", supported formats: " + context.getSupportedFormats());
+        }
+        return null;
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
+        Objects.requireNonNull(key);
+        Objects.requireNonNull(type);
+
+        T val = get(key, type);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    @Override
+    public Configuration with(ConfigOperator operator) {
+        return operator.operate(this);
+    }
+
+    @Override
+    public <T> T query(ConfigQuery<T> query) {
+        return query.query(this);
+    }
+
+    @Override
+    public ConfigurationContext getContext() {
+        return this.configurationContext;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        DefaultConfiguration that = (DefaultConfiguration) o;
+
+        if (!configurationContext.equals(that.configurationContext)) return false;
+        return configEvaluator.getClass().equals(that.configEvaluator.getClass());
+    }
+
+    @Override
+    public int hashCode() {
+        int result = configurationContext.hashCode();
+        result = 31 * result + configEvaluator.getClass().hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Configuration{\n " +
+                configurationContext +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
new file mode 100644
index 0000000..1b3f1ce
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/DefaultConfigurationBuilder.java
@@ -0,0 +1,239 @@
+/*
+ * 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.spisupport;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.*;
+import org.apache.tamaya.spi.ConfigurationBuilder;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Default implementation of {@link ConfigurationBuilder}.
+ */
+public class DefaultConfigurationBuilder implements ConfigurationBuilder {
+
+    protected final DefaultConfigurationContextBuilder contextBuilder;
+
+    /**
+     * Creates a new builder instance.
+     */
+    public DefaultConfigurationBuilder() {
+        this.contextBuilder = new DefaultConfigurationContextBuilder();
+    }
+
+    /**
+     * Creates a new builder instance.
+     */
+    public DefaultConfigurationBuilder(ConfigurationContext context) {
+        this.contextBuilder = new DefaultConfigurationContextBuilder(context);
+    }
+
+    /**
+     * Creates a new builder instance initializing it with the given context.
+     * @param configuration the configuration to be used, not null.
+     */
+    public DefaultConfigurationBuilder(Configuration configuration) {
+        this.contextBuilder = new DefaultConfigurationContextBuilder(configuration.getContext());
+    }
+
+    /**
+     * Allows to set configuration context during unit tests.
+     */
+    public ConfigurationBuilder setConfiguration(Configuration configuration) {
+        this.contextBuilder.setContext(configuration.getContext());
+        return this;
+    }
+
+
+    @Override
+    public ConfigurationBuilder setContext(ConfigurationContext context) {
+        this.contextBuilder.setContext(context);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder addPropertySources(PropertySource... sources){
+        this.contextBuilder.addPropertySources(sources);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder addPropertySources(Collection<PropertySource> sources){
+        this.contextBuilder.addPropertySources(sources);
+        return this;
+    }
+
+    public ConfigurationBuilder addDefaultPropertyFilters() {
+        this.contextBuilder.addDefaultPropertyFilters();
+        return this;
+    }
+
+    public ConfigurationBuilder addDefaultPropertySources() {
+        this.contextBuilder.addDefaultPropertySources();
+        return this;
+    }
+
+    public ConfigurationBuilder addDefaultPropertyConverters() {
+        this.contextBuilder.addDefaultPropertyConverters();
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertySources(PropertySource... propertySources) {
+        this.contextBuilder.removePropertySources(propertySources);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertySources(Collection<PropertySource> propertySources) {
+        this.contextBuilder.removePropertySources(propertySources);
+        return this;
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return this.contextBuilder.getPropertySources();
+    }
+
+    @Override
+    public ConfigurationBuilder increasePriority(PropertySource propertySource) {
+        this.contextBuilder.increasePriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder decreasePriority(PropertySource propertySource) {
+        this.contextBuilder.decreasePriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder highestPriority(PropertySource propertySource) {
+        this.contextBuilder.highestPriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder lowestPriority(PropertySource propertySource) {
+        this.contextBuilder.lowestPriority(propertySource);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder addPropertyFilters(Collection<PropertyFilter> filters){
+        this.contextBuilder.addPropertyFilters(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder addPropertyFilters(PropertyFilter... filters){
+        this.contextBuilder.addPropertyFilters(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertyFilters(PropertyFilter... filters) {
+        this.contextBuilder.removePropertyFilters(filters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+        this.contextBuilder.removePropertyFilters(filters);
+        return this;
+    }
+
+
+    @Override
+    public <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                    PropertyConverter<T>... converters) {
+        this.contextBuilder.removePropertyConverters(typeToConvert, converters);
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                    Collection<PropertyConverter<T>> converters) {
+        this.contextBuilder.removePropertyConverters(typeToConvert, converters);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder removePropertyConverters(TypeLiteral<?> typeToConvert) {
+        this.contextBuilder.removePropertyConverters(typeToConvert);
+        return this;
+    }
+
+
+    @Override
+    public ConfigurationBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy combinationPolicy){
+        this.contextBuilder.setPropertyValueCombinationPolicy(combinationPolicy);
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> type, PropertyConverter<T>... propertyConverters){
+        this.contextBuilder.addPropertyConverters(type, propertyConverters);
+        return this;
+    }
+
+    @Override
+    public <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> type, Collection<PropertyConverter<T>> propertyConverters){
+        this.contextBuilder.addPropertyConverters(type, propertyConverters);
+        return this;
+    }
+
+    /**
+     * Builds a new configuration based on the configuration of this builder instance.
+     *
+     * @return a new {@link org.apache.tamaya.Configuration configuration instance},
+     *         never {@code null}.
+     */
+    @Override
+    public Configuration build() {
+        return new DefaultConfiguration(this.contextBuilder.build());
+    }
+
+    @Override
+    public ConfigurationBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator) {
+        this.contextBuilder.sortPropertyFilter(comparator);
+        return this;
+    }
+
+    @Override
+    public ConfigurationBuilder sortPropertySources(Comparator<PropertySource> comparator) {
+        this.contextBuilder.sortPropertySources(comparator);
+        return this;
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return this.contextBuilder.getPropertyFilters();
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter() {
+        return this.contextBuilder.getPropertyConverter();
+    }
+}


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

Posted by an...@apache.org.
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/d0e14ed7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/d0e14ed7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/d0e14ed7

Branch: refs/heads/configjsr
Commit: d0e14ed705b464f3d15f3bae5979cc90df275dc9
Parents: 9bc56a3
Author: Anatole Tresch <an...@apache.org>
Authored: Sun Dec 10 23:06:52 2017 +0100
Committer: Anatole Tresch <an...@apache.org>
Committed: Sun Dec 10 23:06:53 2017 +0100

----------------------------------------------------------------------
 code/base/bnd.bnd                               |  31 ++
 code/base/pom.xml                               |  91 ++++
 code/compat/bnd.bnd                             |  34 ++
 code/compat/pom.xml                             |  70 +++
 .../java/org/apache/tamaya/ConfigException.java |  44 ++
 .../java/org/apache/tamaya/ConfigOperator.java  |  38 ++
 .../java/org/apache/tamaya/ConfigQuery.java     |  37 ++
 .../java/org/apache/tamaya/Configuration.java   | 180 +++++++
 .../apache/tamaya/ConfigurationProvider.java    | 138 ++++++
 .../java/org/apache/tamaya/package-info.java    |  23 +
 .../apache/tamaya/spi/ConfigurationBuilder.java | 347 ++++++++++++++
 .../apache/tamaya/spi/ConfigurationContext.java | 172 +++++++
 .../tamaya/spi/ConfigurationContextBuilder.java | 334 +++++++++++++
 .../tamaya/spi/ConfigurationProviderSpi.java    | 128 +++++
 .../apache/tamaya/spi/ConversionContext.java    | 266 +++++++++++
 .../org/apache/tamaya/spi/FilterContext.java    | 140 ++++++
 .../apache/tamaya/spi/PropertyConverter.java    |  44 ++
 .../org/apache/tamaya/spi/PropertyFilter.java   |  51 ++
 .../org/apache/tamaya/spi/PropertySource.java   | 174 +++++++
 .../tamaya/spi/PropertySourceProvider.java      |  61 +++
 .../org/apache/tamaya/spi/PropertyValue.java    | 232 +++++++++
 .../apache/tamaya/spi/PropertyValueBuilder.java | 196 ++++++++
 .../spi/PropertyValueCombinationPolicy.java     |  71 +++
 .../org/apache/tamaya/spi/package-info.java     |  24 +
 .../tamaya/spisupport/ConfigValueEvaluator.java |  48 ++
 .../spisupport/DefaultConfigValueEvaluator.java |  70 +++
 .../tamaya/spisupport/DefaultConfiguration.java | 281 +++++++++++
 .../spisupport/DefaultConfigurationBuilder.java | 239 ++++++++++
 .../spisupport/DefaultConfigurationContext.java | 277 +++++++++++
 .../DefaultConfigurationContextBuilder.java     | 431 +++++++++++++++++
 .../apache/tamaya/spisupport/EnumConverter.java |  39 ++
 .../spisupport/PriorityServiceComparator.java   |  84 ++++
 .../spisupport/PropertyConverterManager.java    | 472 +++++++++++++++++++
 .../spisupport/PropertyFilterComparator.java    |  72 +++
 .../tamaya/spisupport/PropertyFiltering.java    | 123 +++++
 .../spisupport/PropertySourceComparator.java    | 120 +++++
 .../tamaya/spisupport/RegexPropertyFilter.java  |  84 ++++
 .../propertysource/BasePropertySource.java      | 172 +++++++
 .../propertysource/BuildablePropertySource.java | 231 +++++++++
 .../BuildablePropertySourceProvider.java        | 114 +++++
 .../propertysource/CLIPropertySource.java       | 137 ++++++
 .../EnvironmentPropertySource.java              | 287 +++++++++++
 .../JavaConfigurationPropertySource.java        | 134 ++++++
 .../propertysource/MapPropertySource.java       | 102 ++++
 .../PropertiesResourcePropertySource.java       | 109 +++++
 .../propertysource/SimplePropertySource.java    | 284 +++++++++++
 .../propertysource/SystemPropertySource.java    | 199 ++++++++
 .../propertysource/WrappedPropertySource.java   | 126 +++++
 .../spisupport/propertysource/package-info.java |  23 +
 .../compat/src/main/resources/tamaya-banner.txt |  11 +
 .../org/apache/tamaya/ConfigExceptionTest.java  |  45 ++
 .../org/apache/tamaya/ConfigurationTest.java    |  63 +++
 .../org/apache/tamaya/TestConfiguration.java    | 138 ++++++
 .../tamaya/TestConfigurationProvider.java       |  76 +++
 .../java/org/apache/tamaya/TypeLiteralTest.java |  91 ++++
 .../tamaya/spi/ConversionContextTest.java       | 193 ++++++++
 .../apache/tamaya/spi/FilterContextTest.java    | 157 ++++++
 .../tamaya/spi/ServiceContextManagerTest.java   | 105 +++++
 .../apache/tamaya/spi/ServiceContextTest.java   | 128 +++++
 .../apache/tamaya/spi/TestServiceContext.java   | 120 +++++
 .../tamaya/spisupport/RegexFilterTest.java      |  75 +++
 ...g.apache.tamaya.spi.ConfigurationProviderSpi |  19 +
 .../org.apache.tamaya.spi.ServiceContext        |  19 +
 .../org/apache/tamaya/core/BannerManager.java   | 163 +++++++
 .../tamaya/core/OSGIServiceComparator.java      |  70 +++
 .../apache/tamaya/core/OSGIServiceContext.java  | 187 ++++++++
 .../apache/tamaya/core/OSGIServiceLoader.java   | 254 ++++++++++
 .../core/TamayaConfigProviderResolver.java      |  92 ++++
 .../core/converters/BigDecimalConverter.java    |  78 +++
 .../core/converters/BigIntegerConverter.java    | 107 +++++
 .../core/converters/BooleanConverter.java       |  74 +++
 .../tamaya/core/converters/ByteConverter.java   |  84 ++++
 .../tamaya/core/converters/CharConverter.java   |  81 ++++
 .../tamaya/core/converters/ClassConverter.java  |  79 ++++
 .../tamaya/core/converters/ConvertQuery.java    |  81 ++++
 .../core/converters/CurrencyConverter.java      | 103 ++++
 .../tamaya/core/converters/DoubleConverter.java |  94 ++++
 .../core/converters/DurationConverter.java      |  60 +++
 .../tamaya/core/converters/FileConverter.java   |  63 +++
 .../tamaya/core/converters/FloatConverter.java  |  94 ++++
 .../core/converters/InstantConverter.java       |  58 +++
 .../core/converters/IntegerConverter.java       |  87 ++++
 .../core/converters/LocalDateConverter.java     |  58 +++
 .../core/converters/LocalDateTimeConverter.java |  58 +++
 .../core/converters/LocalTimeConverter.java     |  58 +++
 .../tamaya/core/converters/LongConverter.java   |  84 ++++
 .../tamaya/core/converters/NumberConverter.java |  85 ++++
 .../converters/OffsetDateTimeConverter.java     |  58 +++
 .../core/converters/OffsetTimeConverter.java    |  58 +++
 .../core/converters/OptionalConverter.java      |  78 +++
 .../tamaya/core/converters/PathConverter.java   |  64 +++
 .../tamaya/core/converters/ShortConverter.java  |  85 ++++
 .../core/converters/SupplierConverter.java      |  70 +++
 .../tamaya/core/converters/URIConverter.java    |  63 +++
 .../tamaya/core/converters/URLConverter.java    |  63 +++
 .../tamaya/core/converters/package-info.java    |  23 +
 .../javax.config.spi.ConfigProviderResolver     |  19 +
 .../services/javax.config.spi.ConfigSource      |  22 +
 .../services/javax.config.spi.Converter         |  44 ++
 .../org.apache.tamaya.spi.ConfigValueEvaluator  |  19 +
 code/core/src/main/resources/tamaya-banner.txt  |  11 +
 .../apache/tamaya/core/BannerManagerTest.java   |  89 ++++
 .../apache/tamaya/core/ConfigBuilderTest.java   |  94 ++++
 .../tamaya/core/ConfigContextBuilderTest.java   | 424 +++++++++++++++++
 .../tamaya/core/ExtConfigBuilderTest.java       | 447 ++++++++++++++++++
 .../core/TamayaConfigProviderResolverTest.java  |  69 +++
 .../apache/tamaya/core/TestConfigSource.java    |  67 +++
 .../core/testdata/TestConfigNamesSource.java    |  51 ++
 .../apache/tamaya/core/testdata/TestFilter.java |  42 ++
 .../core/testdata/TestRemovingFilter.java       |  47 ++
 .../resources/META-INF/javaconfig.properties    |  22 +
 .../src/test/resources/META-INF/javaconfig.xml  |  25 +
 .../services/javax.config.spi.ConfigSource      |  21 +
 .../javax.config.spi.ConfigSourceProvider       |  19 +
 .../services/javax.config.spi.Converter         |  19 +
 .../services/org.apache.tamaya.spi.Filter       |  20 +
 116 files changed, 12809 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/base/bnd.bnd
----------------------------------------------------------------------
diff --git a/code/base/bnd.bnd b/code/base/bnd.bnd
new file mode 100644
index 0000000..cc6472d
--- /dev/null
+++ b/code/base/bnd.bnd
@@ -0,0 +1,31 @@
+-buildpath: \
+	osgi.annotation; version=6.0.0,\
+	osgi.core; version=6.0,\
+	osgi.cmpn; version=6.0
+
+-testpath: \
+	${junit}
+
+javac.source: 1.8
+javac.target: 1.8
+
+Bundle-Version: ${version}.${tstamp}
+Bundle-Name: Apache Tamaya - SPI Support
+Bundle-SymbolicName: org.apache.tamaya.spisupport
+Bundle-Description: Apacha Tamaya Config - SPI Support
+Bundle-Category: Implementation
+Bundle-Copyright: (C) Apache Foundation
+Bundle-License: Apache Licence version 2
+Bundle-Vendor: Apache Software Foundation
+Bundle-ContactAddress: dev-tamaya@incubator.apache.org
+Bundle-DocURL: http://tamaya.apache.org
+Export-Package: \
+	org.apache.tamaya.base,\
+    org.apache.tamaya.base.configsource,\
+    org.apache.tamaya.base.convert,\
+    org.apache.tamaya.base.filter,\
+    org.apache.tamaya.spi
+Import-Package: \
+    javax.config,\
+    javax.config.spi,\
+    javax.annotation

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/base/pom.xml
----------------------------------------------------------------------
diff --git a/code/base/pom.xml b/code/base/pom.xml
new file mode 100644
index 0000000..dc16016
--- /dev/null
+++ b/code/base/pom.xml
@@ -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 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.tamaya</groupId>
+        <artifactId>tamaya-code</artifactId>
+        <version>0.4-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>tamaya-base</artifactId>
+    <name>Apache Tamaya JavaConfig SPI Base Support</name>
+    <description>Apache Tamaya Base Classes useful when implementing the JavaConfig SPI.</description>
+    <packaging>jar</packaging>
+
+    <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>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <!--
+                 ! See https://issues.apache.org/jira/browse/TAMAYA-318
+                 !-->
+                <groupId>org.pitest</groupId>
+                <artifactId>pitest-maven</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/bnd.bnd
----------------------------------------------------------------------
diff --git a/code/compat/bnd.bnd b/code/compat/bnd.bnd
new file mode 100644
index 0000000..0409b56
--- /dev/null
+++ b/code/compat/bnd.bnd
@@ -0,0 +1,34 @@
+-buildpath: \
+	osgi.annotation; version=6.0.0,\
+	osgi.core; version=6.0,\
+	osgi.cmpn; version=6.0
+
+-testpath: \
+	${junit}
+
+javac.source: 1.8
+javac.target: 1.8
+
+Bundle-Version: ${version}.${tstamp}
+Bundle-SymbolicName: org.apache.tamaya.compat
+Bundle-Name: Apache Tamaya - API
+Bundle-Description: Apacha Tamaya Configuration Java API
+Bundle-Category: API
+Bundle-Copyright: (C) Apache Foundation
+Bundle-License: Apache Licence version 2
+Bundle-Vendor: Apache Software Foundation
+Bundle-ContactAddress: dev-tamaya@incubator.apache.org
+Bundle-DocURL: http://tamaya.apache.org
+Export-Package: \
+	org.apache.tamaya,\
+	org.apache.tamaya.spisupport,\
+	org.apache.tamaya.spi,\
+	org.apache.tamaya.spisupport.propertysource
+Import-Package: \
+    javax.config,\
+    javax.config.spi,\
+    org.apache.tamaya.base,\
+    org.apache.tamaya.base.configsource,\
+    org.apache.tamaya.base.convert,\
+    org.apache.tamaya.base.filter,\
+    org.apache.tamaya.spi

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/pom.xml
----------------------------------------------------------------------
diff --git a/code/compat/pom.xml b/code/compat/pom.xml
new file mode 100644
index 0000000..c48131b
--- /dev/null
+++ b/code/compat/pom.xml
@@ -0,0 +1,70 @@
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.tamaya</groupId>
+        <artifactId>tamaya-code</artifactId>
+        <version>0.4-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>tamaya-compat</artifactId>
+    <name>Apache Tamaya Compatibility API</name>
+    <packaging>jar</packaging>
+
+    <description>
+        The compatibility API from former Tamaya versions.
+    </description>
+    
+
+    <url>http://tamaya.incubator.apache.org</url>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/ConfigException.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/ConfigException.java b/code/compat/src/main/java/org/apache/tamaya/ConfigException.java
new file mode 100644
index 0000000..38b0801
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/ConfigException.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+/**
+ * Exception class (runtime exception) for configuration issues.
+ */
+public class ConfigException extends RuntimeException{
+
+    private static final long serialVersionUID = -5886094818057522680L;
+
+    /**
+     * Creates a new configuration exception.
+     * @param message the exception message, not {@code null}.
+     */
+    public ConfigException(String message){
+        super(message);
+    }
+
+    /**
+     * Creates a new configuration exception.
+     * @param message the exception message, not {@code null}.
+     * @param t the throwable.
+     */
+    public ConfigException(String message, Throwable t){
+        super(message, t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/ConfigOperator.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/ConfigOperator.java b/code/compat/src/main/java/org/apache/tamaya/ConfigOperator.java
new file mode 100644
index 0000000..b14c155
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/ConfigOperator.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya;
+
+/**
+ * Models a function that maps a given {@link org.apache.tamaya.Configuration} to another {@link org.apache.tamaya.Configuration}. This can be used
+ * to modell additional functionality and applying it to a given {@link org.apache.tamaya.Configuration} instance by calling
+ * the {@link org.apache.tamaya.Configuration#with(org.apache.tamaya.ConfigOperator)} method.
+ */
+@FunctionalInterface
+public interface ConfigOperator {
+
+    /**
+     * Creates a new {@link org.apache.tamaya.Configuration} based on the given Configuration. Operators basically acts similar to
+     * decorators, whereas operated instances may have non compatible behaviour, e.g. by applying security constraints
+     * or view restrictions.
+     *
+     * @param config the input configuration, not {@code null}.
+     * @return the operated configuration, never {@code null}.
+     */
+    Configuration operate(Configuration config);
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/ConfigQuery.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/ConfigQuery.java b/code/compat/src/main/java/org/apache/tamaya/ConfigQuery.java
new file mode 100644
index 0000000..28b8b93
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/ConfigQuery.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+/**
+ * Models a function that maps a given {@link Configuration} to something else. This can be used
+ * to model additional functionality and applying it to a given {@link Configuration} instance by
+ * calling the {@link Configuration#query(ConfigQuery)} method.
+ */
+@FunctionalInterface
+public interface ConfigQuery<T> {
+
+    /**
+     * Creates a result based on the given Configuration. Queries basically acts similar to
+     * operators, whereas they returns any kind of result.
+     *
+     * @param config the input configuration, not {@code null}.
+     * @return the query result.
+     */
+    T query(Configuration config);
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/Configuration.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/Configuration.java b/code/compat/src/main/java/org/apache/tamaya/Configuration.java
new file mode 100644
index 0000000..3cf57f7
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/Configuration.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya;
+
+import org.apache.tamaya.spi.ConfigurationBuilder;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.TypeLiteral;
+
+import java.util.Map;
+
+
+/**
+ * <p>A configuration models a aggregated set current properties, identified by
+ * a unique key, but adds higher level access functions to
+ * a {@link org.apache.tamaya.spi.PropertySource}. Hereby in most
+ * cases a configuration is a wrapper around a composite
+ * {@link org.apache.tamaya.spi.PropertySource} instance, which may combine
+ * multiple child config in well defined tree like structure,
+ * where nodes define logically the rules current priority, filtering,
+ * combination and overriding.
+ * </p>
+ * <h3>Implementation Requirements</h3>
+ * Implementations current this interface must be
+ * <ul>
+ *  <li>Thread safe</li>
+ *  <li>Immutable</li>
+ * </ul>
+ *
+ * <p>It is not recommended that implementations also are serializable, since the any configuration can be <i>frozen</i>
+ * by reading out its complete configuration map into a serializable and remotable structure. This helps significantly
+ * simplifying the development current this interface, e.g. for being backed up by systems and stores that are not part current
+ * this library at all.</p>
+ */
+public interface Configuration {
+
+    /**
+     * Access a property.
+     *
+     * @param key the property's key, not {@code null}.
+     * @return the property's value.
+     */
+    default String get(String key){
+        return get(key, org.apache.tamaya.spi.TypeLiteral.of(String.class));
+    }
+
+    /**
+     * Access a property.
+     *
+     * @param key the property's key, not {@code null}.
+     * @param defaultValue value to be returned, if no value is present, not {@code null}
+     * @return the property's keys.
+     */
+    default String getOrDefault(String key, String defaultValue){
+        return getOrDefault(key, org.apache.tamaya.spi.TypeLiteral.of(String.class), defaultValue);
+    }
+
+    /**
+     * Get the property keys as type T. This will implicitly require a corresponding {@link
+     * org.apache.tamaya.spi.PropertyConverter} to be available that is capable current providing type T
+     * fromMap the given String keys.
+     *
+     * @param <T> the type of the class modeled by the type parameter
+     * @param key          the property's absolute, or relative path, e.g. @code
+     *                     a/b/c/d.myProperty}, not  {@code null}.
+     * @param type         The target type required, not  {@code null}.
+     * @param defaultValue value to be used, if no value is present, not {@code null}
+     * @return the property value, never {@code null}.
+     * @throws ConfigException if the keys could not be converted to the required target type.
+     */
+    default <T> T getOrDefault(String key, Class<T> type, T defaultValue){
+        return getOrDefault(key, org.apache.tamaya.spi.TypeLiteral.of(type), defaultValue);
+    }
+
+    /**
+     * Get the property keys as type T. This will implicitly require a corresponding {@link
+     * org.apache.tamaya.spi.PropertyConverter} to be available that is capable current providing type T
+     * fromMap the given String keys.
+     *
+     * @param <T> the type of the class modeled by the type parameter
+     * @param key          the property's absolute, or relative path, e.g. @code
+     *                     a/b/c/d.myProperty}.
+     * @param type         The target type required, not {@code null}.
+     * @return the property value, never {@code null}.
+     * @throws ConfigException if the keys could not be converted to the required target type.
+     */
+    default <T> T get(String key, Class<T> type){
+        return get(key, org.apache.tamaya.spi.TypeLiteral.of(type));
+    }
+
+    /**
+     * Get the property keys as type T. This will implicitly require a corresponding {@link
+     * org.apache.tamaya.spi.PropertyConverter} to be available that is capable current providing type T
+     * fromMap the given String keys.
+     *
+     * @param <T> the type of the type literal
+     * @param key          the property's absolute, or relative path, e.g. @code
+     *                     a/b/c/d.myProperty}, not {@code null}.
+     * @param type         The target type required, not {@code null}.
+     * @return the property value, never {@code null}.
+     * @throws ConfigException if the keys could not be converted to the required target type.
+     */
+    <T> T get(String key, org.apache.tamaya.spi.TypeLiteral<T> type);
+
+    /**
+     * Get the property keys as type T. This will implicitly require a corresponding {@link
+     * org.apache.tamaya.spi.PropertyConverter} to be available that is capable current providing type T
+     * fromMap the given String keys.
+     *
+     * @param <T> the type of the type literal
+     * @param key          the property's absolute, or relative path, e.g.
+     *                     {@code a/b/c/d.myProperty}, not {@code null}.
+     * @param type         The target type required, not {@code null}.
+     * @param defaultValue default value to be used, if no value is present.
+     * @return the property value, never null.
+     * @throws ConfigException if the keys could not be converted to the required target type.
+     */
+    <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue);
+
+    /**
+     * Access all currently known configuration properties as a full {@code Map<String,String>}.
+     * Be aware that entries from non scannable parts of the registered {@link org.apache.tamaya.spi.PropertySource}
+     * instances may not be contained in the result, but nevertheless be accessible calling one of the
+     * {@code get(...)} methods.
+     * @return all currently known configuration properties.
+     */
+    Map<String,String> getProperties();
+
+    /**
+     * Extension point for adjusting configuration.
+     *
+     * @param operator A configuration operator, e.g. a filter, or an adjuster
+     *                 combining configurations, never  {@code null}.
+     * @return the new adjusted configuration returned by the {@code operator}, never {@code null}.
+     */
+    default Configuration with(ConfigOperator operator){
+        return operator.operate(this);
+    }
+
+    /**
+     * Query a configuration.
+     *
+     * @param <T> the type of the configuration.
+     * @param query the query, not {@code null}.
+     * @return the result returned by the {@code query}.
+     */
+    default <T> T query(ConfigQuery<T> query){
+        return query.query(this);
+    }
+
+    /**
+     * Access a configuration's context.
+     * @return the configuration context, never null.
+     */
+    ConfigurationContext getContext();
+
+    /**
+     * Create a new builder using this instance as it's base.
+     * @return a new builder, never null.
+     */
+    default ConfigurationBuilder toBuilder() {
+        return ConfigurationProvider.getConfigurationBuilder().setConfiguration(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/ConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/ConfigurationProvider.java b/code/compat/src/main/java/org/apache/tamaya/ConfigurationProvider.java
new file mode 100644
index 0000000..bacb944
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/ConfigurationProvider.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya;
+
+import org.apache.tamaya.spi.*;
+
+import java.util.logging.Logger;
+
+/**
+ * Static access to the {@link Configuration} for the very application.
+ */
+public final class ConfigurationProvider {
+
+    private static final Logger LOG = Logger.getLogger(ConfigurationProvider.class.getName());
+
+    private static ConfigurationProviderSpi spi() {
+        ConfigurationProviderSpi spi = ServiceContextManager.getServiceContext()
+                .getService(ConfigurationProviderSpi.class);
+        if(spi==null){
+            throw new IllegalStateException("ConfigurationProviderSpi not available.");
+        }
+        return spi;
+    }
+
+    private ConfigurationProvider() {
+        // just to prevent initialisation
+    }
+
+    /**
+     * Access the current configuration.
+     *
+     * @return the corresponding Configuration instance, never {@code null}.
+     */
+    public static Configuration getConfiguration() {
+        return spi().getConfiguration();
+    }
+
+    /**
+     * Creates a new configuration instance based on the given context.
+     *
+     * @param context the configuration context, not {@code null}.
+     * @return a new Configuration instance, never {@code null}.
+     */
+    public static Configuration createConfiguration(ConfigurationContext context) {
+        return spi().createConfiguration(context);
+    }
+
+    /**
+     * Get access to the current ConfigurationContext.
+     *
+     * @return the current ConfigurationContext, never null.
+     * @deprecated Use {@link Configuration#getContext()} instead of.
+     */
+    @Deprecated
+    public static ConfigurationContext getConfigurationContext() {
+        return spi().getConfigurationContext();
+    }
+
+    /**
+     * This method allows to replace the current {@link org.apache.tamaya.spi.ConfigurationContext} with a new
+     * instance. This can be used to update the context with a new one, e.g. because some of the configuration
+     * data has changed and should be updated. It is the responsibility of the ConfigurationProvider to trigger
+     * corresponding update events for the current {@link org.apache.tamaya.Configuration}, so observing
+     * listeners can do whatever is appropriate to react to any given configuration changes.
+     *
+     * @param context the new ConfigurationContext to be applied.
+     * @throws java.lang.UnsupportedOperationException if the current provider is read-only and does not support
+     *                                                 applying a new ConfigurationContext.
+     * @deprecated Use #setConfiguration(Configuration) instead of.
+     */
+    @Deprecated
+    public static void setConfigurationContext(ConfigurationContext context) {
+        spi().setConfigurationContext(context);
+    }
+
+    /**
+     * This method allows to replace the current default {@link org.apache.tamaya.Configuration} with a new
+     * instance. It is the responsibility of the ConfigurationProvider to trigger
+     * corresponding update events for the current {@link org.apache.tamaya.Configuration}, so observing
+     * listeners can do whatever is appropriate to react to any given configuration change.
+     *
+     * @param config the new Configuration to be applied, not {@code null}
+     * @throws java.lang.UnsupportedOperationException if the current provider is read-only and
+     *                                                 does not support
+     *                                                 applying a new Configuration.
+     */
+    public static void setConfiguration(Configuration config) {
+        LOG.info("TAMAYA Applying new Configuration: " + config);
+        spi().setConfiguration(config);
+    }
+
+    /**
+     * Create a new {@link ConfigurationBuilder} instance. This method creates
+     * a new builder instance that is not related to any concrete {@link org.apache.tamaya.spi.ConfigurationContext}.
+     * You can use {@link #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} to change the
+     * current configuration context.
+     *
+     * @return a new, empty {@link ConfigurationBuilder}, never null.
+     * @see #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)
+     * @see org.apache.tamaya.spi.ConfigurationContext
+     * @deprecated Will be removed.
+     */
+    @Deprecated
+    public static ConfigurationContextBuilder getConfigurationContextBuilder() {
+        return spi().getConfigurationContextBuilder();
+    }
+
+    /**
+     * Create a new {@link ConfigurationBuilder} instance. This method creates
+     * a new builder instance that is not related to any concrete {@link org.apache.tamaya.spi.ConfigurationContext}.
+     * You can use {@link #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} to change the
+     * current configuration context.
+     *
+     * @return a new, empty {@link ConfigurationBuilder}, never null.
+     * @see #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)
+     * @see org.apache.tamaya.spi.ConfigurationContext
+     */
+    public static ConfigurationBuilder getConfigurationBuilder() {
+        return spi().getConfigurationBuilder();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/package-info.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/package-info.java b/code/compat/src/main/java/org/apache/tamaya/package-info.java
new file mode 100644
index 0000000..486116a
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/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.
+ */
+
+/**
+ * This package contains the Apache Tamaya API.
+ */
+package org.apache.tamaya;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java
new file mode 100644
index 0000000..ac3e3b9
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationBuilder.java
@@ -0,0 +1,347 @@
+/*
+ * 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.Configuration;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A builder for creating new instance of {@link Configuration}.
+ * Builders can be obtained in exactly two ways:
+ * <ol>
+ *     <li>By accessing a preinitialized builder from an existing {@link Configuration},
+ *     by calling {@link org.apache.tamaya.Configuration#toBuilder()}.</li>
+ *     <li>By accessing an empty builder instance from
+ *     {@link org.apache.tamaya.ConfigurationProvider#getConfigurationBuilder()}.</li>
+ * </ol>
+ * After all changes are applied to a builder a new {@link Configuration} instance can
+ * be created and can be applied by calling
+ * {@link #build()}}.
+ *
+ */
+public interface ConfigurationBuilder {
+
+    /**
+     * Init this builder instance with the given {@link Configuration} instance. This
+     * method will use any existing property sources, filters, converters and the combination
+     * policy of the given {@link Configuration} and initialize the current builder
+     * with them. All previous property sources, filters, converters and the combination
+     * policy of this instance will be replaced.
+     *
+     * @param config the {@link Configuration} instance to be used, not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder setConfiguration(Configuration config);
+
+    /**
+     * Init this builder instance with the given {@link ConfigurationContext} instance. This
+     * method will use any existing property sources, filters, converters and the combination
+     * policy of the given {@link ConfigurationContext} and initialize the current builder
+     * with them. All previous property sources, filters, converters and the combination
+     * policy of this instance will be replaced.
+     *
+     * @param context the {@link ConfigurationContext} instance to be used, not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder setContext(ConfigurationContext context);
+
+    /**
+     * This method can be used for adding {@link PropertySource}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 #sortPropertySources}.
+     *
+     * @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.
+     */
+    ConfigurationBuilder addPropertySources(PropertySource... propertySources);
+
+    /**
+     * This method can be used for programmatically adding {@link PropertySource}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 #sortPropertySources}.
+     *
+     * @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.
+     */
+    ConfigurationBuilder addPropertySources(Collection<PropertySource> propertySources);
+
+    /**
+     * Add all registered (default) property sources to the context built. The sources are ordered
+     * based on their ordinal values and added to the chain of property sources with
+     * higher priority.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addDefaultPropertySources();
+
+    /**
+     * 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.
+     */
+    ConfigurationBuilder removePropertySources(PropertySource... 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.
+     */
+    ConfigurationBuilder removePropertySources(Collection<PropertySource> propertySources);
+
+    /**
+     * 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<PropertySource> getPropertySources();
+
+    /**
+     * Access the current chain of property filters. Items at the end of the list have
+     * precedence/more significance.
+     *
+     * @return the property filter chain, never {@code null}.
+     */
+    List<PropertyFilter> getPropertyFilters();
+
+    /**
+     * Access the current registered property converters.
+     *
+     * @return the current registered property converters.
+     */
+    Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter();
+
+    /**
+     * 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.
+     */
+    ConfigurationBuilder increasePriority(PropertySource 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.
+     */
+    ConfigurationBuilder decreasePriority(PropertySource 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.
+     */
+    ConfigurationBuilder highestPriority(PropertySource 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.
+     */
+    ConfigurationBuilder lowestPriority(PropertySource propertySource);
+
+    /**
+     * 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 #sortPropertyFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addPropertyFilters(PropertyFilter... 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 #sortPropertyFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addPropertyFilters(Collection<PropertyFilter> filters);
+
+    /**
+     * Add all auto-discoverable property filters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addDefaultPropertyFilters();
+
+
+    /**
+     * 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.
+     */
+    ConfigurationBuilder removePropertyFilters(PropertyFilter... 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.
+     */
+    ConfigurationBuilder removePropertyFilters(Collection<PropertyFilter> filters);
+
+    /**
+     * 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 converter is for
+     * @param propertyConverters the PropertyConverters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> typeToConvert,
+                                                   @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters);
+
+    /**
+     * 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 converter is for
+     * @param propertyConverters the PropertyConverters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationBuilder addPropertyConverters(TypeLiteral<T> typeToConvert,
+                                                   Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Add all auto-discoverable property converters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder addDefaultPropertyConverters();
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converter is for
+     * @param propertyConverters    the converter to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                      @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters);
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converter is for
+     * @param propertyConverters    the converter to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                      Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Removes all converters for the given type, which actually renders a given type
+     * unsupported for type conversion.
+     *
+     * @param typeToConvert the type which the converter is for
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder removePropertyConverters(TypeLiteral<?> typeToConvert);
+
+    /**
+     * 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.
+     */
+    ConfigurationBuilder sortPropertySources(Comparator<PropertySource> comparator);
+
+    /**
+     * 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.
+     */
+    ConfigurationBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator);
+
+    /**
+     * Sets the {@link PropertyValueCombinationPolicy} used to evaluate the final
+     * property values.
+     *
+     * @param policy the {@link PropertyValueCombinationPolicy} used, not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy);
+
+    /**
+     * Builds a new {@link Configuration} based on the data in this builder. The ordering of property
+     * sources and property filters is not changed, regardless of their ordinals. For ensure a certain
+     * ordering/significance use {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)}
+     * before building the context.
+     *
+     * @return the final configuration, never null.
+     */
+    Configuration build();
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java
new file mode 100644
index 0000000..43f7ea0
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java
@@ -0,0 +1,172 @@
+/*
+ * 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.List;
+import java.util.Map;
+
+/**
+ * Central SPI for programmatically dealing with the setup of the configuration system.
+ * This includes adding and enlisting {@link org.apache.tamaya.spi.PropertySource}s,
+ * managing {@link PropertyConverter}s, ConfigFilters, etc.
+ */
+public interface ConfigurationContext {
+
+    /**
+     * This method can be used for programmatically adding {@link PropertySource}s.
+     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     *
+     * @param propertySources the PropertySources to add
+     * @deprecated Use {@link ConfigurationContextBuilder} to create a new {@link ConfigurationContext}.
+     * @see #toBuilder()
+     */
+    @Deprecated
+    void addPropertySources(PropertySource... propertySources);
+
+    /**
+     * 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<PropertySource> getPropertySources();
+
+    /**
+     * Access a {@link PropertySource} using its (unique) name.
+     * @param name the propoerty source's name, not {@code null}.
+     * @return the propoerty source found, or {@code null}.
+     */
+    PropertySource getPropertySource(String name);
+
+    /**
+     * This method can be used for programmatically adding {@link PropertyConverter}s.
+     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     *
+     * @param <T> the type of the type literal
+     * @param type the type which the converters is for
+     * @param propertyConverter the PropertyConverters to add for this type
+     * @deprecated Use {@link ConfigurationContextBuilder} to create a new {@link ConfigurationContext}.
+     * @see #toBuilder()
+     */
+    @Deprecated
+    <T> void addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter);
+
+
+    /**
+     * <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<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters();
+
+    /**
+     * <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 <T> the type of the type literal
+     * @param type type of the desired converters
+     * @return a sorted list of registered PropertySources per type.
+     */
+    <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type);
+
+    /**
+     * Access the current PropertyFilter instances.
+     * @return the list of registered PropertyFilters, never null.
+     */
+    List<PropertyFilter> getPropertyFilters();
+
+    /**
+     * Access the {@link org.apache.tamaya.spi.PropertyValueCombinationPolicy} used to evaluate the final
+     * property values.
+     * @return the {@link org.apache.tamaya.spi.PropertyValueCombinationPolicy} used, never null.
+     */
+    PropertyValueCombinationPolicy getPropertyValueCombinationPolicy();
+
+    /**
+     * Creates a {@link ConfigurationContextBuilder} preinitialized with the data from this instance.
+     * @return a new builder instance, never null.
+     * @deprecated Will be removed.
+     */
+    @Deprecated
+    ConfigurationContextBuilder toBuilder();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
new file mode 100644
index 0000000..8e3f307
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
@@ -0,0 +1,334 @@
+/*
+ * 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.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A builder for creating new or adapting instances of {@link ConfigurationContext}.
+ * Builders can be obtained in exactly two ways:
+ * <ol>
+ *     <li>By accessing a preinitialized builder from an existing {@link ConfigurationContext},
+ *     by calling {@link org.apache.tamaya.spi.ConfigurationContext#toBuilder()}.</li>
+ *     <li>By accessing an empty builder instance from
+ *     {@link org.apache.tamaya.ConfigurationProvider#getConfigurationContextBuilder()}.</li>
+ * </ol>
+ * After all changes are applied to a builder a new {@link ConfigurationContext} instance can
+ * be created and can be applied by calling
+ * {@link org.apache.tamaya.ConfigurationProvider#setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)}.
+ * @deprecated Use {@link ConfigurationBuilder} instead.
+ */
+@Deprecated
+public interface ConfigurationContextBuilder {
+
+    /**
+     * Init this builder instance with the given {@link ConfigurationContext} instance. This
+     * method will use any existing property sources, filters, converters and the combination
+     * policy of the given {@link ConfigurationContext} and initialize the current builder
+     * with them.
+     *
+     * @param context the {@link ConfigurationContext} instance to be used, not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder setContext(ConfigurationContext context);
+
+    /**
+     * This method can be used for adding {@link PropertySource}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 #sortPropertySources}.
+     *
+     * @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.
+     */
+    ConfigurationContextBuilder addPropertySources(PropertySource... propertySources);
+
+    /**
+     * This method can be used for programmatically adding {@link PropertySource}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 #sortPropertySources}.
+     *
+     * @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.
+     */
+    ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySources);
+
+    /**
+     * Add all registered (default) property sources to the context built. The sources are ordered
+     * based on their ordinal values and added to the chain of property sources with
+     * higher priority.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addDefaultPropertySources();
+
+    /**
+     * 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.
+     */
+    ConfigurationContextBuilder removePropertySources(PropertySource... 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.
+     */
+    ConfigurationContextBuilder removePropertySources(Collection<PropertySource> propertySources);
+
+    /**
+     * 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<PropertySource> getPropertySources();
+
+    /**
+     * 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<PropertyFilter> getPropertyFilters();
+
+    /**
+     * Access the current registered property converters.
+     *
+     * @return the current registered property converters.
+     */
+    Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter();
+
+    /**
+     * 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.
+     */
+    ConfigurationContextBuilder increasePriority(PropertySource 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.
+     */
+    ConfigurationContextBuilder decreasePriority(PropertySource 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.
+     */
+    ConfigurationContextBuilder highestPriority(PropertySource 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.
+     */
+    ConfigurationContextBuilder lowestPriority(PropertySource propertySource);
+
+    /**
+     * 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 #sortPropertyFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addPropertyFilters(PropertyFilter... 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 #sortPropertyFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters);
+
+    /**
+     * Add all registered (default) property filters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addDefaultPropertyFilters();
+
+
+    /**
+     * 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.
+     */
+    ConfigurationContextBuilder removePropertyFilters(PropertyFilter... 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.
+     */
+    ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters);
+
+    /**
+     * 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 propertyConverters the PropertyConverters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert,
+                                                          @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters);
+
+    /**
+     * 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 propertyConverters the PropertyConverters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert,
+                                                          Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Add all registered (default) property converters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addDefaultPropertyConverters();
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param propertyConverters    the converters to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                             @SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters);
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param propertyConverters    the converters to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                             Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * 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.
+     */
+    ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert);
+
+    /**
+     * 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.
+     */
+    ConfigurationContextBuilder sortPropertySources(Comparator<PropertySource> comparator);
+
+    /**
+     * 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.
+     */
+    ConfigurationContextBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator);
+
+    /**
+     * Sets the {@link PropertyValueCombinationPolicy} used to evaluate the final
+     * property values.
+     *
+     * @param policy the {@link PropertyValueCombinationPolicy} used, not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy);
+
+    /**
+     * Builds a new {@link ConfigurationContext} based on the data in this builder. The ordering of property
+     * sources and property filters is not changed, regardless of their ordinals. For ensure a certain
+     * ordering/significance call {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)}
+     * before building the context.
+     *
+     * @return the final context to be used to create a configuration.
+     * @see org.apache.tamaya.ConfigurationProvider#createConfiguration(ConfigurationContext)
+     */
+    ConfigurationContext build();
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
new file mode 100644
index 0000000..fb93ab4
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
@@ -0,0 +1,128 @@
+/*
+ * 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.Configuration;
+
+/**
+ * SPI that must be implemented to provide the component that manages all {@link org.apache.tamaya.Configuration}
+ * instances in a system. In SE this may be a true singleton containing exact one {@link org.apache.tamaya.Configuration}
+ * instance, whereas in Java EE and other more complex environments instances may be returned depending the current
+ * runtime context.
+ */
+public interface ConfigurationProviderSpi {
+
+    /**
+     * Access the current {@link org.apache.tamaya.Configuration}.
+     *
+     * @return the current {@link org.apache.tamaya.Configuration} instance, never null.
+     */
+    Configuration getConfiguration();
+
+    /**
+     * Create a {@link Configuration} instance using the given context. The configuration
+     * created hereby must respect the artifacts provided by its context (property sources,
+     * filters, converters, policies etc), including their ordering and significance.
+     * @param context the context to be used, not {@code null}.
+     * @return the corresponding configuration instance.
+     */
+    Configuration createConfiguration(ConfigurationContext context);
+
+    /**
+     * Creates a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder} instance.
+     *
+     * @return a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder}, never null.
+     * @deprecated Will be removed
+     */
+    @Deprecated
+    ConfigurationContextBuilder getConfigurationContextBuilder();
+
+    /**
+     * Creates a new {@link org.apache.tamaya.spi.ConfigurationBuilder} instance.
+     *
+     * @return a new {@link org.apache.tamaya.spi.ConfigurationBuilder}, never null.
+     */
+    ConfigurationBuilder getConfigurationBuilder();
+
+    /**
+     * This method allows to replace the current {@link org.apache.tamaya.Configuration} with a new
+     * instance. This can be used to update the configuration with a new one, e.g. because some of the
+     * data has changed and must be updated. It is the responsibility of the ConfigurationProvider to trigger
+     * corresponding update events for the current {@link org.apache.tamaya.Configuration}.
+     *
+     * @param config the new Configuration to be applied.
+     * @throws java.lang.UnsupportedOperationException if the current provider is read-only.
+     */
+    void setConfiguration(Configuration config);
+
+    /**
+     * Method that allows to determine if a new {@link org.apache.tamaya.Configuration} can be applied
+     * programmatically.
+     *
+     * @return true, if {@link #setConfiguration(org.apache.tamaya.Configuration)} is supported
+     * by the current implementation.
+     * @see #setConfiguration(org.apache.tamaya.Configuration)
+     */
+    default boolean isConfigurationSettable(){
+        return true;
+    }
+
+    /**
+     * Get access to the current {@link ConfigurationContext}.
+     *
+     * @return the current {@link ConfigurationContext}, never null.
+     * @deprecated Will be removed in favour of {@link Configuration#getContext()}.
+     */
+    @Deprecated
+    default ConfigurationContext getConfigurationContext(){
+        return getConfiguration().getContext();
+    }
+
+    /**
+     * This method allows to replace the current {@link org.apache.tamaya.spi.ConfigurationContext} with a new
+     * instance. This can be used to update the context with a new one, e.g. because some of the configuration
+     * data has changed and must be updated. It is the responsibility of the ConfigurationProvider to trigger
+     * corresponding update event for the current {@link org.apache.tamaya.spi.ConfigurationContext} or
+     * {@link org.apache.tamaya.Configuration}.
+     *
+     * @param context the new ConfigurationContext to be applied.
+     * @throws java.lang.UnsupportedOperationException if the current provider is read-only.
+     * @deprecated use {@link #setConfiguration(Configuration)}
+     */
+    @Deprecated
+    default void setConfigurationContext(ConfigurationContext context){
+        setConfiguration(createConfiguration(context));
+    }
+
+    /**
+     * Method that allows to determine if a new {@link org.apache.tamaya.spi.ConfigurationContext} can be applied
+     * programmatically.
+     *
+     * @return true, if {@link #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} is supported
+     * by the current implementation.
+     * @see #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)
+     * @deprecated use {@link #isConfigurationSettable()}
+     */
+    @Deprecated
+    default boolean isConfigurationContextSettable(){
+        return isConfigurationSettable();
+    }
+
+
+}


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

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/spi/FilterContextTest.java b/code/compat/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
new file mode 100644
index 0000000..e272b9a
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.spi.FilterContext;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link org.apache.tamaya.spi.FilterContext}.
+ */
+public class FilterContextTest {
+
+    @Test(expected = NullPointerException.class)
+    public void constructorRequiresNonNullPropertyValueTwoParameterVariant() {
+        new org.apache.tamaya.spi.FilterContext(null, new TestConfigContext());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void constructorRequiresNonNullConfigurationContextTwoParameterVariant() {
+        new org.apache.tamaya.spi.FilterContext(PropertyValue.of("a", "b", "s"), null);
+    }
+
+    @SuppressWarnings("unchecked")
+	@Test(expected = NullPointerException.class)
+    public void constructorRequiresNonNullPropertyValueThreeParameterVariant() {
+        new org.apache.tamaya.spi.FilterContext(null, Collections.EMPTY_MAP, new TestConfigContext());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test(expected = NullPointerException.class)
+    public void constructorRequiresNonNullConfigurationContextThreeParameterVariant() {
+        new org.apache.tamaya.spi.FilterContext(PropertyValue.of("a", "b", "s"), Collections.EMPTY_MAP, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void constructorRequiresNonNullMapForConfigEntriesThreeParameterVariant() {
+        new org.apache.tamaya.spi.FilterContext(PropertyValue.of("a", "b", "s"), null, new TestConfigContext());
+    }
+
+    @Test
+    public void getKey() throws Exception {
+        PropertyValue val = PropertyValue.of("getKey", "v", "");
+        org.apache.tamaya.spi.FilterContext ctx = new org.apache.tamaya.spi.FilterContext(val,
+                new HashMap<String,PropertyValue>(), new TestConfigContext());
+        assertEquals(val, ctx.getProperty());
+    }
+
+    @Test
+    public void isSinglePropertyScoped() throws Exception {
+        PropertyValue val = PropertyValue.of("isSinglePropertyScoped", "v", "");
+        org.apache.tamaya.spi.FilterContext ctx = new org.apache.tamaya.spi.FilterContext(val, new HashMap<String,PropertyValue>(), new TestConfigContext());
+        assertEquals(false, ctx.isSinglePropertyScoped());
+        ctx = new org.apache.tamaya.spi.FilterContext(val, new TestConfigContext());
+        assertEquals(true, ctx.isSinglePropertyScoped());
+    }
+
+    @Test
+    public void getConfigEntries() throws Exception {
+        Map<String,PropertyValue> config = new HashMap<>();
+        for(int i=0;i<10;i++) {
+            config.put("key-"+i, PropertyValue.of("key-"+i, "value-"+i, "test"));
+        }
+        PropertyValue val = PropertyValue.of("getConfigEntries", "v", "");
+        org.apache.tamaya.spi.FilterContext ctx = new org.apache.tamaya.spi.FilterContext(val, config, new TestConfigContext());
+        assertEquals(config, ctx.getConfigEntries());
+    }
+
+    @Test
+    public void testToString() throws Exception {
+        Map<String,PropertyValue> config = new HashMap<>();
+        for(int i=0;i<2;i++) {
+            config.put("key-"+i, PropertyValue.of("key-"+i, "value-"+i, "test"));
+        }
+        PropertyValue val = PropertyValue.of("testToString", "val", "mySource");
+        org.apache.tamaya.spi.FilterContext ctx = new FilterContext(val, config, new TestConfigContext());
+        String toString = ctx.toString();
+
+        assertNotNull(toString);
+        assertTrue(toString.contains("FilterContext{value='PropertyValue{key='testToString', value='val', " +
+                                     "source='mySource'}', configEntries=["));
+        assertTrue(toString.contains("key-0"));
+        assertTrue(toString.contains("key-1"));
+        assertTrue(toString.endsWith("}"));
+    }
+
+    private static class TestConfigContext implements ConfigurationContext {
+
+        @Override
+        public void addPropertySources(PropertySource... propertySources) {
+
+        }
+
+        @Override
+        public List<PropertySource> getPropertySources() {
+            return null;
+        }
+
+        @Override
+        public PropertySource getPropertySource(String name) {
+            return null;
+        }
+
+        @Override
+        public <T> void addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter) {
+
+        }
+
+        @Override
+        public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+            return null;
+        }
+
+        @Override
+        public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type) {
+            return null;
+        }
+
+        @Override
+        public List<PropertyFilter> getPropertyFilters() {
+            return null;
+        }
+
+        @Override
+        public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy() {
+            return null;
+        }
+
+        @Override
+        public ConfigurationContextBuilder toBuilder() {
+            return null;
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java b/code/compat/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
new file mode 100644
index 0000000..31fb2f8
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/spi/ServiceContextManagerTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.junit.Test;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ * Additional tests for {@link ServiceContextManager}, created by atsticks on 20.08.16.
+ */
+public class ServiceContextManagerTest {
+
+    @Test
+    public void setGetServiceContext() throws Exception {
+        ServiceContext prev = ServiceContextManager.getServiceContext();
+        try {
+            MyServiceContext mine = new MyServiceContext();
+            ServiceContextManager.set(mine);
+            assertTrue(ServiceContextManager.getServiceContext() == mine);
+            ServiceContextManager.set(mine);
+            assertTrue(ServiceContextManager.getServiceContext() == mine);
+        } finally {
+            ServiceContextManager.set(prev);
+            assertTrue(ServiceContextManager.getServiceContext() == prev);
+        }
+
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void setRequiresNonNullParameter() {
+        ServiceContextManager.set(null);
+    }
+
+    private static final class MyServiceContext implements ServiceContext{
+
+        @Override
+        public int ordinal() {
+            return 0;
+        }
+
+        @Override
+        public <T> T getService(Class<T> serviceType) {
+            return null;
+        }
+
+        @Override
+        public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+            return getService(serviceType, ServiceContext.defaultClassLoader());
+        }
+
+        @Override
+        public <T> T create(Class<T> serviceType) {
+            return null;
+        }
+
+        @Override
+        public <T> T create(Class<T> serviceType, ClassLoader classLoader) {
+            return create(serviceType, ServiceContext.defaultClassLoader());
+        }
+
+        @Override
+        public <T> List<T> getServices(Class<T> serviceType) {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader) {
+            return getServices(serviceType, ServiceContext.defaultClassLoader());
+        }
+
+        @Override
+        public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException {
+            return null;
+        }
+
+        @Override
+        public URL getResource(String resource, ClassLoader cl) {
+            return null;
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/spi/ServiceContextTest.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/spi/ServiceContextTest.java b/code/compat/src/test/java/org/apache/tamaya/spi/ServiceContextTest.java
new file mode 100644
index 0000000..fe4ee05
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/spi/ServiceContextTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+
+import org.junit.Test;
+
+public class ServiceContextTest {
+
+    private final ServiceContext serviceContext = new ServiceContext(){
+
+        @Override
+        public int ordinal() {
+            return 1;
+        }
+
+        @Override
+        public <T> T getService(Class<T> serviceType) {
+            if(String.class.equals(serviceType)){
+                return serviceType.cast("ServiceContextTest");
+            }
+            return null;
+        }
+
+        @Override
+        public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+            return getService(serviceType, ServiceContext.defaultClassLoader());
+        }
+
+        @Override
+        public <T> T create(Class<T> serviceType) {
+            return getService(serviceType);
+        }
+
+        @Override
+        public <T> T create(Class<T> serviceType, ClassLoader classLoader) {
+            return create(serviceType, ServiceContext.defaultClassLoader());
+        }
+
+        @SuppressWarnings("unchecked")
+		@Override
+        public <T> List<T> getServices(Class<T> serviceType) {
+            if(String.class.equals(serviceType)){
+                List<String> list = new ArrayList<>();
+                list.add("ServiceContextTest");
+                return List.class.cast(list);
+            }
+            return Collections.emptyList();
+        }
+
+        @Override
+        public <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader) {
+            return getServices(serviceType, ServiceContext.defaultClassLoader());
+        }
+
+        @Override
+        public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException {
+            return cl.getResources(resource);
+        }
+
+        @Override
+        public URL getResource(String resource, ClassLoader cl) {
+            return cl.getResource(resource);
+        }
+    };
+
+    @Test
+    public void testOrdinal() throws Exception {
+        assertEquals(1, serviceContext.ordinal());
+    }
+
+    @Test
+    public void testgetService() throws Exception {
+        assertEquals("ServiceContextTest", serviceContext.getService(String.class));
+        assertNull(serviceContext.getService(Integer.class));
+    }
+
+    @Test
+    public void testGetService() throws Exception {
+        String service = serviceContext.getService(String.class);
+        assertNotNull(service);
+        assertEquals("ServiceContextTest", service);
+        Integer intService = serviceContext.getService(Integer.class);
+        assertNull(intService);
+    }
+
+    @Test
+    public void testGetServices() throws Exception {
+        Collection<String> services = serviceContext.getServices(String.class);
+        assertNotNull(services);
+        assertFalse(services.isEmpty());
+        assertEquals("ServiceContextTest", services.iterator().next());
+        List<Integer> intServices = serviceContext.getServices(Integer.class);
+        assertNotNull(intServices);
+        assertTrue(intServices.isEmpty());
+    }
+
+    @Test
+    public void testGetInstance() throws Exception {
+        assertNotNull(ServiceContextManager.getServiceContext());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/spi/TestServiceContext.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/spi/TestServiceContext.java b/code/compat/src/test/java/org/apache/tamaya/spi/TestServiceContext.java
new file mode 100644
index 0000000..4b8edc1
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/spi/TestServiceContext.java
@@ -0,0 +1,120 @@
+/*
+ * 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.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link org.apache.tamaya.spi.ServiceContext} interface and hereby uses the JDK
+ * {@link java.util.ServiceLoader} to load the services required.
+ */
+public final class TestServiceContext implements ServiceContext {
+    /** List current services loaded, per class. */
+    private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+
+    private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+
+    @Override
+    public int ordinal() {
+        return 1;
+    }
+
+    @SuppressWarnings("rawtypes")
+	@Override
+    public <T> T getService(Class<T> serviceType) {
+        T cached = serviceType.cast(singletons.get(serviceType));
+        if(cached==null) {
+            cached = create(serviceType);
+            singletons.put((Class)serviceType, cached);
+        }
+        if (cached == Object.class) {
+            cached = null;
+        }
+        return cached;
+    }
+
+    @Override
+    public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+        return getService(serviceType, ServiceContext.defaultClassLoader());
+    }
+
+    @SuppressWarnings("unchecked")
+	@Override
+    public <T> T create(Class<T> serviceType) {
+        Collection<T> services = getServices(serviceType);
+        if (services.isEmpty()) {
+            return (T) Object.class; // as marker for 'nothing here'
+        }
+        else{
+            return services.iterator().next();
+        }
+    }
+
+    @Override
+    public <T> T create(Class<T> serviceType, ClassLoader classLoader) {
+        return create(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(Class<T> serviceType) {
+        try {
+            List<T> services = new ArrayList<>();
+            for (T t : ServiceLoader.load(serviceType)) {
+                services.add(t);
+            }
+            services = Collections.unmodifiableList(services);
+            @SuppressWarnings("unchecked")
+			final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>)services));
+            return previousServices != null ? previousServices : services;
+        } catch (Exception e) {
+            Logger.getLogger(TestServiceContext.class.getName()).log(Level.WARNING,
+                                      "Error loading services current type " + serviceType, e);
+            return Collections.emptyList();
+        }
+    }
+
+    @Override
+    public <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader) {
+        return getServices(serviceType, ServiceContext.defaultClassLoader());
+    }
+
+    @Override
+    public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException {
+        return cl.getResources(resource);
+    }
+
+    @Override
+    public URL getResource(String resource, ClassLoader cl) {
+        return cl.getResource(resource);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/spisupport/RegexFilterTest.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/spisupport/RegexFilterTest.java b/code/compat/src/test/java/org/apache/tamaya/spisupport/RegexFilterTest.java
new file mode 100644
index 0000000..5614c01
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/spisupport/RegexFilterTest.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.spisupport;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link RegexPropertyFilter}. Created by anatole on 11.02.16.
+ */
+public class RegexFilterTest {
+
+    private static PropertyValue prop1 = PropertyValue.of("test1", "test1", "test");
+    private static PropertyValue prop2 = PropertyValue.of("test2", "test2", "test");
+    private static PropertyValue prop3 = PropertyValue.of("test1.test3", "test.test3", "test");
+    private static Configuration config = new DefaultConfigurationBuilder().build();
+
+    @org.junit.Test
+    public void testFilterProperty() throws Exception {
+        RegexPropertyFilter filter = new RegexPropertyFilter();
+        filter.setIncludes("test1.*");
+        Map<String,PropertyValue> map = new HashMap<>();
+        map.put(prop1.getKey(), prop1);
+        map.put(prop2.getKey(), prop2);
+        map.put(prop3.getKey(), prop3);
+        FilterContext ctx = new FilterContext(prop1, config.getContext());
+        assertEquals(filter.filterProperty(prop1, ctx), prop1);
+        ctx = new FilterContext(prop2, config.getContext());
+        assertNull(filter.filterProperty(prop2, ctx));
+        ctx = new FilterContext(prop3, map, config.getContext());
+        assertEquals(filter.filterProperty(
+                prop3, ctx), prop3);
+        ctx = new FilterContext(prop3, map, config.getContext());
+        assertEquals(filter.filterProperty(
+                prop3, ctx), prop3);
+        filter = new RegexPropertyFilter();
+        filter.setIncludes("test1.*");
+        ctx = new FilterContext(prop1, map, config.getContext());
+        assertNotNull(filter.filterProperty(prop1, ctx));
+        ctx = new FilterContext(prop2, map, config.getContext());
+        assertNull(filter.filterProperty(prop2, ctx));
+        ctx = new FilterContext(prop3, map, config.getContext());
+        assertNotNull(filter.filterProperty(prop3, ctx));
+    }
+
+    @org.junit.Test
+    public void testToString() throws Exception {
+        RegexPropertyFilter filter = new RegexPropertyFilter();
+        filter.setIncludes("test\\..*");
+        assertTrue(filter.toString().contains("test\\..*"));
+        assertTrue(filter.toString().contains("RegexPropertyFilter"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/resources/META-INF/services/org.apache.tamaya.spi.ConfigurationProviderSpi
----------------------------------------------------------------------
diff --git a/code/compat/src/test/resources/META-INF/services/org.apache.tamaya.spi.ConfigurationProviderSpi b/code/compat/src/test/resources/META-INF/services/org.apache.tamaya.spi.ConfigurationProviderSpi
new file mode 100644
index 0000000..b9c5ba5
--- /dev/null
+++ b/code/compat/src/test/resources/META-INF/services/org.apache.tamaya.spi.ConfigurationProviderSpi
@@ -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.TestConfigurationProvider

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/code/compat/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/code/compat/src/test/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
new file mode 100644
index 0000000..199956f
--- /dev/null
+++ b/code/compat/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.spi.TestServiceContext
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/BannerManager.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/BannerManager.java b/code/core/src/main/java/org/apache/tamaya/core/BannerManager.java
new file mode 100644
index 0000000..d387267
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/BannerManager.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core;
+
+import javax.config.ConfigProvider;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * Controls the output of the banner of Tamaya.
+ *
+ * <p>This class controls if and how the banner of Tamaya is presented the user.
+ * The banner is provided by the Tamaya Core under the resource path
+ * {@value BANNER_RESOURCE_PATH}.</p>
+ *
+ * <p>The behavior of the banner manager can be controlled by
+ * specifying the configuration key {@code tamaya.banner} with one of
+ * the three folowing values:
+ *
+ * <dl>
+ *     <dt>OFF</dt>
+ *     <dd>Banner will not be shown</dd>
+ *     <dt>CONSOLE</dt>
+ *     <dd>The banner will be printed on STDOUT</dd>
+ *     <dt>LOGGER</dt>
+ *     <dd>The banner will be logged</dd>
+ * </dl>
+ *
+ * In case of any other value the banner will not be shown.
+ * </p>
+ *
+ *
+ *
+ * @see BannerTarget
+ */
+class BannerManager {
+    /**
+     * The resouce path to the file containing the banner of Tamaya.
+     */
+    protected final static String BANNER_RESOURCE_PATH = "/tamaya-banner.txt";
+
+    enum BannerTarget {
+        OFF, CONSOLE, LOGGER
+    }
+
+    private BannerTarget bannerTarget;
+
+    public BannerManager(String value) {
+        value = Objects.requireNonNull(value).toUpperCase(Locale.getDefault());
+
+        try {
+            bannerTarget = BannerTarget.valueOf(value);
+        } catch (NullPointerException | IllegalArgumentException e) {
+            bannerTarget = BannerTarget.OFF;
+        }
+    }
+
+    public void outputBanner() {
+        BannerPrinter bp = new SilentBannerPrinter();
+
+        switch (bannerTarget) {
+            case CONSOLE:
+                bp = new ConsoleBannerPrinter();
+                break;
+            case LOGGER:
+                bp = new LoggingBannerPrinter();
+                break;
+            case OFF:
+            default:
+                break;
+        }
+
+        bp.outputBanner();
+    }
+}
+
+abstract class AbstractBannerPrinter implements BannerPrinter {
+    private static final Logger log = Logger.getLogger(AbstractBannerPrinter.class.getName());
+
+    @Override
+    public void outputBanner() {
+        try (InputStream in = ConfigProvider.class.getResourceAsStream(BannerManager.BANNER_RESOURCE_PATH)) {
+            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+            String line;
+
+            while ((line = reader.readLine()) != null) {
+                outputSingleLine(line);
+            }
+        } catch (Exception e) {
+            log.log(Level.WARNING, "Failed to output the banner of tamaya.", e);
+        }
+    }
+
+    abstract void outputSingleLine(String line);
+}
+
+
+/**
+ * Outputs the Tamaya banner to an implementation specific output channel
+ * as STDOUT or the logging system.
+ */
+interface BannerPrinter {
+    /**
+     * Outputs the banner to the output channel
+     * used by the implementation.
+     */
+    void outputBanner();
+}
+
+/**
+ * Silent implementation of a {@link BannerPrinter}.
+ */
+class SilentBannerPrinter implements BannerPrinter {
+    @Override
+    public void outputBanner() {
+    }
+}
+
+/**
+ * Logs the banner via JUL at level {@link java.util.logging.Level#INFO}.
+ */
+class LoggingBannerPrinter extends AbstractBannerPrinter {
+    private static final Logger log = Logger.getLogger(LoggingBannerPrinter.class.getName());
+
+    @Override
+    void outputSingleLine(String line) {
+        log.log(Level.INFO, line);
+    }
+}
+
+/**
+ * Prints the banner to the console.
+ */
+class ConsoleBannerPrinter extends AbstractBannerPrinter {
+    @Override
+    void outputSingleLine(String line) {
+        System.out.println(line);
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceComparator.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceComparator.java b/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceComparator.java
new file mode 100644
index 0000000..009927d
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceComparator.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core;
+
+import org.osgi.framework.ServiceReference;
+
+import javax.annotation.Priority;
+import java.util.Comparator;
+
+/**
+ * Comparator implementation for ordering services loaded based on their increasing priority values.
+ */
+@SuppressWarnings("rawtypes")
+class OSGIServiceComparator implements Comparator<ServiceReference> {
+
+    @Override
+    public int compare(ServiceReference o1, ServiceReference o2) {
+        int prio = getPriority(o1) - getPriority(o2);
+        if (prio < 0) {
+            return 1;
+        } else if (prio > 0) {
+            return -1;
+        } else {
+            return 0; //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.
+     */
+    public static int getPriority(Class<? extends Object> type) {
+        int prio = 1;
+        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/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceContext.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceContext.java b/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceContext.java
new file mode 100644
index 0000000..eb01733
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceContext.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core;
+
+import org.apache.tamaya.spi.ServiceContext;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+import javax.config.spi.ConfigProviderResolver;
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * ServiceContext implementation based on OSGI Service mechanisms.
+ */
+public class OSGIServiceContext implements ServiceContext{
+
+    private static final Logger LOG = Logger.getLogger(OSGIServiceContext.class.getName());
+    private static final OSGIServiceComparator REF_COMPARATOR = new OSGIServiceComparator();
+
+    private final OSGIServiceLoader osgiServiceLoader;
+
+    public OSGIServiceContext(OSGIServiceLoader osgiServiceLoader){
+        this.osgiServiceLoader = Objects.requireNonNull(osgiServiceLoader);
+    }
+
+    public boolean isInitialized(){
+        return osgiServiceLoader != null;
+    }
+
+
+    @Override
+    public int ordinal() {
+        return 10;
+    }
+
+    @Override
+    public <T> T getService(Class<T> serviceType) {
+        LOG.finest("TAMAYA  Loading service: " + serviceType.getName());
+        ServiceReference<T> ref = this.osgiServiceLoader.getBundleContext().getServiceReference(serviceType);
+        if(ref!=null){
+            return this.osgiServiceLoader.getBundleContext().getService(ref);
+        }
+        if(ConfigProviderResolver.class==serviceType){
+            @SuppressWarnings("unchecked")
+			T service = (T)new TamayaConfigProviderResolver();
+            this.osgiServiceLoader.getBundleContext().registerService(
+                    serviceType.getName(),
+                    service,
+                    new Hashtable<String, Object>());
+            return service;
+        }
+        return null;
+    }
+
+    @Override
+    public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+        return getService(serviceType);
+    }
+
+    @SuppressWarnings("unchecked")
+	@Override
+    public <T> T create(Class<T> serviceType) {
+        LOG.finest("TAMAYA  Creating service: " + serviceType.getName());
+        ServiceReference<T> ref = this.osgiServiceLoader.getBundleContext().getServiceReference(serviceType);
+        if(ref!=null){
+            try {
+                return (T)this.osgiServiceLoader.getBundleContext().getService(ref).getClass().newInstance();
+            } catch (Exception e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public <T> T create(Class<T> serviceType, ClassLoader classLoader) {
+        return create(serviceType);
+    }
+
+    @Override
+    public <T> List<T> getServices(Class<T> serviceType) {
+        LOG.finest("TAMAYA  Loading services: " + serviceType.getName());
+        List<ServiceReference<T>> refs = new ArrayList<>();
+        List<T> services = new ArrayList<>(refs.size());
+        try {
+            refs.addAll(this.osgiServiceLoader.getBundleContext().getServiceReferences(serviceType, null));
+            Collections.sort(refs, REF_COMPARATOR);
+            for(ServiceReference<T> ref:refs){
+                T service = osgiServiceLoader.getBundleContext().getService(ref);
+                if(service!=null) {
+                    services.add(service);
+                }
+            }
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+        try{
+            for(T service:ServiceLoader.load(serviceType)){
+                services.add(service);
+            }
+            return services;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return services;
+    }
+
+    @Override
+    public <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader) {
+        return getServices(serviceType);
+    }
+
+    @Override
+    public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException{
+        LOG.finest("TAMAYA  Loading resources: " + resource);
+        List<URL> result = new ArrayList<>();
+        URL url = osgiServiceLoader.getBundleContext().getBundle()
+                .getEntry(resource);
+        if(url != null) {
+            LOG.finest("TAMAYA  Resource: " + resource + " found in unregistered bundle " +
+                    osgiServiceLoader.getBundleContext().getBundle().getSymbolicName());
+            result.add(url);
+        }
+        for(Bundle bundle: osgiServiceLoader.getResourceBundles()) {
+            url = bundle.getEntry(resource);
+            if (url != null && !result.contains(url)) {
+                LOG.finest("TAMAYA  Resource: " + resource + " found in registered bundle " + bundle.getSymbolicName());
+                result.add(url);
+            }
+        }
+        for(Bundle bundle: osgiServiceLoader.getBundleContext().getBundles()) {
+            url = bundle.getEntry(resource);
+            if (url != null && !result.contains(url)) {
+                LOG.finest("TAMAYA  Resource: " + resource + " found in unregistered bundle " + bundle.getSymbolicName());
+                result.add(url);
+            }
+        }
+        return Collections.enumeration(result);
+    }
+
+    @Override
+    public URL getResource(String resource, ClassLoader cl){
+        LOG.finest("TAMAYA  Loading resource: " + resource);
+        URL url = osgiServiceLoader.getBundleContext().getBundle()
+                .getEntry(resource);
+        if(url!=null){
+            LOG.finest("TAMAYA  Resource: " + resource + " found in bundle " +
+                    osgiServiceLoader.getBundleContext().getBundle().getSymbolicName());
+            return url;
+        }
+        for(Bundle bundle: osgiServiceLoader.getResourceBundles()) {
+            url = bundle.getEntry(resource);
+            if(url != null){
+                LOG.finest("TAMAYA  Resource: " + resource + " found in registered bundle " + bundle.getSymbolicName());
+                return url;
+            }
+        }
+        for(Bundle bundle: osgiServiceLoader.getBundleContext().getBundles()) {
+            url = bundle.getEntry(resource);
+            if(url != null){
+                LOG.finest("TAMAYA  Resource: " + resource + " found in unregistered bundle " + bundle.getSymbolicName());
+                return url;
+            }
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/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
new file mode 100644
index 0000000..90e74bc
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/OSGIServiceLoader.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.spisupport.PriorityServiceComparator;
+import org.osgi.framework.*;
+
+/**
+ * A bundle listener that registers services defined in META-INF/services, when
+ * a bundle is starting.
+ *
+ * @author anatole@apache.org
+ */
+@SuppressWarnings("rawtypes")
+public class OSGIServiceLoader implements BundleListener {
+	// Provide logging
+	private static final Logger log = Logger.getLogger(OSGIServiceLoader.class.getName());
+	private static final String META_INF_SERVICES = "META-INF/services/";
+
+	private BundleContext context;
+
+	private Set<Bundle> resourceBundles = Collections.synchronizedSet(new HashSet<Bundle>());
+
+	public OSGIServiceLoader(BundleContext context) {
+		this.context = Objects.requireNonNull(context);
+		// Check for matching bundles already installed...
+		for (Bundle bundle : context.getBundles()) {
+			switch (bundle.getState()) {
+			case Bundle.ACTIVE:
+				checkAndLoadBundle(bundle);
+			}
+		}
+	}
+
+	public BundleContext getBundleContext() {
+		return context;
+	}
+
+	public Set<Bundle> getResourceBundles() {
+		synchronized (resourceBundles) {
+			return new HashSet<>(resourceBundles);
+		}
+	}
+
+	@Override
+	public void bundleChanged(BundleEvent bundleEvent) {
+		// Parse and create metadata when installed
+		if (bundleEvent.getType() == BundleEvent.STARTED) {
+			Bundle bundle = bundleEvent.getBundle();
+			checkAndLoadBundle(bundle);
+		} else if (bundleEvent.getType() == BundleEvent.STOPPED) {
+			Bundle bundle = bundleEvent.getBundle();
+			checkAndUnloadBundle(bundle);
+		}
+	}
+
+	private void checkAndUnloadBundle(Bundle bundle) {
+		if (bundle.getEntry(META_INF_SERVICES) == null) {
+			return;
+		}
+		synchronized (resourceBundles) {
+			resourceBundles.remove(bundle);
+			log.fine("Unregistered ServiceLoader bundle: " + bundle.getSymbolicName());
+		}
+		Enumeration<String> entryPaths = bundle.getEntryPaths(META_INF_SERVICES);
+		while (entryPaths.hasMoreElements()) {
+			String entryPath = entryPaths.nextElement();
+			if (!entryPath.endsWith("/")) {
+				removeEntryPath(bundle, entryPath);
+			}
+		}
+	}
+
+	private void checkAndLoadBundle(Bundle bundle) {
+		if (bundle.getEntry(META_INF_SERVICES) == null) {
+			return;
+		}
+		synchronized (resourceBundles) {
+			resourceBundles.add(bundle);
+			log.info("Registered ServiceLoader bundle: " + bundle.getSymbolicName());
+		}
+		Enumeration<String> entryPaths = bundle.getEntryPaths(META_INF_SERVICES);
+		while (entryPaths.hasMoreElements()) {
+			String entryPath = entryPaths.nextElement();
+			if (!entryPath.endsWith("/")) {
+				processEntryPath(bundle, entryPath);
+			}
+		}
+	}
+
+	private void processEntryPath(Bundle bundle, String entryPath) {
+		try {
+			String serviceName = entryPath.substring(META_INF_SERVICES.length());
+			if (!serviceName.startsWith("org.apache.tamaya")) {
+				// Ignore non Tamaya entries...
+				return;
+			}
+			Class<?> serviceClass = bundle.loadClass(serviceName);
+			URL child = bundle.getEntry(entryPath);
+			InputStream inStream = child.openStream();
+			log.info("Loading Services " + serviceClass.getName() + " from bundle...: " + bundle.getSymbolicName());
+			try (BufferedReader br = new BufferedReader(new InputStreamReader(inStream, "UTF-8"))) {
+				String implClassName = br.readLine();
+				while (implClassName != null) {
+					int hashIndex = implClassName.indexOf("#");
+					if (hashIndex > 0) {
+						implClassName = implClassName.substring(0, hashIndex - 1);
+					} else if (hashIndex == 0) {
+						implClassName = "";
+					}
+					implClassName = implClassName.trim();
+					if (implClassName.length() > 0) {
+						try {
+							// Load the service class
+							log.fine("Loading Class " + implClassName + " from bundle...: " + bundle.getSymbolicName());
+							Class<?> implClass = bundle.loadClass(implClassName);
+							if (!serviceClass.isAssignableFrom(implClass)) {
+								log.warning("Configured service: " + implClassName + " is not assignable to "
+										+ serviceClass.getName());
+								continue;
+							}
+							log.info("Loaded Service Factory (" + serviceName + "): " + implClassName);
+							// Provide service properties
+							Hashtable<String, String> props = new Hashtable<>();
+							props.put(Constants.VERSION_ATTRIBUTE, bundle.getVersion().toString());
+							String vendor = bundle.getHeaders().get(Constants.BUNDLE_VENDOR);
+							props.put(Constants.SERVICE_VENDOR, (vendor != null ? vendor : "anonymous"));
+							// Translate annotated @Priority into a service ranking
+							props.put(Constants.SERVICE_RANKING,
+									String.valueOf(PriorityServiceComparator.getPriority(implClass)));
+
+							// Register the service factory on behalf of the intercepted bundle
+							JDKUtilServiceFactory factory = new JDKUtilServiceFactory(implClass);
+							BundleContext bundleContext = bundle.getBundleContext();
+							bundleContext.registerService(serviceName, factory, props);
+							log.info("Registered Tamaya service class: " + implClassName + "(" + serviceName + ")");
+						} catch (Exception e) {
+							log.log(Level.SEVERE, "Failed to load service: " + implClassName, e);
+						} catch (NoClassDefFoundError err) {
+							log.log(Level.SEVERE, "Failed to load service: " + implClassName, err);
+						}
+					}
+					implClassName = br.readLine();
+				}
+			}
+		} catch (RuntimeException rte) {
+			throw rte;
+		} catch (Exception e) {
+			log.log(Level.SEVERE, "Failed to read services from: " + entryPath, e);
+		}
+	}
+
+	private void removeEntryPath(Bundle bundle, String entryPath) {
+		try {
+			String serviceName = entryPath.substring(META_INF_SERVICES.length());
+			if (!serviceName.startsWith("org.apache.tamaya")) {
+				// Ignore non Tamaya entries...
+				return;
+			}
+			Class<?> serviceClass = bundle.loadClass(serviceName);
+
+			URL child = bundle.getEntry(entryPath);
+			InputStream inStream = child.openStream();
+
+			BufferedReader br = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
+			String implClassName = br.readLine();
+			while (implClassName != null) {
+				int hashIndex = implClassName.indexOf("#");
+				if (hashIndex > 0) {
+					implClassName = implClassName.substring(0, hashIndex - 1);
+				} else if (hashIndex == 0) {
+					implClassName = "";
+				}
+				implClassName = implClassName.trim();
+				if (implClassName.length() > 0) {
+					log.fine("Unloading Service (" + serviceName + "): " + implClassName);
+					try {
+						// Load the service class
+						Class<?> implClass = bundle.loadClass(implClassName);
+						if (!serviceClass.isAssignableFrom(implClass)) {
+							log.warning("Configured service: " + implClassName + " is not assignable to "
+									+ serviceClass.getName());
+							continue;
+						}
+						ServiceReference<?> ref = bundle.getBundleContext().getServiceReference(implClass);
+						if (ref != null) {
+							bundle.getBundleContext().ungetService(ref);
+						}
+					} catch (Exception e) {
+						log.log(Level.SEVERE, "Failed to unload service: " + implClassName, e);
+					} catch (NoClassDefFoundError err) {
+						log.log(Level.SEVERE, "Failed to unload service: " + implClassName, err);
+					}
+				}
+				implClassName = br.readLine();
+			}
+			br.close();
+		} catch (RuntimeException rte) {
+			throw rte;
+		} catch (Exception e) {
+			log.log(Level.SEVERE, "Failed to read services from: " + entryPath, e);
+		}
+	}
+
+	/**
+	 * Service factory simply instantiating the configured service.
+	 */
+	static class JDKUtilServiceFactory implements ServiceFactory {
+		private final Class<?> serviceClass;
+
+		public JDKUtilServiceFactory(Class<?> serviceClass) {
+			this.serviceClass = serviceClass;
+		}
+
+		@Override
+		public Object getService(Bundle bundle, ServiceRegistration registration) {
+			try {
+				log.fine("Creating Service...:" + serviceClass.getName());
+				return serviceClass.newInstance();
+			} catch (Exception ex) {
+				ex.printStackTrace();
+				throw new IllegalStateException("Failed to create service: " + serviceClass.getName(), ex);
+			}
+		}
+
+		@Override
+		public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/TamayaConfigProviderResolver.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/TamayaConfigProviderResolver.java b/code/core/src/main/java/org/apache/tamaya/core/TamayaConfigProviderResolver.java
new file mode 100644
index 0000000..f4bc048
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/TamayaConfigProviderResolver.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.core;
+
+import org.apache.tamaya.base.DefaultConfigBuilder;
+import org.apache.tamaya.spi.ConfigContext;
+import org.apache.tamaya.spi.Filter;
+import org.apache.tamaya.spi.ServiceContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.Config;
+import javax.config.spi.ConfigBuilder;
+import javax.config.spi.ConfigProviderResolver;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of the Configuration API. This class uses the current {@link ConfigContext} to evaluate the
+ * chain of {@link javax.config.spi.ConfigSource} and {@link Filter}
+ * instance to evaluate the current Configuration.
+ */
+@Component(service = ConfigProviderResolver.class)
+public class TamayaConfigProviderResolver extends ConfigProviderResolver {
+
+    private Map<ClassLoader, Config> configs = new ConcurrentHashMap<>();
+
+    @Override
+    public Config getConfig() {
+        return getConfig(Thread.currentThread().getContextClassLoader());
+    }
+
+    @Override
+    public Config getConfig(ClassLoader loader) {
+        Config config = this.configs.get(loader);
+        if(config==null){
+            config = new DefaultConfigBuilder()
+                    .addDiscoveredFilters()
+                    .addDiscoveredConverters()
+                    .addDefaultSources()
+                    .addDiscoveredSources()
+                    .build();
+            this.configs.put(loader, config);
+        }
+        return config;
+    }
+
+    @Override
+    public ConfigBuilder getBuilder() {
+        return new DefaultConfigBuilder();
+    }
+
+    @Override
+    public void registerConfig(Config config, ClassLoader classLoader) {
+        if(classLoader==null){
+            classLoader = ServiceContext.defaultClassLoader();
+        }
+        if(configs.containsKey(classLoader)){
+            Logger.getLogger(getClass().getName())
+                    .warning("Replacing existing config for classloader: " + classLoader);
+//            throw new IllegalArgumentException("Already a config registered with classloader: " + classLoader);
+        }
+        this.configs.put(classLoader, config);
+    }
+
+    @Override
+    public void releaseConfig(Config config) {
+        for(Map.Entry<ClassLoader, Config> en: this.configs.entrySet()){
+            if(en.getValue().equals(config)){
+                this.configs.remove(en.getKey());
+                return;
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/BigDecimalConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/BigDecimalConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/BigDecimalConverter.java
new file mode 100644
index 0000000..e29cf85
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/BigDecimalConverter.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to BigDecimal, the supported format is one of the following:
+ * <ul>
+ *     <li>232573527352.76352753</li>
+ *     <li>-23257352.735276352753</li>
+ *     <li>-0xFFFFFF (integral numbers only)</li>
+ *     <li>-0XFFFFAC (integral numbers only)</li>
+ *     <li>0xFFFFFF (integral numbers only)</li>
+ *     <li>0XFFFFAC (integral numbers only)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class BigDecimalConverter implements Converter<BigDecimal> {
+
+    /** The logger. */
+    private static final Logger LOG = Logger.getLogger(BigDecimalConverter.class.getName());
+    /** Converter to be used if the format is not directly supported by BigDecimal, e.g. for integral hex values. */
+    private final BigIntegerConverter integerConverter = new BigIntegerConverter();
+
+    @Override
+    public BigDecimal convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        if(context!=null) {
+            context.addSupportedFormats(getClass(), "<BigDecimal> -> new BigDecimal(String)");
+        }
+        String trimmed = Objects.requireNonNull(value).trim();
+        try{
+            return new BigDecimal(trimmed);
+        } catch(Exception e){
+            LOG.finest("Parsing BigDecimal failed, trying BigInteger for: " + value);
+            BigInteger bigInt = integerConverter.convert(value);
+            if(bigInt!=null){
+                return new BigDecimal(bigInt);
+            }
+            LOG.finest("Failed to parse BigDecimal from: " + value);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java
new file mode 100644
index 0000000..1e73b19
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/BigIntegerConverter.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.math.BigInteger;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to BigInteger, the supported format is one of the following:
+ * <ul>
+ *     <li>0xFFFFFF</li>
+ *     <li>0XFFFFAC</li>
+ *     <li>23257352735276352753</li>
+ *     <li>-0xFFFFFF</li>
+ *     <li>-0XFFFFAC</li>
+ *     <li>-23257352735276352753</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class BigIntegerConverter implements Converter<BigInteger> {
+
+    /** The logger. */
+    private static final Logger LOG = Logger.getLogger(BigIntegerConverter.class.getName());
+    /** Converter used to decode hex, octal values. */
+    private final ByteConverter byteConverter = new ByteConverter();
+
+    @Override
+    public BigInteger convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "[-]0X.. (hex)", "[-]0x... (hex)", "<bigint> -> new BigInteger(bigint)");
+        String trimmed = Objects.requireNonNull(value).trim();
+        if(trimmed.startsWith("0x") || trimmed.startsWith("0X")){
+            LOG.finest("Parsing Hex value to BigInteger: " + value);
+            trimmed = trimmed.substring(2);
+            StringBuilder decimal = new StringBuilder();
+            for(int offset = 0;offset < trimmed.length();offset+=2){
+                if(offset==trimmed.length()-1){
+                    LOG.finest("Invalid Hex-Byte-String: " + value);
+                    return null;
+                }
+                byte val = byteConverter.convert("0x" + trimmed.substring(offset, offset + 2));
+                if(val<10){
+                    decimal.append('0').append(val);
+                } else{
+                    decimal.append(val);
+                }
+            }
+            return new BigInteger(decimal.toString());
+        } else if(trimmed.startsWith("-0x") || trimmed.startsWith("-0X")){
+            LOG.finest("Parsing Hex value to BigInteger: " + value);
+            trimmed = trimmed.substring(3);
+            StringBuilder decimal = new StringBuilder();
+            for(int offset = 0;offset < trimmed.length();offset+=2){
+                if(offset==trimmed.length()-1){
+                    LOG.finest("Invalid Hex-Byte-String: " + trimmed);
+                    return null;
+                }
+                byte val = byteConverter.convert("0x" + trimmed.substring(offset, offset + 2));
+                if(val<10){
+                    decimal.append('0').append(val);
+                } else{
+                    decimal.append(val);
+                }
+            }
+            return new BigInteger('-' + decimal.toString());
+        }
+        try{
+            return new BigInteger(trimmed);
+        } catch(Exception e){
+            LOG.log(Level.FINEST, "Failed to parse BigInteger from: " + value, e);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/BooleanConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/BooleanConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/BooleanConverter.java
new file mode 100644
index 0000000..df322b1
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/BooleanConverter.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Boolean.
+ */
+@Component(service = Converter.class)
+public class BooleanConverter implements Converter<Boolean> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public Boolean convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "yes (ignore case)", "y (ignore case)", "true (ignore case)", "t (ignore case)", "1", "no (ignore case)", "n (ignore case)", "false (ignore case)", "f (ignore case)", "0");
+        String ignoreCaseValue = Objects.requireNonNull(value)
+                                        .trim()
+                                        .toLowerCase(Locale.ENGLISH);
+        switch(ignoreCaseValue) {
+            case "1":
+            case "yes":
+            case "y":
+            case "true":
+            case "t":
+            case "on":
+                return Boolean.TRUE;
+            case "no":
+            case "n":
+            case "false":
+            case "f":
+            case "0":
+            case "off":
+                return Boolean.FALSE;
+            default:
+                LOG.finest("Unknown boolean value encountered: " + value);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java
new file mode 100644
index 0000000..7b72cc5
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/ByteConverter.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Byte, the supported format is one of the following:
+ * <ul>
+ *     <li>123 (byte value)</li>
+ *     <li>0xFF (byte value)</li>
+ *     <li>0XDF (byte value)</li>
+ *     <li>0D1 (byte value)</li>
+ *     <li>-123 (byte value)</li>
+ *     <li>-0xFF (byte value)</li>
+ *     <li>-0XDF (byte value)</li>
+ *     <li>-0D1 (byte value)</li>
+ *     <li>MIN_VALUE (ignoring case)</li>
+ *     <li>MIN (ignoring case)</li>
+ *     <li>MAX_VALUE (ignoring case)</li>
+ *     <li>MAX (ignoring case)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class ByteConverter implements Converter<Byte> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public Byte convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(),"<byte>", "MIN_VALUE", "MIN", "MAX_VALUE", "MAX");
+        String trimmed = Objects.requireNonNull(value).trim();
+        switch(trimmed.toUpperCase(Locale.ENGLISH)){
+            case "MIN_VALUE":
+            case "MIN":
+                return Byte.MIN_VALUE;
+            case "MAX_VALUE":
+            case "MAX":
+                return Byte.MAX_VALUE;
+            default:
+                try{
+                    return Byte.decode(trimmed);
+                }
+                catch(Exception e){
+                    LOG.log(Level.FINEST, "Unparseable Byte: " + value);
+                    return null;
+                }
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java
new file mode 100644
index 0000000..9fa4e69
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/CharConverter.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Character, the supported format is one of the following:
+ * <ul>
+ *     <li>'a'</li>
+ *     <li>123 (byte value)</li>
+ *     <li>0xFF (byte value)</li>
+ *     <li>0XDF (byte value)</li>
+ *     <li>0D1 (byte value)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class CharConverter implements Converter<Character> {
+
+    private static final Logger LOG = Logger.getLogger(CharConverter.class.getName());
+
+    @Override
+    public Character convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(),"\\'<char>\\'", "<char>", "<charNum>");
+        String trimmed = Objects.requireNonNull(value).trim();
+        if(trimmed.isEmpty()){
+            return null;
+        }
+        if(trimmed.startsWith("'")) {
+            try {
+                trimmed = trimmed.substring(1, trimmed.length() - 1);
+                if (trimmed.isEmpty()) {
+                    return null;
+                }
+                return trimmed.charAt(0);
+            } catch (Exception e) {
+                LOG.finest("Invalid character format encountered: '" + value + "', valid formats are 'a', 101 and a.");
+                return null;
+            }
+        }
+        try {
+            Integer val = Integer.parseInt(trimmed);
+            return (char) val.shortValue();
+        } catch (Exception e) {
+            LOG.finest("Character format is not numeric: '" + value + "', using first character.");
+            return trimmed.charAt(0);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/ClassConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/ClassConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/ClassConverter.java
new file mode 100644
index 0000000..c998065
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/ClassConverter.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Class, hereby using the following classloaders:
+ * <ul>
+ *     <li>The current ThreadContext ClassLoader</li>
+ *     <li>The Classloader of this class</li>
+ *     <li>The system Classloader</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class ClassConverter implements Converter<Class<?>> {
+
+    private final Logger LOG = Logger.getLogger(getClass().getName());
+
+    @Override
+    public Class<?> convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        if(value==null){
+            return null;
+        }
+        context.addSupportedFormats(getClass(),"<fullyQualifiedClassName>");
+        String trimmed = Objects.requireNonNull(value).trim();
+        try{
+            return Class.forName(trimmed, false, Thread.currentThread().getContextClassLoader());
+        }
+        catch(Exception e){
+            LOG.finest("Class not found in context CL: " + trimmed);
+        }
+        try{
+            return Class.forName(trimmed, false, ClassConverter.class.getClassLoader());
+        }
+        catch(Exception e){
+            LOG.finest("Class not found in ClassConverter's CL: " + trimmed);
+        }
+        try{
+            return Class.forName(trimmed, false, ClassLoader.getSystemClassLoader());
+        }
+        catch(Exception e){
+            LOG.finest("Class not found in System CL (giving up): " + trimmed);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/ConvertQuery.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/ConvertQuery.java b/code/core/src/main/java/org/apache/tamaya/core/converters/ConvertQuery.java
new file mode 100644
index 0000000..2b22d83
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/ConvertQuery.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.apache.tamaya.spi.ConfigContext;
+import org.apache.tamaya.spi.ConfigContextSupplier;
+
+import javax.config.Config;
+import javax.config.spi.Converter;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Query to convert a String value.
+ * @param <T> the target type.
+ */
+final class ConvertQuery<T> implements Function<Config, T> {
+
+    private static final Logger LOG = Logger.getLogger(ConvertQuery.class.getName());
+
+    private String rawValue;
+    private Type type;
+
+    public ConvertQuery(String rawValue, Type type) {
+        this.rawValue = Objects.requireNonNull(rawValue);
+        this.type = Objects.requireNonNull(type);
+    }
+
+    @Override
+    public T apply(Config config) {
+        if(!(config instanceof ConfigContextSupplier)){
+            throw new IllegalArgumentException("Config must implement ConfigContextSupplier");
+        }
+        ConfigContext ctx = ((ConfigContextSupplier)config).getConfigContext();
+        List<Converter> converters = ctx.getConverters(type);
+        ConversionContext context = new ConversionContext.Builder("<nokey>", type)
+                .setConfiguration(config)
+                .setKey(ConvertQuery.class.getName())
+                .build();
+        ConversionContext.setContext(context);
+        try {
+            for (Converter<?> conv : converters) {
+                try {
+                    if (conv instanceof OptionalConverter) {
+                        continue;
+                    }
+                    T result = (T) conv.convert(rawValue);
+                    if (result != null) {
+                        return result;
+                    }
+                } catch (Exception e) {
+                    LOG.log(Level.FINEST, e, () -> "Converter " + conv + " failed to convert to " + type);
+                }
+            }
+        }finally{
+            ConversionContext.reset();
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/core/src/main/java/org/apache/tamaya/core/converters/CurrencyConverter.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/converters/CurrencyConverter.java b/code/core/src/main/java/org/apache/tamaya/core/converters/CurrencyConverter.java
new file mode 100644
index 0000000..502e05c
--- /dev/null
+++ b/code/core/src/main/java/org/apache/tamaya/core/converters/CurrencyConverter.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.converters;
+
+import org.apache.tamaya.base.convert.ConversionContext;
+import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.util.Currency;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to Currency, the supported format is one of the following:
+ * <ul>
+ *     <li>CHF (currency code)</li>
+ *     <li>123 (numeric currency value &gt;
+ *     = 0)</li>
+ *     <li>DE (ISO 2-digit country)</li>
+ *     <li>de_DE, de_DE_123 (Locale)</li>
+ * </ul>
+ */
+@Component(service = Converter.class)
+public class CurrencyConverter implements Converter<Currency> {
+
+    private static final Logger LOG = Logger.getLogger(CurrencyConverter.class.getName());
+
+    @Override
+    public Currency convert(String value) {
+        ConversionContext context = ConversionContext.getContext();
+        context.addSupportedFormats(getClass(), "<currencyCode>, using Locale.ENGLISH", "<numericValue>", "<locale>");
+        String trimmed = Objects.requireNonNull(value).trim();
+        try {
+            return Currency.getInstance(trimmed.toUpperCase(Locale.ENGLISH));
+        } catch (Exception e) {
+            LOG.log(Level.FINEST, "Not a valid textual currency code: " + trimmed + ", checking for numeric...", e);
+        }
+        try {
+            // Check for numeric code
+            Integer numCode = Integer.parseInt(trimmed);
+            for (Currency currency : Currency.getAvailableCurrencies()) {
+                if (currency.getNumericCode() == numCode) {
+                    return currency;
+                }
+            }
+        } catch (Exception e) {
+            LOG.log(Level.FINEST, "Not a valid numeric currency code: " + trimmed + ", checking for locale...", e);
+        }
+        try {
+            // Check for numeric code
+            String[] parts = trimmed.split("\\_");
+            Locale locale;
+            switch (parts.length) {
+                case 1:
+                    locale = new Locale("", parts[0]);
+                    break;
+                case 2:
+                    locale = new Locale(parts[0], parts[1]);
+                    break;
+                case 3:
+                    locale = new Locale(parts[0], parts[1], parts[2]);
+                    break;
+                default:
+                    locale = null;
+            }
+            if (locale != null) {
+                return Currency.getInstance(locale);
+            }
+            LOG.finest("Not a valid currency: " + trimmed + ", giving up...");
+        } catch (Exception e) {
+            LOG.log(Level.FINEST, "Not a valid country locale for currency: " + trimmed + ", giving up...", e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o){
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode(){
+        return getClass().hashCode();
+    }
+}


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

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySourceProvider.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySourceProvider.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySourceProvider.java
new file mode 100644
index 0000000..1becb50
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/BuildablePropertySourceProvider.java
@@ -0,0 +1,114 @@
+/*
+ * 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.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+
+import java.util.*;
+
+/**
+ * A Buildable property source.
+ */
+public class BuildablePropertySourceProvider implements PropertySourceProvider{
+
+    private List<PropertySource> sources = new ArrayList<>();
+
+    @Override
+    public Collection<PropertySource> getPropertySources() {
+        return Collections.unmodifiableCollection(sources);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BuildablePropertySourceProvider that = (BuildablePropertySourceProvider) 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<PropertySource> sources = new ArrayList<>();
+
+        private Builder() {
+        }
+
+        /**
+         * With propertySources.
+         *
+         * @param propertySources the propertySources
+         * @return the builder
+         */
+        public Builder withPropertySourcs(PropertySource... 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<PropertySource> sources) {
+            this.sources.addAll(sources);
+            return this;
+        }
+
+        /**
+         * Build buildable property source.
+         *
+         * @return the buildable property source
+         */
+        public BuildablePropertySourceProvider build() {
+            BuildablePropertySourceProvider buildablePropertySource = new BuildablePropertySourceProvider();
+            buildablePropertySource.sources.addAll(this.sources);
+            return buildablePropertySource;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.java
new file mode 100644
index 0000000..a83722f
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/CLIPropertySource.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.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.*;
+
+/**
+ * PropertySource that allows to add the programs main arguments as configuration entries. Unix syntax using '--' and
+ * '-' params is supported.
+ */
+public class CLIPropertySource extends BasePropertySource {
+
+    /** The original main arguments. */
+    private static String[] args = new String[0];
+
+    /** The map of parsed main arguments. */
+    private static Map<String,PropertyValue> mainArgs;
+
+    /** Initializes the initial state. */
+    static{
+        initMainArgs(args);
+    }
+
+    /**
+     * Creates a new instance.
+     */
+    public CLIPropertySource(){
+        this((String[])null);
+    }
+
+    /**
+     * Creates a new instance, allows optionally to pass the main arguments.
+     * @param args the args, or null.
+     */
+    public CLIPropertySource(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 CLIPropertySource(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){
+        CLIPropertySource.args = Objects.requireNonNull(args);
+        // TODO is there a way to figure out the args?
+        String argsProp = System.getProperty("main.args");
+        if(argsProp!=null){
+            CLIPropertySource.args = argsProp.split("\\s");
+        }
+        Map<String,String> result = null;
+        if(CLIPropertySource.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:CLIPropertySource.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);
+                    }
+                }
+            }
+        }
+        Map<String,PropertyValue> finalProps = new HashMap<>();
+        for(Map.Entry<String,String> en:result.entrySet()) {
+            finalProps.put(en.getKey(),
+                    PropertyValue.of(en.getKey(), en.getValue(), "main-args"));
+        }
+        CLIPropertySource.mainArgs = Collections.unmodifiableMap(finalProps);
+    }
+
+    @Override
+    public Map<String, PropertyValue> 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/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java
new file mode 100644
index 0000000..920f37b
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/EnvironmentPropertySource.java
@@ -0,0 +1,287 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>{@link PropertySource} 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 EnvironmentPropertySource} 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 EnvironmentPropertySource} 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 EnvironmentPropertySource extends BasePropertySource {
+    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 EnvironmentPropertySource}
+     */
+    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 EnvironmentPropertySource(){
+        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 EnvironmentPropertySource(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 EnvironmentPropertySource(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 EnvironmentPropertySource(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 PropertyValue get(String key) {
+        if (isDisabled()) {
+            return null;
+        }
+
+        String effectiveKey = hasPrefix() ? getPrefix() + "." + key
+                                          : key;
+
+        String value = getPropertiesProvider().getenv(effectiveKey);
+
+        return PropertyValue.of(key, value, getName());
+    }
+
+    private boolean hasPrefix() {
+        return null != prefix;
+    }
+
+    @Override
+    public Map<String, PropertyValue> getProperties() {
+        if(disabled){
+            return Collections.emptyMap();
+        }
+        String prefix = this.prefix;
+        if(prefix==null) {
+            Map<String, PropertyValue> entries = new HashMap<>(System.getenv().size());
+            for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
+                entries.put(entry.getKey(), PropertyValue.of(entry.getKey(), entry.getValue(), getName()));
+            }
+            return entries;
+        }else{
+            Map<String, PropertyValue> entries = new HashMap<>(System.getenv().size());
+            for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
+                entries.put(prefix + entry.getKey(), PropertyValue.of(prefix + entry.getKey(), entry.getValue(), getName()));
+            }
+            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 EnvironmentPropertySource}.</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();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java
new file mode 100644
index 0000000..92f520e
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/JavaConfigurationPropertySource.java
@@ -0,0 +1,134 @@
+/*
+ * 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.spisupport.propertysource;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.spisupport.PropertySourceComparator;
+
+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 JavaConfigurationPropertySource extends BasePropertySource {
+    /**
+     * 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/javaconfiguration.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/javaconfiguration.xml";
+
+    private static final int DEFAULT_ORDINAL = 900;
+
+    private boolean enabled = evaluateEnabled();
+
+    public JavaConfigurationPropertySource(){
+        super("resource:META-INF/javaconfiguration.*", 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<PropertySource> getPropertySources() {
+        List<PropertySource> propertySources = new ArrayList<>();
+        propertySources.addAll(loadPropertySourcesByName(DEFAULT_SIMPLE_PROPERTIES_FILE_NAME));
+        propertySources.addAll(loadPropertySourcesByName(DEFAULT_XML_PROPERTIES_FILE_NAME));
+        Collections.sort(propertySources, PropertySourceComparator.getInstance());
+        return propertySources;
+    }
+
+    private Collection<? extends PropertySource> loadPropertySourcesByName(String filename) {
+        List<PropertySource> 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 ConfigException(msg, e);
+        }
+
+        while (propertyLocations.hasMoreElements()) {
+            URL currentUrl = propertyLocations.nextElement();
+            SimplePropertySource sps = new SimplePropertySource(currentUrl);
+
+            propertySources.add(sps);
+        }
+
+        return propertySources;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled){
+        this.enabled = enabled;
+    }
+
+
+    @Override
+    public Map<String, PropertyValue> getProperties() {
+        if (!isEnabled()) {
+            return Collections.emptyMap();
+        }
+        Map<String,PropertyValue> result = new HashMap<>();
+        for(PropertySource ps:getPropertySources()){
+            result.putAll(ps.getProperties());
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "JavaConfigurationPropertySource{" +
+                "enabled=" + enabled +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/MapPropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/MapPropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/MapPropertySource.java
new file mode 100644
index 0000000..0cabb35
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/MapPropertySource.java
@@ -0,0 +1,102 @@
+/*
+ * 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.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertyValue;
+
+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 MapPropertySource extends BasePropertySource {
+
+    /**
+     * The current properties.
+     */
+    private final Map<String, PropertyValue> 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 MapPropertySource(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 MapPropertySource(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(),
+                        PropertyValue.of(en.getKey(), en.getValue(), name));
+            }
+        } else {
+            for (Map.Entry<String, String> en : props.entrySet()) {
+                this.props.put(prefix + en.getKey(),
+                        PropertyValue.of(prefix + en.getKey(), en.getValue(), name));
+            }
+        }
+    }
+
+    /**
+     * 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 MapPropertySource(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, PropertyValue> getProperties() {
+        return Collections.unmodifiableMap(this.props);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.java
new file mode 100644
index 0000000..27b6e4b
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/PropertiesResourcePropertySource.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.spisupport.propertysource;
+
+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 PropertiesResourcePropertySource extends MapPropertySource {
+    /** The logger used. */
+    private static final Logger LOGGER = Logger.getLogger(PropertiesResourcePropertySource.class.getName());
+
+    /**
+     * Creates a new instance.
+     * @param url the resource URL, not null.
+     */
+    public PropertiesResourcePropertySource(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 PropertiesResourcePropertySource(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 PropertiesResourcePropertySource(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 PropertiesResourcePropertySource(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 = PropertiesResourcePropertySource.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/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java
new file mode 100644
index 0000000..070a564
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/SimplePropertySource.java
@@ -0,0 +1,284 @@
+/*
+ * 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.spisupport.propertysource;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertyValue;
+
+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 org.apache.tamaya.spi.PropertySource} for
+ * simple property files and XML property files.
+ */
+public class SimplePropertySource extends BasePropertySource {
+
+    private static final Logger LOG = Logger.getLogger(SimplePropertySource.class.getName());
+
+    /**
+     * The current properties.
+     */
+    private Map<String, PropertyValue> properties = new HashMap<>();
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimplePropertySource(File propertiesLocation) {
+        super(propertiesLocation.toString(), 0);
+        try {
+            this.properties = load(propertiesLocation.toURI().toURL());
+        } catch (IOException e) {
+            throw new ConfigException("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 SimplePropertySource(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 SimplePropertySource(String name, Map<String, String> properties, int defaultOrdinal){
+        super(name, defaultOrdinal);
+        for(Map.Entry<String,String> en: properties.entrySet()) {
+            this.properties.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), name));
+        }
+    }
+
+    /**
+     * 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 SimplePropertySource(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 SimplePropertySource(String name, URL propertiesLocation) {
+        super(name, 0);
+        this.properties = load(propertiesLocation);
+    }
+
+    private SimplePropertySource(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, PropertyValue> 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, PropertyValue> load(URL propertiesFile) {
+        boolean isXML = isXMLPropertieFiles(propertiesFile);
+
+        Map<String, PropertyValue> 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, PropertyValue.of(key, props.getProperty(key), source));
+            }
+        } catch (IOException e) {
+            throw new ConfigException("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, PropertyValue> 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(), PropertyValue.of(en.getKey(), en.getValue(), name));
+            }
+            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, PropertyValue.of(key, val, name));
+            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 SimplePropertySource build() {
+            return new SimplePropertySource(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java
new file mode 100644
index 0000000..cfc60bb
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/SystemPropertySource.java
@@ -0,0 +1,199 @@
+/*
+ * 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.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This {@link org.apache.tamaya.spi.PropertySource} manages the system properties. You can disable this feature by
+ * setting {@code tamaya.envprops.disable} or {@code tamaya.defaults.disable}.
+ */
+public class SystemPropertySource extends BasePropertySource {
+
+    /**
+     * default ordinal used.
+     */
+    public static final int DEFAULT_ORDINAL = 1000;
+
+    private volatile Map<String,PropertyValue> 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 SystemPropertySource(){
+        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 SystemPropertySource(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 SystemPropertySource(String prefix, int ordinal){
+        this.prefix = prefix;
+        setOrdinal(ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     */
+    public SystemPropertySource(String prefix){
+        this.prefix = prefix;
+    }
+
+
+    private Map<String, PropertyValue> loadProperties() {
+        Properties sysProps = System.getProperties();
+        previousHash = System.getProperties().hashCode();
+        final String prefix = this.prefix;
+        Map<String, PropertyValue> 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(),
+                            PropertyValue.of((String) entry.getKey(),
+                                    (String) entry.getValue(),
+                                    getName()));
+                } else {
+                    entries.put(prefix + entry.getKey(),
+                            PropertyValue.of(prefix + entry.getKey(),
+                                    (String) entry.getValue(),
+                                    getName()));
+                }
+            }
+        }
+        return entries;
+    }
+
+    @Override
+    public String getName() {
+        if(disabled){
+            return super.getName() + "(disabled)";
+        }
+        return super.getName();
+    }
+
+    @Override
+    public PropertyValue get(String key) {
+        if(disabled){
+            return null;
+        }
+        String prefix = this.prefix;
+        if(prefix==null) {
+            return PropertyValue.of(key, System.getProperty(key), getName());
+        }
+        return PropertyValue.of(key, System.getProperty(key.substring(prefix.length())), getName());
+    }
+
+    @Override
+    public Map<String, PropertyValue> 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, PropertyValue> properties = loadProperties();
+            this.cachedProperties = Collections.unmodifiableMap(properties);
+        }
+        return this.cachedProperties;
+    }
+
+    @Override
+    public boolean isScannable() {
+        return true;
+    }
+
+    @Override
+    protected String toStringValues() {
+        return  super.toStringValues() +
+                "  prefix=" + prefix + '\n' +
+                "  disabled=" + disabled + '\n';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/WrappedPropertySource.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/WrappedPropertySource.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/WrappedPropertySource.java
new file mode 100644
index 0000000..feaaf7b
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/WrappedPropertySource.java
@@ -0,0 +1,126 @@
+/*
+ * 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.spisupport.propertysource;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spisupport.PropertySourceComparator;
+
+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 WrappedPropertySource implements PropertySource{
+
+    private Integer ordinal;
+    private PropertySource delegate;
+    private long loaded = System.currentTimeMillis();
+
+    private WrappedPropertySource(PropertySource delegate) {
+        this(delegate, null);
+    }
+
+    private WrappedPropertySource(PropertySource delegate, Integer ordinal) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.ordinal = ordinal;
+    }
+
+    public static WrappedPropertySource of(PropertySource ps) {
+        if(ps instanceof  WrappedPropertySource){
+            return (WrappedPropertySource)ps;
+        }
+        return new WrappedPropertySource(ps);
+    }
+
+    public static WrappedPropertySource of(PropertySource ps, Integer ordinal) {
+        if(ps instanceof  WrappedPropertySource){
+            return new WrappedPropertySource(((WrappedPropertySource)ps).getDelegate(), ordinal);
+        }
+        return new WrappedPropertySource(ps, ordinal);
+    }
+
+    public int getOrdinal() {
+        if(this.ordinal!=null){
+            return this.ordinal;
+        }
+        return PropertySourceComparator.getOrdinal(delegate);
+    }
+
+    public void setOrdinal(Integer ordinal) {
+        this.ordinal = ordinal;
+    }
+
+    public void setDelegate(PropertySource delegate) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.loaded = System.currentTimeMillis();
+    }
+
+    @Override
+    public String getName() {
+        return delegate.getName();
+    }
+
+    @Override
+    public PropertyValue get(String key) {
+        return delegate.get(key);
+    }
+
+    @Override
+    public Map<String, PropertyValue> getProperties() {
+        return delegate.getProperties();
+    }
+
+    @Override
+    public boolean isScannable() {
+        return delegate.isScannable();
+    }
+
+    public PropertySource getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof WrappedPropertySource)) return false;
+
+        WrappedPropertySource that = (WrappedPropertySource) 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() +
+                ", scannable=" + isScannable() +
+                ", loadedAt=" + loaded +
+                ", delegate-class=" + delegate.getClass().getName() +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/package-info.java
----------------------------------------------------------------------
diff --git a/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/package-info.java b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/package-info.java
new file mode 100644
index 0000000..21e5aec
--- /dev/null
+++ b/code/compat/src/main/java/org/apache/tamaya/spisupport/propertysource/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 internal implementations artifacts registered as services.
+ */
+package org.apache.tamaya.spisupport.propertysource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/main/resources/tamaya-banner.txt
----------------------------------------------------------------------
diff --git a/code/compat/src/main/resources/tamaya-banner.txt b/code/compat/src/main/resources/tamaya-banner.txt
new file mode 100644
index 0000000..b4ceca4
--- /dev/null
+++ b/code/compat/src/main/resources/tamaya-banner.txt
@@ -0,0 +1,11 @@
+
+ █████╗ ██████╗  █████╗  ██████╗██╗  ██╗███████╗    ████████╗ █████╗ ███╗   ███╗ █████╗ ██╗   ██╗ █████╗
+██╔══██╗██╔══██╗██╔══██╗██╔════╝██║  ██║██╔════╝    ╚══██╔══╝██╔══██╗████╗ ████║██╔══██╗╚██╗ ██╔╝██╔══██╗
+███████║██████╔╝███████║██║     ███████║█████╗         ██║   ███████║██╔████╔██║███████║ ╚████╔╝ ███████║
+██╔══██║██╔═══╝ ██╔══██║██║     ██╔══██║██╔══╝         ██║   ██╔══██║██║╚██╔╝██║██╔══██║  ╚██╔╝  ██╔══██║
+██║  ██║██║     ██║  ██║╚██████╗██║  ██║███████╗       ██║   ██║  ██║██║ ╚═╝ ██║██║  ██║   ██║   ██║  ██║
+╚═╝  ╚═╝╚═╝     ╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝╚══════╝       ╚═╝   ╚═╝  ╚═╝╚═╝     ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝
+
+Apache Tamaya Configuration API:  http://tamaya.incubator.apache.org
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/ConfigExceptionTest.java b/code/compat/src/test/java/org/apache/tamaya/ConfigExceptionTest.java
new file mode 100644
index 0000000..fa7da0a
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/ConfigExceptionTest.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;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests instantiating {@link ConfigException}.
+ */
+public class ConfigExceptionTest {
+
+    @Test
+    public void testCreationMessage(){
+        ConfigException ex = new ConfigException("test");
+        assertNull(ex.getCause());
+        assertEquals(ex.getMessage(), "test");
+    }
+
+    @Test
+    public void testCreationMessageThrowable(){
+        Exception e = new IllegalStateException("blabla");
+        ConfigException ex = new ConfigException("test", e);
+        assertTrue(ex.getCause() == e);
+        assertEquals("test", ex.getMessage());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/ConfigurationTest.java b/code/compat/src/test/java/org/apache/tamaya/ConfigurationTest.java
new file mode 100644
index 0000000..ecbb75c
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/ConfigurationTest.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;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * Test class that tests the default methods implemented on {@link org.apache.tamaya.Configuration}. The provided
+ * {@link org.apache.tamaya.TestConfiguration} is implemeted with maximal use of the default methods.
+ */
+public class ConfigurationTest {
+
+    @Test
+    public void testget() throws Exception {
+        assertEquals(Boolean.TRUE, ConfigurationProvider.getConfiguration().get("booleanTrue", Boolean.class));
+        assertEquals(Boolean.FALSE, ConfigurationProvider.getConfiguration().get("booleanFalse", Boolean.class));
+        assertEquals((int)Byte.MAX_VALUE, (int)ConfigurationProvider.getConfiguration().get("byte", Byte.class));
+        assertEquals(Integer.MAX_VALUE, (int)ConfigurationProvider.getConfiguration().get("int", Integer.class));
+        assertEquals(Long.MAX_VALUE, (long)ConfigurationProvider.getConfiguration().get("long", Long.class));
+        assertEquals(Float.MAX_VALUE, (double)ConfigurationProvider.getConfiguration().get("float", Float.class), 0.0d);
+        assertEquals(Double.MAX_VALUE, ConfigurationProvider.getConfiguration().get("double", Double.class), 0.0d);
+    }
+
+    @Test
+    public void testGetBoolean() throws Exception {
+        assertTrue(ConfigurationProvider.getConfiguration().get("booleanTrue", Boolean.class));
+        assertFalse(ConfigurationProvider.getConfiguration().get("booleanFalse", Boolean.class));
+        assertFalse(ConfigurationProvider.getConfiguration().get("foorBar", Boolean.class));
+    }
+
+    @Test
+    public void testGetInteger() throws Exception {
+        assertEquals(Integer.MAX_VALUE,(int) ConfigurationProvider.getConfiguration().get("int", Integer.class));
+    }
+
+    @Test
+    public void testGetLong() throws Exception {
+        assertEquals(Long.MAX_VALUE,(long) ConfigurationProvider.getConfiguration().get("long", Long.class));
+    }
+
+    @Test
+    public void testGetDouble() throws Exception {
+        assertEquals(Double.MAX_VALUE,ConfigurationProvider.getConfiguration().get("double", Double.class), 0.0d);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/TestConfiguration.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/TestConfiguration.java b/code/compat/src/test/java/org/apache/tamaya/TestConfiguration.java
new file mode 100644
index 0000000..a035467
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/TestConfiguration.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya;
+
+
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.TypeLiteral;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test Configuration class, that is used to testdata the default methods provided by the API.
+ */
+public class TestConfiguration implements Configuration{
+
+    private static final Map<String, String> VALUES;
+    static {
+        VALUES = new HashMap<>();
+        VALUES.put("long", String.valueOf(Long.MAX_VALUE));
+        VALUES.put("int", String.valueOf(Integer.MAX_VALUE));
+        VALUES.put("double", String.valueOf(Double.MAX_VALUE));
+        VALUES.put("float", String.valueOf(Float.MAX_VALUE));
+        VALUES.put("short", String.valueOf(Short.MAX_VALUE));
+        VALUES.put("byte", String.valueOf(Byte.MAX_VALUE));
+        VALUES.put("booleanTrue", "true");
+        VALUES.put("booleanFalse", "false");
+        VALUES.put("String", "aStringValue");
+    }
+
+    @Override
+    public String get(String key) {
+        return VALUES.get(key);
+    }
+
+    @Override
+    public String getOrDefault(String key, String defaultValue) {
+        String val = get(key);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+        T val = get(key, type);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    @SuppressWarnings("unchecked")
+	@Override
+    public <T> T get(String key, Class<T> type) {
+        if(type.equals(Long.class)){
+            return (T)(Object)Long.MAX_VALUE;
+        }
+        else if(type.equals(Integer.class)){
+            return (T)(Object) Integer.MAX_VALUE;
+        }
+        else if(type.equals(Double.class)){
+            return (T)(Object) Double.MAX_VALUE;
+        }
+        else if(type.equals(Float.class)){
+            return (T)(Object) Float.MAX_VALUE;
+        }
+        else if(type.equals(Short.class)){
+            return (T)(Object) Short.MAX_VALUE;
+        }
+        else if(type.equals(Byte.class)){
+            return (T)(Object) Byte.MAX_VALUE;
+        }
+        else if(type.equals(Boolean.class)){
+            if("booleanTrue".equals(key)) {
+                return (T)Boolean.TRUE;
+            }
+            else{
+                return (T)Boolean.FALSE;
+            }
+        }
+        else if(type.equals(String.class)){
+            return (T)"aStringValue";
+        }
+        throw new ConfigException("No such property: " + key);
+    }
+
+    @Override
+    public <T> T get(String key, org.apache.tamaya.spi.TypeLiteral<T> type) {
+        throw new RuntimeException("Method not implemented yet.");
+    }
+
+    @Override
+    public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
+        T val = get(key, type);
+        if(val==null){
+            return defaultValue;
+        }
+        return val;
+    }
+
+    @Override
+    public Configuration with(ConfigOperator operator) {
+        return null;
+    }
+
+    @Override
+    public <T> T query(ConfigQuery<T> query) {
+        throw new RuntimeException("Method not implemented yet.");
+    }
+
+    @Override
+    public ConfigurationContext getContext() {
+        return null;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        throw new RuntimeException("Method not implemented yet.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/TestConfigurationProvider.java b/code/compat/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
new file mode 100644
index 0000000..cc1e2c3
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/TestConfigurationProvider.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;
+
+import javax.annotation.Priority;
+
+import org.apache.tamaya.spi.*;
+
+/**
+ * Test Configuration class, that is used to testdata the default methods provided by the API.
+ */
+@Priority(-1)
+public class TestConfigurationProvider implements ConfigurationProviderSpi {
+
+    private static final Configuration config = new TestConfiguration();
+
+    @Override
+    public Configuration getConfiguration() {
+        return config;
+    }
+
+    @Override
+    public Configuration createConfiguration(ConfigurationContext context) {
+        return config;
+    }
+
+    @Override
+    public ConfigurationContext getConfigurationContext() {
+        return config.getContext();
+    }
+
+    @Override
+    public void setConfigurationContext(ConfigurationContext context) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isConfigurationContextSettable() {
+        return false;
+    }
+
+    @Override
+    public ConfigurationBuilder getConfigurationBuilder() {
+        return null;
+    }
+
+    @Override
+    public ConfigurationContextBuilder getConfigurationContextBuilder() {
+        return null;
+    }
+
+    @Override
+    public void setConfiguration(Configuration config) {
+    }
+
+    @Override
+    public boolean isConfigurationSettable() {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/TypeLiteralTest.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/TypeLiteralTest.java b/code/compat/src/test/java/org/apache/tamaya/TypeLiteralTest.java
new file mode 100644
index 0000000..8e2ddc6
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/TypeLiteralTest.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;
+
+import static org.apache.tamaya.spi.TypeLiteral.getGenericInterfaceTypeParameters;
+import static org.apache.tamaya.spi.TypeLiteral.getTypeParameters;
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tamaya.spi.TypeLiteral;
+import org.junit.Test;
+
+/**
+ * Tests for the {@link org.apache.tamaya.spi.TypeLiteral} class.
+ */
+@SuppressWarnings("serial")
+public class TypeLiteralTest {
+
+	@Test(expected = NullPointerException.class)
+    public void constructorRequiresNonNullParameter() {
+       new org.apache.tamaya.spi.TypeLiteral<List<String>>(null){};
+    }
+
+    @Test
+    public void test_constrcutor(){
+        org.apache.tamaya.spi.TypeLiteral<List<String>> listTypeLiteral = new org.apache.tamaya.spi.TypeLiteral<List<String>>(){};
+        assertEquals(List.class, listTypeLiteral.getRawType());
+        assertEquals(String.class, org.apache.tamaya.spi.TypeLiteral.getTypeParameters(listTypeLiteral.getType())[0]);
+    }
+
+    @Test
+    public void test_of(){
+        class MyListClass extends ArrayList<String>{}
+        org.apache.tamaya.spi.TypeLiteral<MyListClass> listTypeLiteral = org.apache.tamaya.spi.TypeLiteral.of(MyListClass.class);
+        assertEquals(MyListClass.class, listTypeLiteral.getRawType());
+        assertEquals(MyListClass.class, listTypeLiteral.getType());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void ofDoesNotAcceptNullAsParamter() {
+        org.apache.tamaya.spi.TypeLiteral.of(null);
+    }
+
+    @Test
+    public void test_getTypeParameter(){
+        org.apache.tamaya.spi.TypeLiteral<List<String>> listTypeLiteral = new org.apache.tamaya.spi.TypeLiteral<List<String>>(){};
+        assertEquals(List.class, listTypeLiteral.getRawType());
+        assertEquals(String.class, TypeLiteral.getTypeParameters(listTypeLiteral.getType())[0]);
+    }
+
+    @Test
+    public void test_getGenericInterfaceTypeParameter(){
+        class MyListClass extends ArrayList<String> implements List<String>{}
+        assertEquals(String.class, getGenericInterfaceTypeParameters(MyListClass.class, List.class)[0]);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getGenericInterfaceTypeParametersRequiredNonNullValueForClassParameter() {
+        getGenericInterfaceTypeParameters(null, Iterator.class);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getGenericInterfaceTypeParametersRequiredNonNullValueForInterfaceParameter() {
+        getGenericInterfaceTypeParameters(String.class, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getTypeParametersRequiresNonNullParameter() {
+        getTypeParameters(null);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/d0e14ed7/code/compat/src/test/java/org/apache/tamaya/spi/ConversionContextTest.java
----------------------------------------------------------------------
diff --git a/code/compat/src/test/java/org/apache/tamaya/spi/ConversionContextTest.java b/code/compat/src/test/java/org/apache/tamaya/spi/ConversionContextTest.java
new file mode 100644
index 0000000..42673f8
--- /dev/null
+++ b/code/compat/src/test/java/org/apache/tamaya/spi/ConversionContextTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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.ConfigOperator;
+import org.apache.tamaya.ConfigQuery;
+import org.apache.tamaya.Configuration;
+import org.junit.Test;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link org.apache.tamaya.base.convert.ConversionContext}, created by atsticks on 20.08.16.
+ */
+public class ConversionContextTest {
+    @Test
+    public void getKey() throws Exception {
+        ConversionContext ctx = new org.apache.tamaya.spi.ConversionContext.Builder("getKey", TypeLiteral.of(String.class)).build();
+        assertEquals("getKey", ctx.getKey());
+    }
+
+    @Test
+    public void getTargetType() throws Exception {
+        ConversionContext ctx = new ConversionContext.Builder("getTargetType", TypeLiteral.of(String.class)).build();
+        assertEquals(TypeLiteral.of(String.class), ctx.getTargetType());
+    }
+
+    @Test
+    public void getAnnotatedElement() throws Exception {
+        ConversionContext ctx = new ConversionContext.Builder("getAnnotatedElement", TypeLiteral.of(List.class)).build();
+        assertNull(ctx.getAnnotatedElement());
+    }
+
+    @Test
+    public void testConfiguration() throws Exception {
+        Configuration config = new MyConfiguration();
+        ConversionContext ctx = new ConversionContext.Builder("testConfiguration", TypeLiteral.of(List.class))
+                .setConfiguration(config).build();
+        assertEquals(config, ctx.getConfiguration());
+    }
+
+    @Test
+    public void testSupportedFormats() throws Exception {
+        ConversionContext ctx = new ConversionContext.Builder("getAnnotatedElement", TypeLiteral.of(List.class))
+                .addSupportedFormats(MyConverter.class, "0.0.0.0/nnn").build();
+        assertTrue(ctx.getSupportedFormats().contains("0.0.0.0/nnn (MyConverter)"));
+    }
+
+    @Test
+    public void testToString() throws Exception {
+        ConversionContext ctx = new ConversionContext.Builder("getAnnotatedElement", TypeLiteral.of(List.class))
+                .addSupportedFormats(MyConverter.class, "0.0.0.0/nnn").build();
+        assertEquals("ConversionContext{configuration=null, key='getAnnotatedElement', targetType=TypeLiteral{type=interface java.util.List}, annotatedElement=null, supportedFormats=[0.0.0.0/nnn (MyConverter)]}", ctx.toString());
+    }
+
+    @Test
+    public void getConfigurationContext() throws Exception {
+        ConfigurationContext context = new MyConfigurationContext();
+        ConversionContext ctx = new ConversionContext.Builder("getAnnotatedElement", TypeLiteral.of(List.class))
+                .setConfigurationContext(context).build();
+        assertEquals(context, ctx.getConfigurationContext());
+    }
+
+
+    private static final class MyConverter implements PropertyConverter<InetAddress>{
+        @Override
+        public InetAddress convert(String value, ConversionContext context) {
+            return null;
+        }
+    }
+
+    private static final class MyConfigurationContext implements ConfigurationContext {
+
+        @Override
+        public void addPropertySources(PropertySource... propertySources) {
+
+        }
+
+        @Override
+        public List<PropertySource> getPropertySources() {
+            return null;
+        }
+
+        @Override
+        public PropertySource getPropertySource(String name) {
+            return null;
+        }
+
+        @Override
+        public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+
+        }
+
+        @Override
+        public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+            return null;
+        }
+
+        @Override
+        public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> type) {
+            return null;
+        }
+
+        @Override
+        public List<PropertyFilter> getPropertyFilters() {
+            return null;
+        }
+
+        @Override
+        public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy() {
+            return null;
+        }
+
+        @Override
+        public ConfigurationContextBuilder toBuilder() {
+            return null;
+        }
+    }
+
+    private static final class MyConfiguration implements Configuration{
+
+        @Override
+        public String get(String key) {
+            return null;
+        }
+
+        @Override
+        public String getOrDefault(String key, String defaultValue) {
+            return null;
+        }
+
+        @Override
+        public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
+            return null;
+        }
+
+        @Override
+        public <T> T get(String key, Class<T> type) {
+            return null;
+        }
+
+        @Override
+        public <T> T get(String key, TypeLiteral<T> type) {
+            return null;
+        }
+
+        @Override
+        public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
+            return null;
+        }
+
+        @Override
+        public Map<String, String> getProperties() {
+            return null;
+        }
+
+        @Override
+        public Configuration with(ConfigOperator operator) {
+            return null;
+        }
+
+        @Override
+        public <T> T query(ConfigQuery<T> query) {
+            return null;
+        }
+
+        @Override
+        public ConfigurationContext getContext() {
+            return null;
+        }
+    }
+
+}
\ No newline at end of file