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;
+        }
+    }
+}

Reply via email to