You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2016/10/30 17:22:11 UTC

[02/10] incubator-tamaya git commit: TAMAYA-182: Streamlined/unified builder API and impl.

TAMAYA-182: Streamlined/unified builder API and impl.


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

Branch: refs/heads/master
Commit: 32a1616cd358059d7e715ce4e0b7cfd4b586d1b1
Parents: 8a8a535
Author: anatole <an...@apache.org>
Authored: Sun Oct 23 15:38:00 2016 +0200
Committer: anatole <an...@apache.org>
Committed: Sun Oct 23 15:38:00 2016 +0200

----------------------------------------------------------------------
 .../apache/tamaya/ConfigurationProvider.java    |  10 +
 .../apache/tamaya/spi/ConfigurationContext.java |  45 ++-
 .../tamaya/spi/ConfigurationContextBuilder.java | 233 ++++++++++---
 .../tamaya/spi/ConfigurationProviderSpi.java    |  47 ++-
 .../tamaya/TestConfigurationProvider.java       |  14 +
 .../internal/DefaultConfigurationContext.java   | 127 +++----
 .../DefaultConfigurationContextBuilder.java     | 349 ++++++++++++++++---
 .../internal/DefaultConfigurationProvider.java  |  35 +-
 .../core/internal/PropertyConverterManager.java |  15 +-
 .../propertysource/SystemPropertySource.java    |   1 -
 .../apache/tamaya/core/ConfigurationTest.java   |   6 +
 jqassistant/serviceloader-rules.xml             |   2 +-
 12 files changed, 678 insertions(+), 206 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java b/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java
index bc4cd13..875f8fc 100644
--- a/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java
+++ b/code/api/src/main/java/org/apache/tamaya/ConfigurationProvider.java
@@ -88,6 +88,16 @@ public final class ConfigurationProvider {
     }
 
     /**
+     * Creates a new configuration instance based on the given context.
+     *
+     * @param context the configuration context, not null.
+     * @return a new Configuration instance, never null.
+     */
+    public static Configuration createConfiguration(ConfigurationContext context) {
+        return PROVIDER_SPI.createConfiguration(context);
+    }
+
+    /**
      * Get access to the current ConfigurationContext.
      *
      * @return the current ConfigurationContext, never null.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java
index 3a757a0..f631d55 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContext.java
@@ -35,9 +35,30 @@ public interface ConfigurationContext {
      * This method can be used for programmatically adding {@link PropertySource}s.
      * It is not needed for normal 'usage' by end users, but only for Extension Developers!
      *
-     * @param propertySourcesToAdd the PropertySources to add
+     * @param propertySources the PropertySources to add
+     * @deprecated Use {@link ConfigurationContextBuilder} to create a new {@link ConfigurationContext}.
+     * @see #toBuilder()
      */
-    void addPropertySources(PropertySource... propertySourcesToAdd);
+    @Deprecated
+    void addPropertySources(PropertySource... propertySources);
+
+    /**
+     * This method can be used for programmatically adding {@link PropertyFilter}s.
+     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     *
+     * @param propertyFilters the PropertyFilters to add
+     * @deprecated Use {@link ConfigurationContextBuilder} to create a new {@link ConfigurationContext}.
+     * @see #toBuilder()
+     */
+    @Deprecated
+    void addPropertyFilter(PropertyFilter... propertyFilters);
+
+    /**
+     * Allows to check if a given property source is registered, using its name.
+     * @param name the property source name.
+     * @return true, if a property source with the given name is present.
+     */
+    boolean containsPropertySource(String name);
 
     /**
      * This method returns the current list of registered PropertySources ordered via their ordinal.
@@ -53,23 +74,25 @@ public interface ConfigurationContext {
      */
     List<PropertySource> getPropertySources();
 
-
-//    /**
-//     * Access a {@link PropertySource} using its (unique) name.
-//     * @param name the propoerty source's name, not null.
-//     * @return the propoerty source found, or null.
-//     */
-//    PropertySource getPropertySource(String name);
+    /**
+     * Access a {@link PropertySource} using its (unique) name.
+     * @param name the propoerty source's name, not null.
+     * @return the propoerty source found, or null.
+     */
+    PropertySource getPropertySource(String name);
 
     /**
      * This method can be used for programmatically adding {@link PropertyConverter}s.
      * It is not needed for normal 'usage' by end users, but only for Extension Developers!
      *
      * @param <T> the type of the type literal
-     * @param typeToConvert the type which the converter is for
+     * @param type the type which the converter is for
      * @param propertyConverter the PropertyConverters to add for this type
+     * @deprecated Use {@link ConfigurationContextBuilder} to create a new {@link ConfigurationContext}.
+     * @see #toBuilder()
      */
-    <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter);
+    @Deprecated
+    <T> void addPropertyConverter(TypeLiteral<T> type, PropertyConverter<T> propertyConverter);
 
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
index 6416959..66a2426 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
@@ -20,7 +20,7 @@ package org.apache.tamaya.spi;
 
 import org.apache.tamaya.TypeLiteral;
 
-import java.util.Collection;
+import java.util.*;
 
 /**
  * A builder for creating new or adapting instances of {@link ConfigurationContext}.
@@ -36,20 +36,13 @@ import java.util.Collection;
  * {@link org.apache.tamaya.ConfigurationProvider#setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)}.
  * 
  */
-
-/* @todo This is some Javadoc which is outdated. I am not sure if I can deleted it. The author
- *       should take care. Oliver B. Fischer, 2015-12-23
- * Since this method can
- * throw an UnsupportedOperationException, you should check before if changing the current ConfigurationContext
- * programmatically is supported by calling
- * {@link org.apache.tamaya.ConfigurationProvider#is}.
- */
 public interface ConfigurationContextBuilder {
 
     /**
      * Init this builder instance with the given {@link ConfigurationContext} instance. This
-     * method will replace any existing data in the current builder with the data contained in the given
-     * {@link ConfigurationContext}.
+     * method will use any existing property sources, filters, converters and the combination
+     * policy of the given {@link ConfigurationContext} and initialize the current builder
+     * with them.
      *
      * @param context the {@link ConfigurationContext} instance to be used, not null.
      * @return this builder, for chaining, never null.
@@ -57,43 +50,127 @@ public interface ConfigurationContextBuilder {
     ConfigurationContextBuilder setContext(ConfigurationContext context);
 
     /**
-     * This method can be used for programmatically adding {@link PropertySource}s.
-     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     * This method can be used for adding {@link PropertySource}s.
+     * Hereby the property source is added to the tail of property sources with
+     * lowest priority  regardless of its current ordinal value. To sort the property
+     * sources based on their ordinals call {@kink #sortPropertySources}.
      *
-     * @param propertySourcesToAdd the PropertySources to add
+     * @param propertySources the PropertySources to add
      * @return this builder, for chaining, never null.
+     * @throws IllegalArgumentException If a property source with a given name already
+     * exists.
      */
-    ConfigurationContextBuilder addPropertySources(PropertySource... propertySourcesToAdd);
+    ConfigurationContextBuilder addPropertySources(PropertySource... propertySources);
 
     /**
      * This method can be used for programmatically adding {@link PropertySource}s.
-     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     * Hereby the property source is added to the tail of property sources with
+     * lowest priority regardless of its current ordinal value. To sort the property
+     * sources based on their ordinals call {@kink #sortPropertySources}.
      *
-     * @param propertySourcesToAdd the PropertySources to add
+     * @param propertySources the PropertySources to add
      * @return this builder, for chaining, never null.
+     * @throws IllegalArgumentException If a property source with a given name already
+     * exists.
      */
-    ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySourcesToAdd);
+    ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySources);
 
     /**
-     * This method can be used for programmatically adding {@link PropertySource}s.
-     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     * Removes the given property sources, if existing. The existing order of property
+     * sources is preserved.
      *
-     * @param propertySourcesNames the PropertySource names of the sources to remove
-     * @return this builder, for chaining, never null.
+     * @param propertySources the property sources to remove, not null.
+     * @return the builder for chaining.
      */
-    ConfigurationContextBuilder removePropertySources(String... propertySourcesNames);
+    ConfigurationContextBuilder removePropertySources(PropertySource... propertySources);
 
     /**
-     * This method can be used for programmatically adding {@link PropertySource}s.
-     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     * Removes the given property sources, if existing. The existing order of property
+     * sources is preserved.
      *
-     * @param propertySourcesNames the PropertySource names of the sources to remove
-     * @return this builder, for chaining, never null.
+     * @param propertySources the property sources to remove, not null.
+     * @return the builder for chaining.
+     */
+    ConfigurationContextBuilder removePropertySources(Collection<PropertySource> propertySources);
+
+    /**
+     * Access the current chain of property sources. Items at the end of the list have
+     * precedence/more significance.
+     *
+     * @return the property source chain, never null.
+     */
+    List<PropertySource> getPropertySources();
+
+    /**
+     * Access the current chain of property filters. Items at the end of the list have
+     * precedence/more significance.
+     *
+     * @return the property source chain, never null.
      */
-    ConfigurationContextBuilder removePropertySources(Collection<String> propertySourcesNames);
+    List<PropertyFilter> getPropertyFilters();
 
     /**
-     * Adds the given PropertyFilter instances.
+     * Access the current registered property converters.
+     *
+     * @return the current registered property converters.
+     */
+    Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> getPropertyConverter();
+
+    /**
+     * Increases the priority of the given property source, by moving it towards the end
+     * of the chain of property sources. If the property source given is already at the end
+     * this method has no effect. This operation does not change any ordinal values.
+     *
+     * @param propertySource the property source to be incresed regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    ConfigurationContextBuilder increasePriority(PropertySource propertySource);
+
+    /**
+     * Decreases the priority of the given property source, by moving it towards the start
+     * of the chain of property sources. If the property source given is already the first
+     * this method has no effect. This operation does not change any ordinal values.
+     *
+     * @param propertySource the property source to be decresed regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    ConfigurationContextBuilder decreasePriority(PropertySource propertySource);
+
+    /**
+     * Increases the priority of the given property source to be maximal, by moving it to
+     * the tail of the of property source chain. If the property source given is
+     * already the last item this method has no effect. This operation does not change
+     * any ordinal values.
+     *
+     * @param propertySource the property source to be maximized regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    ConfigurationContextBuilder highestPriority(PropertySource propertySource);
+
+    /**
+     * Decreases the priority of the given property source to be minimal, by moving it to
+     * the start of the chain of property source chain. If the property source given is
+     * already the first item this method has no effect. This operation does not change
+     * any ordinal values.
+     *
+     * @param propertySource the property source to be minimized regarding its significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in the current
+     * chain.
+     */
+    ConfigurationContextBuilder lowestPriority(PropertySource propertySource);
+
+    /**
+     * Adds the given PropertyFilter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the property
+     * filters call {@kink #sortPropertyFilter}.
      *
      * @param filters the filters to add
      * @return this builder, for chaining, never null.
@@ -101,7 +178,10 @@ public interface ConfigurationContextBuilder {
     ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters);
 
     /**
-     * Adds the given PropertyFilter instances.
+     * Adds the given PropertyFilter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the property
+     * filters call {@kink #sortPropertyFilter}.
      *
      * @param filters the filters to add
      * @return this builder, for chaining, never null.
@@ -109,52 +189,99 @@ public interface ConfigurationContextBuilder {
     ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters);
 
     /**
-     * Removes the given PropertyFilter instances.
+     * Removes the given PropertyFilter instances, if existing. The order of the remaining
+     * filters is preserved.
      *
-     * @param filters the filters to remove
+     * @param filters the filter to remove
      * @return this builder, for chaining, never null.
      */
     ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters);
 
     /**
-     * Removes the given PropertyFilter instances.
+     * Removes the given PropertyFilter instances, if existing. The order of the remaining
+     * filters is preserved.
      *
-     * @param filters the filters to remove
+     * @param filters the filter to remove
      * @return this builder, for chaining, never null.
      */
     ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters);
 
     /**
-     * This method can be used for programmatically adding {@link PropertyConverter}s.
-     * It is not needed for normal 'usage' by end users, but only for Extension Developers!
+     * 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 <T> the type of the type literal
      * @param typeToConvert     the type for which the converter is for
-     * @param propertyConverter the PropertyConverters to add for this type
+     * @param propertyConverters the PropertyConverters to add for this type
      * @return this builder, for chaining, never null.
      */
-    <T> ConfigurationContextBuilder addPropertyConverter(TypeLiteral<T> typeToConvert,
-                                                         PropertyConverter<T> propertyConverter);
+    <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert,
+                                                          PropertyConverter<T>... propertyConverters);
 
     /**
-     * Removes the given PropertyConverter instances.
+     * This method can be used for adding {@link PropertyConverter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converter is for
+     * @param propertyConverters the PropertyConverters to add for this type
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert,
+                                                          Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
      *
      * @param typeToConvert the type which the converter is for
-     * @param converters    the converters to remove
+     * @param propertyConverters    the converter to remove
      * @return this builder, for chaining, never null.
      */
-    ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert,
-                                                         PropertyConverter<?>... converters);
+    <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                         PropertyConverter<T>... propertyConverters);
 
     /**
-     * Removes the given PropertyConverter instances.
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
      *
      * @param typeToConvert the type which the converter is for
-     * @param converters    the converters to remove
+     * @param propertyConverters    the converter to remove
      * @return this builder, for chaining, never null.
      */
-    ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert,
-                                                         Collection<PropertyConverter<?>> converters);
+    <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                             Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Removes all converters for the given type, which actually renders a given type
+     * unsupported for type conversion.
+     *
+     * @param typeToConvert the type which the converter is for
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert);
+
+    /**
+     * Sorts the current registered property sources using the given comparator.
+     *
+     * NOTE: property sources at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not null.
+     * @return this instance for chaining.
+     */
+    ConfigurationContextBuilder sortPropertySources(Comparator<PropertySource> comparator);
+
+    /**
+     * Sorts the current registered property filters using the given comparator.
+     *
+     * NOTE: property filters at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not null.
+     * @return this instance for chaining.
+     */
+    ConfigurationContextBuilder sortPropertyFilter(Comparator<PropertyFilter> comparator);
 
     /**
      * Sets the {@link PropertyValueCombinationPolicy} used to evaluate the final
@@ -166,9 +293,15 @@ public interface ConfigurationContextBuilder {
     ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy);
 
     /**
-     * Builds a {@link ConfigurationContext} based on the data set.
-     * @return final context with the current builder's properties.
+     * Builds a new {@link ConfigurationContext} based on the data in this builder. The ordering of property
+     * sources and property filters is not changed, regardless of their ordinals. For ensure a certain
+     * ordering/significance call {@link #sortPropertyFilter(Comparator)} and/or {@link #sortPropertySources(Comparator)}
+     * before building the context.
+     *
+     * @return the final context to be used to create a configuration.
+     * @see org.apache.tamaya.ConfigurationProvider#createConfiguration(ConfigurationContext)
      */
     ConfigurationContext build();
 
 }
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
index d179d1e..1f473e3 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
@@ -36,6 +36,43 @@ public interface ConfigurationProviderSpi {
     Configuration getConfiguration();
 
     /**
+     * Create a {@link Configuration} instance using the given context. The configuration
+     * created hereby must respect the artifacts provided by its context (property sources,
+     * filters, converters, policies etc), including their ordering and significance.
+     * @param context the context to be used, not null.
+     * @return the corresponding configuration instance.
+     */
+    Configuration createConfiguration(ConfigurationContext context);
+
+    /**
+     * Creates a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder} instance.
+     *
+     * @return a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder}, never null.
+     */
+    ConfigurationContextBuilder getConfigurationContextBuilder();
+
+    /**
+     * This method allows to replace the current {@link org.apache.tamaya.Configuration} with a new
+     * instance. This can be used to update the configuration with a new one, e.g. because some of the
+     * data has changed and must be updated. It is the responsibility of the ConfigurationProvider to trigger
+     * corresponding update events for the current {@link org.apache.tamaya.Configuration}.
+     *
+     * @param config the new Configuration to be applied.
+     * @throws java.lang.UnsupportedOperationException if the current provider is read-only.
+     */
+    void setConfiguration(Configuration config);
+
+    /**
+     * Method that allows to determine if a new {@link org.apache.tamaya.Configuration} can be applied
+     * programmatically.
+     *
+     * @return true, if {@link #setConfiguration(org.apache.tamaya.Configuration)} is supported
+     * by the current implementation.
+     * @see #setConfiguration(org.apache.tamaya.Configuration)
+     */
+    boolean isConfigurationSettable();
+
+    /**
      * Get access to the current {@link ConfigurationContext}.
      *
      * @return the current {@link ConfigurationContext}, never null.
@@ -53,7 +90,9 @@ public interface ConfigurationProviderSpi {
      *
      * @param context the new ConfigurationContext to be applied.
      * @throws java.lang.UnsupportedOperationException if the current provider is read-only.
+     * @deprecated use {@link #setConfiguration(Configuration)}
      */
+    @Deprecated
     void setConfigurationContext(ConfigurationContext context);
 
     /**
@@ -63,14 +102,10 @@ public interface ConfigurationProviderSpi {
      * @return true, if {@link #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} is supported
      * by the current implementation.
      * @see #setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)
+     * @deprecated use {@link #isConfigurationSettable()}
      */
+    @Deprecated
     boolean isConfigurationContextSettable();
 
-    /**
-     * Creates a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder} instance.
-     *
-     * @return a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder}, never null.
-     */
-    ConfigurationContextBuilder getConfigurationContextBuilder();
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java b/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
index 1c84b83..3c913a1 100644
--- a/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
+++ b/code/api/src/test/java/org/apache/tamaya/TestConfigurationProvider.java
@@ -38,6 +38,11 @@ public class TestConfigurationProvider implements ConfigurationProviderSpi {
     }
 
     @Override
+    public Configuration createConfiguration(ConfigurationContext context) {
+        return null;
+    }
+
+    @Override
     public ConfigurationContext getConfigurationContext() {
         return null;
     }
@@ -56,4 +61,13 @@ public class TestConfigurationProvider implements ConfigurationProviderSpi {
     public ConfigurationContextBuilder getConfigurationContextBuilder() {
         return null;
     }
+
+    @Override
+    public void setConfiguration(Configuration config) {
+    }
+
+    @Override
+    public boolean isConfigurationSettable() {
+        return false;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
index a1a2f64..15c6147 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContext.java
@@ -25,19 +25,12 @@ import org.apache.tamaya.spi.ConfigurationContextBuilder;
 import org.apache.tamaya.spi.PropertyConverter;
 import org.apache.tamaya.spi.PropertyFilter;
 import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertySourceProvider;
 import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
 import org.apache.tamaya.spi.ServiceContextManager;
 
 import javax.annotation.Priority;
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.logging.Logger;
@@ -73,71 +66,36 @@ public class DefaultConfigurationContext implements ConfigurationContext {
      * Lock for internal synchronization.
      */
     private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
-
-    /** Comparator used for ordering property sources. */
-    private final PropertySourceComparator propertySourceComparator = new PropertySourceComparator();
-
-    /** Comparator used for ordering property filters. */
-    private final PropertyFilterComparator propertyFilterComparator = new PropertyFilterComparator();
-
-
     /**
-     * The first time the Configuration system gets invoked we do initialize
-     * all our {@link org.apache.tamaya.spi.PropertySource}s and
-     * {@link org.apache.tamaya.spi.PropertyFilter}s which are known at startup.
+     * Lock for internal synchronization.
      */
-    public DefaultConfigurationContext() {
-        List<PropertySource> propertySources = new ArrayList<>();
-
-        // first we load all PropertySources which got registered via java.util.ServiceLoader
-        propertySources.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class));
-
-        // after that we add all PropertySources which get dynamically registered via their PropertySourceProviders
-        propertySources.addAll(evaluatePropertySourcesFromProviders());
-
-        // now sort them according to their ordinal values
-        Collections.sort(propertySources, new PropertySourceComparator());
+    private final ReentrantReadWriteLock propertyFilterLock = new ReentrantReadWriteLock();
 
-        immutablePropertySources = Collections.unmodifiableList(propertySources);
-        LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
-                immutablePropertySources);
-
-        // as next step we pick up the PropertyFilters pretty much the same way
-        List<PropertyFilter> propertyFilters = new ArrayList<>();
-        propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
-        Collections.sort(propertyFilters, new PropertyFilterComparator());
-        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
-        LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
-                immutablePropertyFilters);
-
-        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
-        LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
-                immutablePropertyFilters);
-        propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
-        if(propertyValueCombinationPolicy==null) {
-            propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
-        }
-        LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
-    }
 
     DefaultConfigurationContext(DefaultConfigurationContextBuilder builder) {
         List<PropertySource> propertySources = new ArrayList<>();
         // first we load all PropertySources which got registered via java.util.ServiceLoader
-        propertySources.addAll(builder.propertySources.values());
+        propertySources.addAll(builder.propertySources);
         // now sort them according to their ordinal values
-        Collections.sort(propertySources, propertySourceComparator);
         immutablePropertySources = Collections.unmodifiableList(propertySources);
         LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
                 immutablePropertySources);
 
         // as next step we pick up the PropertyFilters pretty much the same way
-        List<PropertyFilter> propertyFilters = new ArrayList<>();
-        propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
-        Collections.sort(propertyFilters, propertyFilterComparator);
+        List<PropertyFilter> propertyFilters = new ArrayList<>(builder.getPropertyFilters());
         immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
         LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
                 immutablePropertyFilters);
 
+        // Finally add the converters
+        for(Map.Entry<TypeLiteral<?>, Collection<PropertyConverter<?>>> en:builder.getPropertyConverter().entrySet()) {
+            for (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);
@@ -148,23 +106,8 @@ public class DefaultConfigurationContext implements ConfigurationContext {
         LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
     }
 
-    /**
-     * Pick up all {@link org.apache.tamaya.spi.PropertySourceProvider}s and return all the
-     * {@link org.apache.tamaya.spi.PropertySource}s they like to register.
-     */
-    private Collection<? extends PropertySource> evaluatePropertySourcesFromProviders() {
-        List<PropertySource> propertySources = new ArrayList<>();
-        Collection<PropertySourceProvider> propertySourceProviders = ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class);
-        for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
-            Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
-            LOG.finer("PropertySourceProvider " + propertySourceProvider.getClass().getName() +
-                    " provided the following property sources: " + sources);
-                propertySources.addAll(sources);
-        }
-
-        return propertySources;
-    }
 
+    @Deprecated
     @Override
     public void addPropertySources(PropertySource... propertySourcesToAdd) {
         Lock writeLock = propertySourceLock.writeLock();
@@ -180,6 +123,28 @@ public class DefaultConfigurationContext implements ConfigurationContext {
         }
     }
 
+
+    @Deprecated
+    @Override
+    public void addPropertyFilter(PropertyFilter... propertyFiltersToAdd) {
+        Lock writeLock = propertyFilterLock.writeLock();
+        try {
+            writeLock.lock();
+            List<PropertyFilter> newPropertyFilters = new ArrayList<>(this.immutablePropertyFilters);
+            newPropertyFilters.addAll(Arrays.asList(propertyFiltersToAdd));
+            Collections.sort(newPropertyFilters, new PropertyFilterComparator());
+
+            this.immutablePropertyFilters = Collections.unmodifiableList(newPropertyFilters);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean containsPropertySource(String name) {
+        return getPropertySource(name)!=null;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -331,15 +296,15 @@ public class DefaultConfigurationContext implements ConfigurationContext {
         return immutablePropertySources;
     }
 
-//    @Override
-//    public PropertySource getPropertySource(String name) {
-//        for(PropertySource ps:getPropertySources()){
-//            if(name.equals(ps.getName())){
-//                return ps;
-//            }
-//        }
-//        return null;
-//    }
+    @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) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
index 944a1e0..f3d823e 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilder.java
@@ -18,95 +18,243 @@
  */
 package org.apache.tamaya.core.internal;
 
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.Configuration;
 import org.apache.tamaya.TypeLiteral;
 import org.apache.tamaya.spi.ConfigurationContext;
 import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
 import org.apache.tamaya.spi.PropertyFilter;
 import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
 import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContextManager;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.logging.Logger;
 
 /**
  * Default implementation of {@link org.apache.tamaya.spi.ConfigurationContextBuilder}.
  */
 public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder {
 
-    final Map<String, PropertySource> propertySources = new HashMap<>();
-    final List<PropertyFilter> propertyFilters = new ArrayList<>();
-    final Map<TypeLiteral<?>, List<PropertyConverter<?>>> propertyConverters = new HashMap<>();
-    PropertyValueCombinationPolicy combinationPolicy;
+    private static final Logger LOG = Logger.getLogger(DefaultConfigurationContextBuilder.class.getName());
+
+    public static final Comparator<PropertySource> DEFAULT_PROPERTYSOURCE_COMPARATOR = new PropertySourceComparator();
+    public static final Comparator<?> DEFAULT_PROPERTYFILTER_COMPARATOR = new PriorityServiceComparator();
+
+    List<PropertyFilter> propertyFilters = new ArrayList<>();
+    List<PropertySource> propertySources = new ArrayList<>();
+    PropertyValueCombinationPolicy combinationPolicy =
+            PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+    Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> propertyConverters = new HashMap<>();
 
-    public DefaultConfigurationContextBuilder(){
+    /**
+     * Flag if the config has already been built.
+     * Configuration can be built only once
+     */
+    private boolean built;
+
+
+
+    /**
+     * Creates a new builder instance.
+     */
+    public DefaultConfigurationContextBuilder() {
     }
 
-    @Override
-    public ConfigurationContextBuilder setContext(ConfigurationContext context) {
-        this.propertySources.clear();
+    /**
+     * Creates a new builder instance.
+     */
+    public DefaultConfigurationContextBuilder(ConfigurationContext context) {
+        this.propertyConverters.putAll(context.getPropertyConverters());
+        this.propertyFilters.addAll(context.getPropertyFilters());
         for(PropertySource ps:context.getPropertySources()) {
-            this.propertySources.put(ps.getName(), ps);
+            addPropertySources(ps);
         }
+        this.combinationPolicy = context.getPropertyValueCombinationPolicy();
+    }
+
+    /**
+     * Allows to set configuration context during unit tests.
+     */
+    ConfigurationContextBuilder setConfigurationContext(ConfigurationContext configurationContext) {
+        checkBuilderState();
+        //noinspection deprecation
         this.propertyFilters.clear();
-        this.propertyFilters.addAll(context.getPropertyFilters());
+        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 ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySourcesToAdd) {
-        for(PropertySource ps:propertySourcesToAdd){
-            if(this.propertySources.containsKey(ps.getName())){
-                throw new ConfigException("Duplicate PropertySource: " + ps.getName());
+    public 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;
+    }
+
+    protected DefaultConfigurationContextBuilder loadDefaultPropertyFilters() {
+        checkBuilderState();
+        for(PropertyFilter pf:ServiceContextManager.getServiceContext().getServices(PropertyFilter.class)){
+            addPropertyFilters(pf);
+        }
+        return this;
+    }
+
+    protected DefaultConfigurationContextBuilder loadDefaultPropertySources() {
+        checkBuilderState();
+        for(PropertySource ps:ServiceContextManager.getServiceContext().getServices(PropertySource.class)){
+            addPropertySources(ps);
+        }
+        for(PropertySourceProvider pv:ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class)){
+            for(PropertySource ps:pv.getPropertySources()){
+                addPropertySources(ps);
             }
         }
-        for(PropertySource ps:propertySourcesToAdd) {
-            this.propertySources.put(ps.getName(), ps);
+        return this;
+    }
+
+    protected DefaultConfigurationContextBuilder loadDefaultPropertyConverters() {
+        checkBuilderState();
+        for(Map.Entry<TypeLiteral, Collection<PropertyConverter>> en:getDefaultPropertyConverters().entrySet()){
+            for(PropertyConverter pc: en.getValue()) {
+                addPropertyConverters(en.getKey(), pc);
+            }
         }
         return this;
     }
 
     @Override
-    public ConfigurationContextBuilder addPropertySources(PropertySource... propertySourcesToAdd) {
-        return addPropertySources(Arrays.asList(propertySourcesToAdd));
+    public ConfigurationContextBuilder removePropertySources(PropertySource... propertySources) {
+        return removePropertySources(Arrays.asList(propertySources));
     }
 
     @Override
-    public ConfigurationContextBuilder removePropertySources(Collection<String> propertySourcesToRemove) {
-        for(String key: propertySourcesToRemove){
-            this.propertySources.remove(key);
+    public ConfigurationContextBuilder removePropertySources(Collection<PropertySource> propertySources) {
+        checkBuilderState();
+        this.propertySources.removeAll(propertySources);
+        return this;
+    }
+
+    public 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 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 removePropertySources(String... propertySourcesToRemove) {
-        return removePropertySources(Arrays.asList(propertySourcesToRemove));
+    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 addPropertyFilters(Collection<PropertyFilter> filters) {
-        this.propertyFilters.addAll(filters);
+    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 ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters) {
+    public ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters){
         return addPropertyFilters(Arrays.asList(filters));
     }
 
     @Override
-    public ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
-        this.propertyFilters.removeAll(filters);
+    public ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters){
+        checkBuilderState();
+        for(PropertyFilter f:filters) {
+            if (!this.propertyFilters.contains(f)) {
+                this.propertyFilters.add(f);
+            }
+        }
         return this;
     }
 
@@ -116,38 +264,153 @@ public class DefaultConfigurationContextBuilder implements ConfigurationContextB
     }
 
     @Override
-    public <T> ConfigurationContextBuilder addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
-        List<PropertyConverter<?>> converters = this.propertyConverters.get(typeToConvert);
-        if(converters==null){
-            converters =  new ArrayList<>();
-            this.propertyConverters.put(typeToConvert, converters);
-        }
+    public ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+        checkBuilderState();
+        this.propertyFilters.removeAll(filters);
         return this;
     }
 
+
     @Override
-    public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert, PropertyConverter<?>... converters) {
+    public <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> typeToConvert,
+                                                                    PropertyConverter<T>... converters) {
         return removePropertyConverters(typeToConvert, Arrays.asList(converters));
     }
 
     @Override
-    public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert, Collection<PropertyConverter<?>> converters) {
-        List<PropertyConverter<?>> existing = this.propertyConverters.get(typeToConvert);
-        if(existing!=null) {
-            existing.removeAll(converters);
+    public <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 ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert) {
+        this.propertyConverters.remove(typeToConvert);
+        return this;
+    }
+
+
+    @Override
+    public 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 ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy) {
-        this.combinationPolicy = Objects.requireNonNull(policy);
+    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;
+    }
+
+    private WrappedPropertySource getWrappedPropertySource(PropertySource delegate) {
+        PropertySource ps = getPropertySource(delegate.getName());
+        return WrappedPropertySource.of(ps);
+    }
+
+    protected ConfigurationContextBuilder loadDefaults() {
+        checkBuilderState();
+        this.combinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+        loadDefaultPropertySources();
+        loadDefaultPropertyFilters();
+        loadDefaultPropertyConverters();
         return this;
     }
 
+
+    protected Map<TypeLiteral, Collection<PropertyConverter>> getDefaultPropertyConverters() {
+        Map<TypeLiteral, Collection<PropertyConverter>> result = new HashMap<>();
+        for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(
+                PropertyConverter.class)) {
+            TypeLiteral target = TypeLiteral.of(TypeLiteral.of(conv.getClass()).getType());
+            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 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/32a1616c/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java
index 4330b7e..e03d9ce 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfigurationProvider.java
@@ -24,6 +24,8 @@ import org.apache.tamaya.spi.ConfigurationContextBuilder;
 import org.apache.tamaya.spi.ConfigurationProviderSpi;
 import org.apache.tamaya.spi.ServiceContextManager;
 
+import java.util.Objects;
+
 /**
  * Implementation of the Configuration API. This class uses the current {@link org.apache.tamaya.spi.ConfigurationContext} to evaluate the
  * chain of {@link org.apache.tamaya.spi.PropertySource} and {@link org.apache.tamaya.spi.PropertyFilter}
@@ -31,7 +33,11 @@ import org.apache.tamaya.spi.ServiceContextManager;
  */
 public class DefaultConfigurationProvider implements ConfigurationProviderSpi {
 
-    private ConfigurationContext context = new DefaultConfigurationContext();
+    ConfigurationContext context = new DefaultConfigurationContextBuilder()
+            .loadDefaultPropertyConverters()
+            .loadDefaultPropertyFilters()
+            .loadDefaultPropertySources().build();
+
     private Configuration config = new DefaultConfiguration(context);
 
     @Override
@@ -40,23 +46,42 @@ public class DefaultConfigurationProvider implements ConfigurationProviderSpi {
     }
 
     @Override
-    public ConfigurationContext getConfigurationContext() {
-        return context;
+    public Configuration createConfiguration(ConfigurationContext context) {
+        return new DefaultConfiguration(context);
     }
 
     @Override
     public ConfigurationContextBuilder getConfigurationContextBuilder() {
-        return ServiceContextManager.getServiceContext().getService(ConfigurationContextBuilder.class);
+        return new DefaultConfigurationContextBuilder();
+    }
+
+    @Override
+    public void setConfiguration(Configuration config) {
+        Objects.requireNonNull(config.getContext());
+        this.config = Objects.requireNonNull(config);
+        this.context = config.getContext();
+    }
+
+    @Override
+    public boolean isConfigurationSettable() {
+        return true;
+    }
+
+    @Deprecated
+    @Override
+    public ConfigurationContext getConfigurationContext() {
+        return context;
     }
 
+    @Deprecated
     @Override
     public void setConfigurationContext(ConfigurationContext context){
-        // TODO think on a SPI or move event part into API...
         this.config = new DefaultConfiguration(context);
         this.context = context;
     }
 
 
+    @Deprecated
     @Override
     public boolean isConfigurationContextSettable() {
         return true;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
index 9360a35..ab35b90 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyConverterManager.java
@@ -112,11 +112,16 @@ public class PropertyConverterManager {
         try {
             writeLock.lock();
             List 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);
             }
-            newConverters.add(converter);
+            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
@@ -222,12 +227,6 @@ public class PropertyConverterManager {
         try {
             readLock.lock();
             addConvertersToList(List.class.cast(this.converters.get(targetType)), converterList);
-        } finally {
-            readLock.unlock();
-        }
-        // transitive converter
-        try {
-            readLock.lock();
             addConvertersToList(List.class.cast(this.transitiveConverters.get(targetType)), converterList);
         } finally {
             readLock.unlock();
@@ -242,7 +241,7 @@ public class PropertyConverterManager {
                 readLock.unlock();
             }
         }
-        if (converterList.isEmpty()) {
+        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) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
----------------------------------------------------------------------
diff --git a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
index 40576fa..bd568d4 100644
--- a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
+++ b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
@@ -20,7 +20,6 @@ package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.spi.PropertyValueBuilder;
 
 import java.util.Collections;
 import java.util.HashMap;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/code/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/code/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java b/code/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
index 98bb29c..3b3b407 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/ConfigurationTest.java
@@ -45,6 +45,12 @@ public class ConfigurationTest {
 
     @Test
     public void testContent(){
+        assertNotNull(current().get("name"));
+        assertNotNull(current().get("name2")); // from default
+        assertNotNull(current().get("name3")); // overridden default, mapped by filter to name property
+        assertNotNull(current().get("name4")); // final only
+
+
         assertEquals("Robin", current().get("name"));
         assertEquals("Sabine", current().get("name2")); // from default
         assertEquals("Mapped to name: Robin", current().get("name3"));  // oderridden default, mapped by filter to name property

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/32a1616c/jqassistant/serviceloader-rules.xml
----------------------------------------------------------------------
diff --git a/jqassistant/serviceloader-rules.xml b/jqassistant/serviceloader-rules.xml
index 6c69b11..082430a 100644
--- a/jqassistant/serviceloader-rules.xml
+++ b/jqassistant/serviceloader-rules.xml
@@ -74,7 +74,7 @@ under the License.
                          OR impl.name =~'.*Test\\$.*')
 
                 AND NOT impl.fqn IN [// All classes of the builder MUST not use the SPI mechanism
-                                     'org.apache.tamaya.builder.ProgrammaticConfigurationContext'
+                                     'org.apache.tamaya.builder.internal.ProgrammaticConfigurationContext'
                                      // See TAMAYA-77 and TAMAYA-78, Oliver B. Fischer, 2015-04-25
                                      // 'org.apache.tamaya.core.internal.DefaultConfigurationContextBuilder'
                                     ]