http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/JavaConfigurationConfigSource.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/configsource/JavaConfigurationConfigSource.java
 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/JavaConfigurationConfigSource.java
new file mode 100644
index 0000000..6fb3fc8
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/JavaConfigurationConfigSource.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.base.configsource;
+
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.config.spi.ConfigSource;
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+
+import static java.lang.String.format;
+import static java.lang.Thread.currentThread;
+
+/**
+ * Provider which reads all {@value DEFAULT_SIMPLE_PROPERTIES_FILE_NAME} and
+ * {@value DEFAULT_XML_PROPERTIES_FILE_NAME} files found in the
+ * classpath. By setting
+ * {@code tamaya.defaultprops.disable} or {@code tamaya.defaults.disable}
+ * as system or environment property this feature can be disabled.
+ */
+public class JavaConfigurationConfigSource extends BaseConfigSource {
+    /**
+     * Default location in the classpath, where Tamaya looks for simple line 
based configuration by default.
+     */
+    public static final String 
DEFAULT_SIMPLE_PROPERTIES_FILE_NAME="META-INF/javaconfig.properties";
+
+    /**
+     * Default location in the classpath, where Tamaya looks for XML based 
configuration by default.
+     */
+    public static final String DEFAULT_XML_PROPERTIES_FILE_NAME = 
"META-INF/javaconfig.xml";
+
+    private static final int DEFAULT_ORDINAL = 900;
+
+    private boolean enabled = evaluateEnabled();
+
+    public JavaConfigurationConfigSource(){
+        super("resource:META-INF/javaconfig.*", DEFAULT_ORDINAL);
+    }
+
+    private boolean evaluateEnabled() {
+        String value = System.getProperty("tamaya.defaultprops.disable");
+        if(value==null){
+            value = System.getenv("tamaya.defaultprops.disable");
+        }
+        if(value==null){
+            value = System.getProperty("tamaya.defaults.disable");
+        }
+        if(value==null){
+            value = System.getenv("tamaya.defaults.disable");
+        }
+        if(value==null){
+            return true;
+        }
+        return value.isEmpty() || !Boolean.parseBoolean(value);
+    }
+
+    private List<ConfigSource> getPropertySources() {
+        List<ConfigSource> propertySources = new ArrayList<>();
+        
propertySources.addAll(loadPropertySourcesByName(DEFAULT_SIMPLE_PROPERTIES_FILE_NAME));
+        
propertySources.addAll(loadPropertySourcesByName(DEFAULT_XML_PROPERTIES_FILE_NAME));
+        Collections.sort(propertySources, 
ConfigSourceComparator.getInstance());
+        return propertySources;
+    }
+
+    private Collection<? extends ConfigSource> 
loadPropertySourcesByName(String filename) {
+        List<ConfigSource> propertySources = new ArrayList<>();
+        Enumeration<URL> propertyLocations;
+        try {
+            propertyLocations = ServiceContextManager.getServiceContext()
+                    .getResources(filename, 
currentThread().getContextClassLoader());
+        } catch (IOException e) {
+            String msg = format("Error while searching for %s", filename);
+
+            throw new IllegalStateException(msg, e);
+        }
+
+        while (propertyLocations.hasMoreElements()) {
+            URL currentUrl = propertyLocations.nextElement();
+            SimpleConfigSource sps = new SimpleConfigSource(currentUrl);
+
+            propertySources.add(sps);
+        }
+
+        return propertySources;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled){
+        this.enabled = enabled;
+    }
+
+
+    @Override
+    public Map<String, String> getProperties() {
+        if (!isEnabled()) {
+            return Collections.emptyMap();
+        }
+        Map<String,String> result = new HashMap<>();
+        for(ConfigSource ps:getPropertySources()){
+            result.putAll(ps.getProperties());
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "JavaConfigPropertySource{" +
+                "enabled=" + enabled +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/MapConfigSource.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/configsource/MapConfigSource.java
 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/MapConfigSource.java
new file mode 100644
index 0000000..2defa06
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/MapConfigSource.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tamaya.base.configsource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Simple PropertySource implementation that just takes a Map and an 
(optional) priority.
+ * Optionally the entries passed can be mapped to a different rootContext.
+ */
+public class MapConfigSource extends BaseConfigSource {
+
+    /**
+     * The current properties.
+     */
+    private final Map<String, String> props = new HashMap<>();
+
+    /**
+     * Creates a new instance, hereby using the default mechanism for 
evaluating the property source's
+     * priority.
+     *
+     * @param name unique name of this source.
+     * @param props the properties
+     */
+    public MapConfigSource(String name, Map<String, String> props) {
+        this(name, props, null);
+    }
+
+    /**
+     * Creates a new instance, hereby using the default mechanism for 
evaluating the property source's
+     * priority, but applying a custom mapping {@code prefix} to the entries 
provided.
+     *
+     * @param name        unique name of this source.
+     * @param props       the properties
+     * @param prefix      the prefix context mapping, or null (for no mapping).
+     */
+    public MapConfigSource(String name, Map<String, String> props, String 
prefix) {
+        super(name);
+        if (prefix == null) {
+            for (Map.Entry<String, String> en : props.entrySet()) {
+                this.props.put(en.getKey(), en.getValue());
+            }
+        } else {
+            for (Map.Entry<String, String> en : props.entrySet()) {
+                this.props.put(prefix + en.getKey(), en.getValue());
+            }
+        }
+    }
+
+    /**
+     * Creates a new instance, hereby using the default mechanism for 
evaluating the property source's
+     * priority, but applying a custom mapping {@code rootContext} to the 
entries provided.
+     *
+     * @param name unique name of this source.
+     * @param props       the properties
+     * @param prefix      the prefix context mapping, or null (for no mapping).
+     */
+    public MapConfigSource(String name, Properties props, String prefix) {
+        this(name, getMap(props), prefix);
+    }
+
+    /**
+     * Simple method to convert Properties into a Map instance.
+     * @param props the properties, not null.
+     * @return the corresponding Map instance.
+     */
+    public static Map<String, String> getMap(Properties props) {
+        Map<String, String> result = new HashMap<>();
+        for (Map.Entry en : props.entrySet()) {
+            result.put(en.getKey().toString(), en.getValue().toString());
+        }
+        return result;
+    }
+
+
+    @Override
+    public Map<String, String> getProperties() {
+        return Collections.unmodifiableMap(this.props);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/PropertiesResourceConfigSource.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/configsource/PropertiesResourceConfigSource.java
 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/PropertiesResourceConfigSource.java
new file mode 100644
index 0000000..4e974df
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/PropertiesResourceConfigSource.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.base.configsource;
+
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Simple PropertySource, with a fixed ordinal that reads a .properties file 
from a given URL.
+ */
+public class PropertiesResourceConfigSource extends MapConfigSource {
+    /** The logger used. */
+    private static final Logger LOGGER = 
Logger.getLogger(PropertiesResourceConfigSource.class.getName());
+
+    /**
+     * Creates a new instance.
+     * @param url the resource URL, not null.
+     */
+    public PropertiesResourceConfigSource(URL url){
+        this(url, null);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the (optional) prefix context for mapping (prefixing) the 
properties loaded.
+     * @param url the resource URL, not null.
+     */
+    public PropertiesResourceConfigSource(URL url, String prefix){
+        super(url.toExternalForm(), loadProps(url), prefix);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the (optional) prefix context for mapping (prefixing) the 
properties loaded.
+     * @param path the resource path, not null.
+     */
+    public PropertiesResourceConfigSource(String path, String prefix){
+        super(path, loadProps(path, null), prefix);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the (optional) prefix context for mapping (prefixing) the 
properties loaded.
+     * @param path the resource path, not null.
+     */
+    public PropertiesResourceConfigSource(String path, String prefix, 
ClassLoader cl){
+        super(path, loadProps(path, cl), prefix);
+    }
+
+    /**
+     * Loads the properties using the JDK's Property loading mechanism.
+     * @param path the resource classpath, not null.
+     * @return the loaded properties.
+     */
+    private static Map<String, String> loadProps(String path, ClassLoader cl) {
+        if(cl==null){
+            cl = PropertiesResourceConfigSource.class.getClassLoader();
+        }
+        URL url = ServiceContextManager.getServiceContext().getResource(path, 
cl);
+        return loadProps(url);
+    }
+
+    /**
+     * Loads the properties using the JDK's Property loading mechanism.
+     * @param url the resource URL, not null.
+     * @return the loaded properties.
+     */
+    private static Map<String, String> loadProps(URL url) {
+        Map<String,String> result = new HashMap<>();
+        if(url!=null) {
+            try (InputStream is = url.openStream()) {
+                Properties props = new Properties();
+                props.load(is);
+                for (Map.Entry en : props.entrySet()) {
+                    result.put(en.getKey().toString(), 
en.getValue().toString());
+                }
+            } catch (Exception e) {
+                LOGGER.log(Level.WARNING, "Failed to read properties from " + 
url, e);
+            }
+        }else{
+            LOGGER.log(Level.WARNING, "No properties found at " + url);
+        }
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/SimpleConfigSource.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/configsource/SimpleConfigSource.java
 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/SimpleConfigSource.java
new file mode 100644
index 0000000..8d59c4c
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/SimpleConfigSource.java
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.base.configsource;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+/**
+ * Simple implementation of a {@link javax.config.spi.ConfigSource} for
+ * simple property files and XML property files.
+ */
+public class SimpleConfigSource extends BaseConfigSource {
+
+    private static final Logger LOG = 
Logger.getLogger(SimpleConfigSource.class.getName());
+
+    /**
+     * The current properties.
+     */
+    private Map<String, String> properties = new HashMap<>();
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimpleConfigSource(File propertiesLocation) {
+        super(propertiesLocation.toString(), 0);
+        try {
+            this.properties = load(propertiesLocation.toURI().toURL());
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed to load properties from 
" + propertiesLocation, e);
+        }
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimpleConfigSource(URL propertiesLocation) {
+        super(propertiesLocation.toString(), 0);
+        this.properties = load(Objects.requireNonNull(propertiesLocation));
+    }
+
+    /**
+     * Creates a new Properties based PropertySource.
+     *
+     * @param name the property source name, not null.
+     * @param properties the properties, not null
+     * @param defaultOrdinal the default ordinal
+     */
+    public SimpleConfigSource(String name, Map<String, String> properties, int 
defaultOrdinal){
+        super(name, defaultOrdinal);
+        for(Map.Entry<String,String> en: properties.entrySet()) {
+            this.properties.put(en.getKey(), en.getValue());
+        }
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given 
properties map.
+     *
+     * @param name       the name, not null.
+     * @param properties the properties, not null.
+     */
+    public SimpleConfigSource(String name, Map<String, String> properties) {
+        this(name, properties, 0);
+    }
+
+    /**
+     * Creates a new Properties based PropertySource based on the given URL.
+     *
+     * @param name               The property source name
+     * @param propertiesLocation the URL encoded location, not null.
+     */
+    public SimpleConfigSource(String name, URL propertiesLocation) {
+        super(name, 0);
+        this.properties = load(propertiesLocation);
+    }
+
+    private SimpleConfigSource(Builder builder) {
+        properties = builder.properties;
+        if(builder.defaultOrdinal!=null){
+            setDefaultOrdinal(builder.defaultOrdinal);
+        }
+        if(builder.ordinal!=null){
+            setOrdinal(builder.ordinal);
+        }
+        setName(builder.name);
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return this.properties;
+    }
+
+    /**
+     * loads the Properties from the given URL
+     *
+     * @param propertiesFile {@link URL} to load Properties from
+     * @return loaded {@link Properties}
+     * @throws IllegalStateException in case of an error while reading 
properties-file
+     */
+    private static Map<String, String> load(URL propertiesFile) {
+        boolean isXML = isXMLPropertieFiles(propertiesFile);
+
+        Map<String, String> properties = new HashMap<>();
+        try (InputStream stream = propertiesFile.openStream()) {
+            Properties props = new Properties();
+            if (stream != null) {
+                if (isXML) {
+                    props.loadFromXML(stream);
+                } else {
+                    props.load(stream);
+                }
+            }
+            String source = propertiesFile.toString();
+            for (String key : props.stringPropertyNames()) {
+                properties.put(key, props.getProperty(key));
+            }
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Error loading properties from 
" + propertiesFile, e);
+        }
+
+        return properties;
+    }
+
+    private static boolean isXMLPropertieFiles(URL url) {
+        return url.getFile().endsWith(".xml");
+    }
+
+
+    /**
+     * {@code SimplePropertySource} builder static inner class.
+     */
+    public static final class Builder {
+        private String name;
+        private Integer defaultOrdinal;
+        private Integer ordinal;
+        private Map<String, String> properties = new HashMap<>();
+
+        private Builder() {
+        }
+
+        /**
+         * Sets the {@code name} to a new UUID and returns a reference to this 
Builder so that the methods
+         * can be chained together.
+         *
+         * @return a reference to this Builder
+         */
+        public Builder withUuidName() {
+            this.name = UUID.randomUUID().toString();
+            return this;
+        }
+
+        /**
+         * Sets the {@code name} and returns a reference to this Builder so 
that the methods
+         * can be chained together.
+         *
+         * @param val the {@code name} to set, not null.
+         * @return a reference to this Builder
+         */
+        public Builder withName(String val) {
+            this.name = Objects.requireNonNull(name);
+            return this;
+        }
+
+        /**
+         * Sets the {@code ordinal} and returns a reference to this Builder so 
that the methods
+         * can be chained together.
+         *
+         * @param val the {@code ordinal} to set
+         * @return a reference to this Builder
+         */
+        public Builder withOrdinal(int val) {
+            this.ordinal = val;
+            return this;
+        }
+
+        /**
+         * Sets the {@code defaultOrdinal} and returns a reference to this 
Builder so that the methods
+         * can be chained together.
+         *
+         * @param val the {@code defaultOrdinal} to set
+         * @return a reference to this Builder
+         */
+        public Builder withDefaultOrdinal(int val) {
+            this.defaultOrdinal = val;
+            return this;
+        }
+
+        /**
+         * Reads the {@code properties} from the given resource and returns a 
reference
+         * to this Builder so that the methods can be chained together.
+         *
+         * @param resource the {@code resource} to read
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(URL resource) {
+            this.properties.putAll(load(resource));
+            return this;
+        }
+
+        /**
+         * Reads the {@code properties} from the given resource and returns a 
reference
+         * to this Builder so that the methods can be chained together.
+         *
+         * @param file the {@code file} to read from (xml or properties 
format).
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(File file) {
+            try {
+                this.properties.putAll(load(file.toURI().toURL()));
+            } catch (MalformedURLException e) {
+                throw new IllegalArgumentException("Failed to read file: " + 
file, e);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the {@code properties} and returns a reference to this Builder 
so that the methods can be chained together.
+         *
+         * @param val the {@code properties} to set
+         * @return a reference to this Builder
+         */
+        public Builder withProperties(Map<String, String> val) {
+            for(Map.Entry<String,String> en: val.entrySet()) {
+                this.properties.put(en.getKey(), en.getValue());
+            }
+            return this;
+        }
+
+        /**
+         * Sets the {@code properties} and returns a reference to this Builder 
so that the methods can be chained together.
+         *
+         * @param val the {@code properties} to set
+         * @return a reference to this Builder
+         */
+        public Builder withProperty(String key, String val) {
+            this.properties.put(key, val);
+            return this;
+        }
+
+        /**
+         * Returns a {@code SimplePropertySource} built from the parameters 
previously set.
+         *
+         * @return a {@code SimplePropertySource} built with parameters of 
this {@code SimplePropertySource.Builder}
+         */
+        public SimpleConfigSource build() {
+            return new SimpleConfigSource(this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/SystemConfigSource.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/configsource/SystemConfigSource.java
 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/SystemConfigSource.java
new file mode 100644
index 0000000..0daf5ce
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/SystemConfigSource.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.base.configsource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This {@link javax.config.spi.ConfigSource} manages the system properties. 
You can disable this feature by
+ * setting {@code tamaya.envprops.disable} or {@code tamaya.defaults.disable}.
+ */
+public class SystemConfigSource extends BaseConfigSource {
+
+    /**
+     * default ordinal used.
+     */
+    public static final int DEFAULT_ORDINAL = 1000;
+
+    private volatile Map<String,String> cachedProperties;
+
+    /**
+     * previous System.getProperties().hashCode()
+     * so we can check if we need to reload
+     */
+    private volatile int previousHash;
+
+    /**
+     * Prefix that allows system properties to virtually be mapped on 
specified sub section.
+     */
+    private String prefix;
+
+    /**
+     * If true, this property source does not return any properties. This is 
useful since this
+     * property source is applied by default, but can be switched off by 
setting the
+     * {@code tamaya.envprops.disable} system/environment property to {@code 
true}.
+     */
+    private boolean disabled = false;
+
+    /**
+     * Creates a new instance. Also initializes the {@code prefix} and {@code 
disabled} properties
+     * from the system-/ environment properties:
+     * <pre>
+     *     tamaya.envprops.prefix
+     *     tamaya.envprops.disable
+     * </pre>
+     */
+    public SystemConfigSource(){
+        super("system-properties", DEFAULT_ORDINAL);
+        initFromSystemProperties();
+        if(!disabled){
+            cachedProperties = Collections.unmodifiableMap(loadProperties());
+        }
+    }
+
+    /**
+     * Initializes the {@code prefix} and {@code disabled} properties from the 
system-/
+     * environment properties:
+     * <pre>
+     *     tamaya.envprops.prefix
+     *     tamaya.envprops.disable
+     * </pre>
+     */
+    private void initFromSystemProperties() {
+        String value = System.getProperty("tamaya.sysprops.prefix");
+        if(value==null){
+            prefix = System.getenv("tamaya.sysprops.prefix");
+        }
+        value = System.getProperty("tamaya.sysprops.disable");
+        if(value==null){
+            value = System.getenv("tamaya.sysprops.disable");
+        }
+        if(value==null){
+            value = System.getProperty("tamaya.defaults.disable");
+        }
+        if(value==null){
+            value = System.getenv("tamaya.defaults.disable");
+        }
+        if(value!=null && !value.isEmpty()) {
+            this.disabled = Boolean.parseBoolean(value);
+        }
+    }
+
+    /**
+     * Creates a new instance using a fixed ordinal value.
+     * @param ordinal the ordinal number.
+     */
+    public SystemConfigSource(int ordinal){
+        this(null, ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     * @param ordinal the ordinal to be used.
+     */
+    public SystemConfigSource(String prefix, int ordinal){
+        this.prefix = prefix;
+        setOrdinal(ordinal);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param prefix the prefix to be used, or null.
+     */
+    public SystemConfigSource(String prefix){
+        this.prefix = prefix;
+    }
+
+
+    private Map<String, String> loadProperties() {
+        Properties sysProps = System.getProperties();
+        previousHash = System.getProperties().hashCode();
+        final String prefix = this.prefix;
+        Map<String, String> entries = new HashMap<>();
+        for (Map.Entry<Object,Object> entry : sysProps.entrySet()) {
+            if(entry.getKey() instanceof String && entry.getValue() instanceof 
String) {
+                if (prefix == null) {
+                    entries.put((String) entry.getKey(), (String) 
entry.getValue());
+                } else {
+                    entries.put(prefix + entry.getKey(), (String) 
entry.getValue());
+                }
+            }
+        }
+        return entries;
+    }
+
+    @Override
+    public String getName() {
+        if(disabled){
+            return super.getName() + "(disabled)";
+        }
+        return super.getName();
+    }
+
+    @Override
+    public String getValue(String key) {
+        if(disabled){
+            return null;
+        }
+        String prefix = this.prefix;
+        if(prefix==null) {
+            return System.getProperty(key);
+        }
+        return System.getProperty(key.substring(prefix.length()));
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        if(disabled){
+            return Collections.emptyMap();
+        }
+        // only need to reload and fill our map if something has changed
+        // synchronization was removed, Instance was marked as volatile. In 
the worst case it
+        // is reloaded twice, but the values will be the same.
+        if (previousHash != System.getProperties().hashCode()) {
+            Map<String, String> properties = loadProperties();
+            this.cachedProperties = Collections.unmodifiableMap(properties);
+        }
+        return this.cachedProperties;
+    }
+
+    @Override
+    protected String toStringValues() {
+        return  super.toStringValues() +
+                "  prefix=" + prefix + '\n' +
+                "  disabled=" + disabled + '\n';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/WrappedConfigSource.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/configsource/WrappedConfigSource.java
 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/WrappedConfigSource.java
new file mode 100644
index 0000000..40842d1
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/WrappedConfigSource.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.base.configsource;
+
+import javax.config.spi.ConfigSource;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Property source effectively managed by the configuration context, allowing 
resetting of ordinal and its
+ * delegate (e.g. in case of refresh).
+ */
+class WrappedConfigSource implements ConfigSource{
+
+    private Integer ordinal;
+    private ConfigSource delegate;
+    private long loaded = System.currentTimeMillis();
+
+    private WrappedConfigSource(ConfigSource delegate) {
+        this(delegate, null);
+    }
+
+    private WrappedConfigSource(ConfigSource delegate, Integer ordinal) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.ordinal = ordinal;
+    }
+
+    public static WrappedConfigSource of(ConfigSource ps) {
+        if(ps instanceof WrappedConfigSource){
+            return (WrappedConfigSource)ps;
+        }
+        return new WrappedConfigSource(ps);
+    }
+
+    public static WrappedConfigSource of(ConfigSource ps, Integer ordinal) {
+        if(ps instanceof WrappedConfigSource){
+            return new 
WrappedConfigSource(((WrappedConfigSource)ps).getDelegate(), ordinal);
+        }
+        return new WrappedConfigSource(ps, ordinal);
+    }
+
+    public int getOrdinal() {
+        if(this.ordinal!=null){
+            return this.ordinal;
+        }
+        return ConfigSourceComparator.getOrdinal(delegate);
+    }
+
+    public void setOrdinal(Integer ordinal) {
+        this.ordinal = ordinal;
+    }
+
+    public void setDelegate(ConfigSource delegate) {
+        this.delegate = Objects.requireNonNull(delegate);
+        this.loaded = System.currentTimeMillis();
+    }
+
+    @Override
+    public String getName() {
+        return delegate.getName();
+    }
+
+    @Override
+    public String getValue(String key) {
+        return delegate.getValue(key);
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        return delegate.getProperties();
+    }
+
+    public ConfigSource getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof WrappedConfigSource)) return false;
+
+        WrappedConfigSource that = (WrappedConfigSource) o;
+
+        return getDelegate().getName().equals(that.getDelegate().getName());
+    }
+
+    @Override
+    public int hashCode() {
+        return getDelegate().getName().hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "WrappedPropertySource{" +
+                "name=" + getName() +
+                ", ordinal=" + getOrdinal() +
+                ", loadedAt=" + loaded +
+                ", delegate-class=" + delegate.getClass().getName() +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/configsource/package-info.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/configsource/package-info.java 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/package-info.java
new file mode 100644
index 0000000..26e6d85
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/configsource/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Contains default implementations for config sources.
+ */
+package org.apache.tamaya.base.configsource;
\ No newline at end of file

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

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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/convert/EnumConverter.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/convert/EnumConverter.java 
b/code/base/src/main/java/org/apache/tamaya/base/convert/EnumConverter.java
new file mode 100644
index 0000000..c0f727b
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/convert/EnumConverter.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.base.convert;
+
+//import org.osgi.service.component.annotations.Component;
+
+import javax.config.spi.Converter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to tge given enum type.
+ */
+//@Component(service = Converter.class)
+public class EnumConverter<T> implements Converter<T> {
+    private final Logger LOG = Logger.getLogger(EnumConverter.class.getName());
+    private Class<T> enumType;
+    private Method factory;
+
+    public EnumConverter(Class<T> enumType) {
+        if (!Enum.class.isAssignableFrom(enumType)) {
+            throw new IllegalArgumentException("Not an Enum: " + 
enumType.getName());
+        }
+        this.enumType = Objects.requireNonNull(enumType);
+        try {
+            this.factory = enumType.getMethod("valueOf", String.class);
+        } catch (NoSuchMethodException e) {
+            throw new IllegalArgumentException("Uncovertible enum type without 
valueOf method found, please provide a custom " +
+                    "PropertyConverter for: " + enumType.getName());
+        }
+    }
+
+    @Override
+    public T convert(String value) {
+        
ConversionContext.getContext().addSupportedFormats(getClass(),"<enumValue>");
+        try {
+            return (T) factory.invoke(null, value);
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + 
enumType.getName(), e);
+        }
+        try {
+            return (T) factory.invoke(null, value.toUpperCase(Locale.ENGLISH));
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + 
enumType.getName(), e);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof EnumConverter)) return false;
+        EnumConverter<?> that = (EnumConverter<?>) o;
+        return Objects.equals(enumType, that.enumType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(enumType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/convert/package-info.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/convert/package-info.java 
b/code/base/src/main/java/org/apache/tamaya/base/convert/package-info.java
new file mode 100644
index 0000000..c63629a
--- /dev/null
+++ b/code/base/src/main/java/org/apache/tamaya/base/convert/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Default implementations for converters and converter management.
+ */
+package org.apache.tamaya.base.convert;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/063f8ada/code/base/src/main/java/org/apache/tamaya/base/filter/FilterComparator.java
----------------------------------------------------------------------
diff --git 
a/code/base/src/main/java/org/apache/tamaya/base/filter/FilterComparator.java 
b/code/base/src/main/java/org/apache/tamaya/base/filter/FilterComparator.java
new file mode 100644
index 0000000..dd2bd49
--- /dev/null
+++ 
b/code/base/src/main/java/org/apache/tamaya/base/filter/FilterComparator.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.base.filter;
+
+import org.apache.tamaya.spi.Filter;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Comparator for PropertyFilters based on their priority annotations.
+ */
+public final class FilterComparator implements Comparator<Filter>, 
Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final FilterComparator INSTANCE = new FilterComparator();
+
+    /**
+     * Get the shared instance of the comparator.
+     * @return the shared instance, never null.
+     */
+    public static FilterComparator getInstance(){
+        return INSTANCE;
+    }
+
+    private FilterComparator(){}
+
+    /**
+     * Compare 2 filters for ordering the filter chain.
+     *
+     * @param filter1 the first filter
+     * @param filter2 the second filter
+     * @return the comparison result
+     */
+    private int comparePropertyFilters(Filter filter1, Filter filter2) {
+        Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
+        Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
+        int ord1 = prio1 != null ? prio1.value() : 0;
+        int ord2 = prio2 != null ? prio2.value() : 0;
+
+        if (ord1 < ord2) {
+            return -1;
+        } else if (ord1 > ord2) {
+            return 1;
+        } else {
+            return 
filter1.getClass().getName().compareTo(filter2.getClass().getName());
+        }
+    }
+
+    @Override
+    public int compare(Filter filter1, Filter filter2) {
+        return comparePropertyFilters(filter1, filter2);
+    }
+}

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


Reply via email to