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 2014/12/15 00:50:57 UTC

[2/3] incubator-tamaya git commit: TAMAYA-26: replaced creation methods with of(XXX) in PropertySourceBuilder. TAMAYA-3: Updated documentation. TAMAYA-25: Adapted component loading.

TAMAYA-26: replaced creation methods with of(XXX) in PropertySourceBuilder.
TAMAYA-3: Updated documentation.
TAMAYA-25: Adapted component loading.


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

Branch: refs/heads/master
Commit: 123a4afcb4f55873ec7a3a3327ffd0e08a26de9d
Parents: 1af5a7d
Author: anatole <an...@apache.org>
Authored: Mon Dec 15 00:48:57 2014 +0100
Committer: anatole <an...@apache.org>
Committed: Mon Dec 15 00:48:57 2014 +0100

----------------------------------------------------------------------
 .../apache/tamaya/ConfigChangeSetBuilder.java   |   2 -
 .../java/org/apache/tamaya/Configuration.java   |  27 ++-
 .../org/apache/tamaya/ConfigurationManager.java |  38 +---
 .../org/apache/tamaya/EnvironmentManager.java   |  44 +---
 .../org/apache/tamaya/PropertyAdapters.java     |  19 +-
 .../java/org/apache/tamaya/PropertySource.java  | 114 +++++-----
 .../java/org/apache/tamaya/spi/Bootstrap.java   | 156 --------------
 .../spi/ConfigurationManagerSingletonSpi.java   |   4 +-
 .../tamaya/spi/DefaultServiceComparator.java    |  85 ++++++++
 .../spi/DefaultServiceContextProvider.java      | 110 ++++++++++
 .../tamaya/spi/DefaultServiceProvider.java      |  87 --------
 .../java/org/apache/tamaya/spi/Orderable.java   |   9 +
 .../org/apache/tamaya/spi/OrdinalProvider.java  |  19 ++
 .../org/apache/tamaya/spi/ServiceContext.java   |  95 +++++++++
 .../tamaya/spi/ServiceContextManager.java       | 100 +++++++++
 .../org/apache/tamaya/spi/ServiceProvider.java  |  57 -----
 .../core/config/AbstractConfiguration.java      |  16 +-
 .../tamaya/core/config/ConfigFunctions.java     |   4 +-
 .../core/config/ConfigurationFormats.java       |  43 +---
 .../core/config/FreezedConfiguration.java       |   2 +-
 .../apache/tamaya/core/internal/MetaConfig.java |   4 +-
 ...DefaultConfigurationManagerSingletonSpi.java |  12 +-
 .../config/EnvPropertiesConfigProvider.java     |   2 +-
 .../config/SystemPropertiesConfigProvider.java  |   2 +-
 .../internal/el/DefaultExpressionEvaluator.java |   7 +-
 ...DependentApplicationEnvironmentProvider.java |   6 +-
 ...ssLoaderDependentEarEnvironmentProvider.java |   6 +-
 .../internal/env/SingleEnvironmentManager.java  |   4 +-
 .../SystemClassLoaderEnvironmentProvider.java   |   4 +-
 .../DefaultConfigFormatsSingletonSpi.java       |   8 +-
 .../resources/DefaultPathResourceLoader.java    |   6 +-
 .../internal/resources/io/AbstractResource.java |   2 +-
 .../core/internal/resources/io/ClassUtils.java  |   2 +-
 .../AbstractClasspathAwarePropertySource.java   |   4 +-
 .../properties/IntersectingPropertySource.java  |   3 +-
 .../properties/PathBasedPropertySource.java     |   7 +-
 .../core/properties/PropertySourceBuilder.java  |   8 +-
 .../core/spi/ConfigurationProviderSpi.java      |   2 +-
 .../tamaya/core/spi/EnvironmentProvider.java    |   2 +-
 .../java/org/apache/tamaya/JavaOneDemo.java     |   8 +-
 .../properties/PropertySourceBuilderTest.java   |   4 +-
 .../internal/MutableTestConfigProvider.java     |   2 +-
 .../tamaya/internal/TestConfigProvider.java     |   4 +-
 .../simple/SimplePropertiesAndCLISample.java    |   7 +-
 .../apache/tamaya/ucs/UC1ReadProperties.java    |  32 +--
 .../apache/tamaya/ucs/UC2CombineProperties.java |  18 +-
 docs/design/2_CoreConcepts.adoc                 | 206 ++++++++++---------
 .../integration/cdi/TestConfigProvider.java     |   2 +-
 48 files changed, 721 insertions(+), 684 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java b/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
index 55ea27c..f9ba38a 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigChangeSetBuilder.java
@@ -299,7 +299,6 @@ public final class ConfigChangeSetBuilder {
      */
     public static Collection<PropertyChangeEvent> compare(PropertySource map1, PropertySource map2) {
         List<PropertyChangeEvent> changes = new ArrayList<>();
-
         for (Map.Entry<String, String> en : map1.toMap().entrySet()) {
             Optional<String> val = map2.get(en.getKey());
             if(!val.isPresent()) {
@@ -309,7 +308,6 @@ public final class ConfigChangeSetBuilder {
                 changes.add(new PropertyChangeEvent(map1, en.getKey(), val.get(), en.getValue()));
             }
         }
-
         for (Map.Entry<String, String> en : map2.toMap().entrySet()) {
             Optional<String> val = map1.get(en.getKey());
             if(!val.isPresent()) {

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/Configuration.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/Configuration.java b/api/src/main/java/org/apache/tamaya/Configuration.java
index 70fab89..2cdd195 100644
--- a/api/src/main/java/org/apache/tamaya/Configuration.java
+++ b/api/src/main/java/org/apache/tamaya/Configuration.java
@@ -156,7 +156,9 @@ public interface Configuration extends PropertySource {
     }
 
     /**
-     * Return a set with all fully qualifies area names.
+     * Return a set with all fully qualifies area names. This method should return the areas as accurate as possible,
+     * but may not provide a complete set of areas that are finally accessible, especially when the underlying storage
+     * does not support key iteration.
      *
      * @return s set with all areas, never {@code null}.
      */
@@ -176,7 +178,9 @@ public interface Configuration extends PropertySource {
 
     /**
      * Return a set with all fully qualified area names, containing the transitive closure also including all
-     * subarea names, regardless if properties are accessible or not.
+     * subarea names, regardless if properties are accessible or not. This method should return the areas as accurate
+     * as possible, but may not provide a complete set of areas that are finally accessible, especially when the
+     * underlying storage does not support key iteration.
      *
      * @return s set with all transitive areas, never {@code null}.
      */
@@ -199,7 +203,9 @@ public interface Configuration extends PropertySource {
 
     /**
      * Return a set with all fully qualified area names, containing only the
-     * areas that match the predicate and have properties attached
+     * areas that match the predicate and have properties attached. This method should return the areas as accurate as possible,
+     * but may not provide a complete set of areas that are finally accessible, especially when the underlying storage
+     * does not support key iteration.
      *
      * @param predicate A predicate to deternine, which areas should be returned, not {@code null}.
      * @return s set with all areas, never {@code null}.
@@ -210,7 +216,9 @@ public interface Configuration extends PropertySource {
 
     /**
      * Return a set with all fully qualified area names, containing the transitive closure also including all
-     * subarea names, regardless if properties are accessible or not.
+     * subarea names, regardless if properties are accessible or not. This method should return the areas as accurate as possible,
+     * but may not provide a complete set of areas that are finally accessible, especially when the underlying storage
+     * does not support key iteration.
      *
      * @param predicate A predicate to deternine, which areas should be returned, not {@code null}.
      * @return s set with all transitive areas, never {@code null}.
@@ -220,7 +228,8 @@ public interface Configuration extends PropertySource {
     }
 
     /**
-     * Allows to evaluate if an area exists.
+     * Allows to evaluate if an area exists. In case where the underlying storage implementation does not allow
+     * querying the keys available, {@code false} should be returned.
      *
      * @param areaKey the configuration area (sub)path.
      * @return {@code true}, if such a node exists.
@@ -350,16 +359,16 @@ public interface Configuration extends PropertySource {
     }
 
     /**
-     * Add a ConfigChangeListener to this configuration instance.
+     * Add a ConfigChangeListener to the given PropertySource instance.
      * @param predicate the event filtering predicate
      * @param l the listener, not null.
      */
-    public static  void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l){
+    public static void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l){
         ConfigurationManager.addChangeListener(predicate, l);
     }
 
     /**
-     * Removes a ConfigChangeListener to this configuration instance.
+     * Removes a ConfigChangeListener from the given PropertySource instance.
      * @param predicate the event filtering predicate
      * @param l the listener, not null.
      */
@@ -368,7 +377,7 @@ public interface Configuration extends PropertySource {
     }
 
     /**
-     * Method to publish changes on a {@link org.apache.tamaya.Configuration} to all interested parties.
+     * Method to publish changes on a {@link org.apache.tamaya.PropertySource} to all interested parties.
      * Basically this method gives an abstraction on the effective event bus design fo listeners. In a CDI context
      * the CDI enterprise event bus should be used internally to do the work, whereas in a SE only environment
      * a more puristic approach would be useful.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
index 9fc3fdc..9915d64 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tamaya;
 
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.spi.ConfigurationManagerSingletonSpi;
 
 import java.util.*;
@@ -30,10 +30,6 @@ import java.util.function.Predicate;
  * proxied configuration templates.
  */
 final class ConfigurationManager{
-    /**
-     * The backing SPI instance.
-     */
-    private static final ConfigurationManagerSingletonSpi configManagerSingletonSpi = loadConfigServiceSingletonSpi();
 
     /**
      * Private singleton constructor.
@@ -42,25 +38,13 @@ final class ConfigurationManager{
     }
 
     /**
-     * Method to initially load the singleton SPI fromMap the {@link org.apache.tamaya.spi.Bootstrap} mechanism.
-     * The instance loaded will be used until the VM is shutdown. In case use cases require more flexibility
-     * it should be transparently implemented in the SPI implementation. This singleton will simply delegate calls
-     * and not cache any responses.
-     *
-     * @return the SPI, never null.
-     */
-    private static ConfigurationManagerSingletonSpi loadConfigServiceSingletonSpi(){
-        return Bootstrap.getService(ConfigurationManagerSingletonSpi.class);
-    }
-
-    /**
      * Allows to check if a configuration with a given name is defined.
      *
      * @param name the configuration's name, not null, not empty.
      * @return true, if such a configuration is defined.
      */
     public static boolean isConfigurationDefined(String name){
-        return Optional.of(configManagerSingletonSpi).get().isConfigurationDefined(name);
+        return ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).isConfigurationDefined(name);
     }
 
     /**
@@ -73,7 +57,7 @@ final class ConfigurationManager{
      * @throws ConfigException if no such configuration is defined.
      */
     public static <T> T getConfiguration(String name, Class<T> template){
-        return Optional.of(configManagerSingletonSpi).get().getConfiguration(name, template);
+        return ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).getConfiguration(name, template);
     }
 
 
@@ -85,7 +69,7 @@ final class ConfigurationManager{
      * @throws ConfigException if no such configuration is defined.
      */
     public static Configuration getConfiguration(String name){
-        return Optional.of(configManagerSingletonSpi).get().getConfiguration(name);
+        return ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).getConfiguration(name);
     }
 
     /**
@@ -95,7 +79,7 @@ final class ConfigurationManager{
      * @throws ConfigException if no such configuration is defined.
      */
     public static Configuration getConfiguration(){
-        return Optional.of(configManagerSingletonSpi).get().getConfiguration();
+        return ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).getConfiguration();
     }
 
     /**
@@ -107,7 +91,7 @@ final class ConfigurationManager{
      * @throws ConfigException if the configuration could not be resolved.
      */
     public static <T> T getConfiguration(Class<T> type){
-        return Optional.of(configManagerSingletonSpi).get().getConfiguration(type);
+        return ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).getConfiguration(type);
     }
 
     /**
@@ -119,7 +103,7 @@ final class ConfigurationManager{
      * @throws ConfigException if the configuration could not be resolved.
      */
     public static void configure(Object instance){
-        Optional.of(configManagerSingletonSpi).get().configure(instance);
+        ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).configure(instance);
     }
 
     /**
@@ -140,7 +124,7 @@ final class ConfigurationManager{
      * @return the evaluated config expression.
      */
     public static String evaluateValue(Configuration config, String expression){
-        return Optional.of(configManagerSingletonSpi).get().evaluateValue(config, expression);
+        return ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).evaluateValue(config, expression);
     }
 
     /**
@@ -149,7 +133,7 @@ final class ConfigurationManager{
      * @param l the listener, not null.
      */
     public static void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
-        Optional.of(configManagerSingletonSpi).get().addChangeListener(predicate, Objects.requireNonNull(l));
+        ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).addChangeListener(predicate, Objects.requireNonNull(l));
     }
 
     /**
@@ -158,7 +142,7 @@ final class ConfigurationManager{
      * @param l the listener, not null.
      */
     public static void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
-        Optional.of(configManagerSingletonSpi).get().removeChangeListener(predicate, Objects.requireNonNull(l));
+        ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).removeChangeListener(predicate, Objects.requireNonNull(l));
     }
 
     /**
@@ -169,6 +153,6 @@ final class ConfigurationManager{
      * @param configChange the change to be published, not null.
      */
     public static void publishChange(ConfigChangeSet configChange) {
-        Optional.of(configManagerSingletonSpi).get().publishChange(Objects.requireNonNull(configChange));
+        ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).publishChange(Objects.requireNonNull(configChange));
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/EnvironmentManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/EnvironmentManager.java b/api/src/main/java/org/apache/tamaya/EnvironmentManager.java
index a6ae5cd..164e456 100644
--- a/api/src/main/java/org/apache/tamaya/EnvironmentManager.java
+++ b/api/src/main/java/org/apache/tamaya/EnvironmentManager.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tamaya;
 
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.spi.EnvironmentManagerSingletonSpi;
 
 import java.util.List;
@@ -31,30 +31,18 @@ import java.util.Set;
  */
 final class EnvironmentManager{
 
-    private static final EnvironmentManagerSingletonSpi environmentManagerSingletonSpi = loadContextProviderSpi();
-
     /**
      * Private singleton constructor.
      */
     private EnvironmentManager(){}
 
     /**
-     * Method to load the environment SPI during initial load.
-     * @return the EnvironmentProviderSpi SPI, never null.
-     */
-    private static EnvironmentManagerSingletonSpi loadContextProviderSpi(){
-        return Bootstrap.getService(EnvironmentManagerSingletonSpi.class);
-    }
-
-    /**
      * Get the current {@link Environment}. The environment is used to determine the current runtime state, which
      * is important for returning the correct configuration.
      * @return the current Environment, never null.
      */
     public static Environment getEnvironment(){
-        return Optional.ofNullable(environmentManagerSingletonSpi).orElseThrow(
-                () -> new IllegalStateException("No SPI loaded.")
-        ).getEnvironment();
+        return ServiceContext.getInstance().getSingleton(EnvironmentManagerSingletonSpi.class).getEnvironment();
     }
 
     /**
@@ -62,9 +50,7 @@ final class EnvironmentManager{
      * @return the current root Environment, never null.
      */
     public static Environment getRootEnvironment(){
-        return Optional.ofNullable(environmentManagerSingletonSpi).orElseThrow(
-                () -> new IllegalStateException("No SPI loaded.")
-        ).getRootEnvironment();
+        return ServiceContext.getInstance().getSingleton(EnvironmentManagerSingletonSpi.class).getRootEnvironment();
     }
 
     /**
@@ -72,9 +58,7 @@ final class EnvironmentManager{
      * @return the hierarchy chain current possible Environments.
      */
     public static List<String> getEnvironmentTypeOrder(){
-        return Optional.ofNullable(environmentManagerSingletonSpi).orElseThrow(
-                () -> new IllegalStateException("No SPI loaded.")
-        ).getEnvironmentTypeOrder();
+        return ServiceContext.getInstance().getSingleton(EnvironmentManagerSingletonSpi.class).getEnvironmentTypeOrder();
     }
 
     /**
@@ -82,9 +66,7 @@ final class EnvironmentManager{
      * @return the current type chain current Environments.
      */
     public static List<String> getEnvironmentHierarchy(){
-        return Optional.ofNullable(environmentManagerSingletonSpi).orElseThrow(
-                () -> new IllegalStateException("No SPI loaded.")
-        ).getEnvironmentHierarchy();
+        return ServiceContext.getInstance().getSingleton(EnvironmentManagerSingletonSpi.class).getEnvironmentHierarchy();
     }
 
     /**
@@ -94,9 +76,7 @@ final class EnvironmentManager{
      * @throws IllegalArgumentException if not such type is present or active.
      */
     public static Optional<Environment> getEnvironment(String environmentType){
-        return Optional.ofNullable(environmentManagerSingletonSpi).orElseThrow(
-                () -> new IllegalStateException("No SPI loaded.")
-        ).getEnvironment(environmentType);
+        return ServiceContext.getInstance().getSingleton(EnvironmentManagerSingletonSpi.class).getEnvironment(environmentType);
     }
 
     /**
@@ -106,9 +86,7 @@ final class EnvironmentManager{
      * @return the corresponding environment, if available.
      */
     public static Optional<Environment> getEnvironment(String environmentType, String contextId){
-        return Optional.ofNullable(environmentManagerSingletonSpi).orElseThrow(
-                () -> new IllegalStateException("No SPI loaded.")
-        ).getEnvironment(environmentType, contextId);
+        return ServiceContext.getInstance().getSingleton(EnvironmentManagerSingletonSpi.class).getEnvironment(environmentType, contextId);
     }
 
     /**
@@ -117,9 +95,7 @@ final class EnvironmentManager{
      * @return the corresponding environment contexts known, never null.
      */
     public static Set<String> getEnvironmentContexts(String environmentType){
-        return Optional.ofNullable(environmentManagerSingletonSpi).orElseThrow(
-                () -> new IllegalStateException("No SPI loaded.")
-        ).getEnvironmentContexts(environmentType);
+        return ServiceContext.getInstance().getSingleton(EnvironmentManagerSingletonSpi.class).getEnvironmentContexts(environmentType);
     }
 
     /**
@@ -128,9 +104,7 @@ final class EnvironmentManager{
      * @return true, if the czurrent environment type is one current the current active environment types.
      */
     public static boolean isEnvironmentActive(String environmentType){
-        return Optional.ofNullable(environmentManagerSingletonSpi).orElseThrow(
-                () -> new IllegalStateException("No SPI loaded.")
-        ).isEnvironmentActive(environmentType);
+        return ServiceContext.getInstance().getSingleton(EnvironmentManagerSingletonSpi.class).isEnvironmentActive(environmentType);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/PropertyAdapters.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/PropertyAdapters.java b/api/src/main/java/org/apache/tamaya/PropertyAdapters.java
index 59dc3b1..cde5934 100644
--- a/api/src/main/java/org/apache/tamaya/PropertyAdapters.java
+++ b/api/src/main/java/org/apache/tamaya/PropertyAdapters.java
@@ -19,25 +19,14 @@
 package org.apache.tamaya;
 
 import org.apache.tamaya.annotation.WithPropertyAdapter;
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.spi.PropertyAdaptersSingletonSpi;
-import java.util.Optional;
 
 /**
  * Singleton manager that provides {@link PropertyAdapter} instance, usable for converting String
  * based configuration entries into any other target types.
  */
 public final class PropertyAdapters{
-    /** The SPI finally registered backing this singleton. */
-    private static final PropertyAdaptersSingletonSpi propertyAdaptersSingletonSpi = loadConfigAdapterProviderSpi();
-
-    /**
-     * Method that loads the singleton backing bean fromMap the {@link org.apache.tamaya.spi.Bootstrap} component.
-     * @return the PropertyAdaptersSingletonSpi, never null.
-     */
-    private static PropertyAdaptersSingletonSpi loadConfigAdapterProviderSpi(){
-        return Bootstrap.getService(PropertyAdaptersSingletonSpi.class);
-    }
 
     /**
      * Orivate singleton constructor.
@@ -53,7 +42,7 @@ public final class PropertyAdapters{
      * @return any adapter replaced with the new adapter, or null.
      */
     public static <T> PropertyAdapter<T> register(Class<T> targetType, PropertyAdapter<T> adapter){
-        return Optional.of(propertyAdaptersSingletonSpi).get().register(targetType, adapter);
+        return ServiceContext.getInstance().getSingleton(PropertyAdaptersSingletonSpi.class).register(targetType, adapter);
     }
 
     /**
@@ -62,7 +51,7 @@ public final class PropertyAdapters{
      * @return true, if the given target type is supported.
      */
     public static boolean isTargetTypeSupported(Class<?> targetType){
-        return Optional.of(propertyAdaptersSingletonSpi).get().isTargetTypeSupported(targetType);
+        return ServiceContext.getInstance().getSingleton(PropertyAdaptersSingletonSpi.class).isTargetTypeSupported(targetType);
     }
 
     /**
@@ -87,7 +76,7 @@ public final class PropertyAdapters{
      * instantiated.
      */
     public static  <T> PropertyAdapter<T> getAdapter(Class<T> targetType, WithPropertyAdapter annotation){
-        return Optional.of(propertyAdaptersSingletonSpi).get().getAdapter(targetType, annotation);
+        return ServiceContext.getInstance().getSingleton(PropertyAdaptersSingletonSpi.class).getAdapter(targetType, annotation);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/PropertySource.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/PropertySource.java b/api/src/main/java/org/apache/tamaya/PropertySource.java
index 22d332c..f44d561 100644
--- a/api/src/main/java/org/apache/tamaya/PropertySource.java
+++ b/api/src/main/java/org/apache/tamaya/PropertySource.java
@@ -24,31 +24,29 @@ import java.util.Optional;
 import java.util.Set;
 
 /**
-* This interface models a provider that serves configuration properties. The contained
-* properties may be read fromMap single or several sources (composite).<br/>
-* Property config are the building blocks out current which complex
-* configuration is setup.
-* <p/>
-* <h3>Implementation Requirements</h3>
-* <p></p>Implementations current this interface must be
-* <ul>
-* <li>Thread safe.
-* </ul>
-* It is highly recommended that implementations also are
-* <ul>
-* <li>Immutable</li>
-* <li>serializable</li>
-* </ul>
-* </p>
-*/
+ * This interface models a provider that serves configuration properties. The contained
+ * properties may be read fromMap single or several sources (composite).<br/>
+ * Property config are the building blocks out current which complex
+ * configuration is setup.
+ * <p/>
+ * <h3>Implementation Requirements</h3>
+ * <p></p>Implementations current this interface must be
+ * <ul>
+ * <li>Thread safe.
+ * </ul>
+ * It is highly recommended that implementations also are
+ * <ul>
+ * <li>Immutable</li>
+ * <li>serializable</li>
+ * </ul>
+ * </p>
+ */
 public interface PropertySource {
 
     /**
-     * Access an empty and immutable PropertyProvider instance.
-     *
-     * @return an empty and immutable PropertyProvider instance, never null.
+     * An empty and immutable PropertyProvider instance.
      */
-    public static final PropertySource EMPTY_PROPERTYSOURCE = new PropertySource(){
+    public static final PropertySource EMPTY_PROPERTYSOURCE = new PropertySource() {
 
         private MetaInfo metaInfo = MetaInfo.of("<empty>");
 
@@ -75,90 +73,90 @@ public interface PropertySource {
 
     /**
      * Access a property.
+     *
      * @param key the property's key, not null.
      * @return the property's value.
      */
     Optional<String> get(String key);
 
     /**
-     * Checks if a property is defined.
-     * @param key the property's key, not null.
-     * @return true, if the property is existing.
-     */
-    boolean containsKey(String key);
-
-    /**
-     * Access the current properties as Map.
-     * @return the a corresponding map, never null.
-     */
-    Map<String, String> toMap();
-
-    /**
      * Get the meta-info current a configuration.
+     *
      * @return the configuration's/config map's metaInfo, or null.
      */
     MetaInfo getMetaInfo();
 
     /**
-     * Compares the given property provider for same
-     * contents, regardless current its current state or runtime implementation.
-     * @param provider the provider to be compared, not null.
-     * @return true, if both property sets equals.
+     * Checks if a property is defined/accessible.
+     * @throws java.lang.UnsupportedOperationException If the underlying storage does not support introspection.
+     * @param key the property's key, not null.
+     * @return true, if the property is existing.
      */
-    default boolean hasSameProperties(PropertySource provider) {
-        return this == provider || ConfigChangeSetBuilder.compare(this, provider).isEmpty();
+    boolean containsKey(String key);
+
+    /**
+     * Allows to quickly check, if a provider is empty.
+     * @return true, if the provier is empty.
+     */
+    default boolean isEmpty(){
+        return keySet().isEmpty();
     }
 
     /**
-     * Access the set current property keys, defined by this provider.
+     * Access the set current property keys, defined by this provider. The resulting Set may not return all keys
+     * accessible, e.g. when the underlying storage does not support iteration of its entries.
+     *
      * @return the key set, never null.
      */
-    default Set<String> keySet(){
+    default Set<String> keySet() {
         return toMap().keySet();
     }
 
     /**
+     * Access the current properties as Map. The resulting Map may not return all items accessible, e.g.
+     * when the underlying storage does not support iteration of its entries.
+     * @return the a corresponding map, never null.
+     */
+    Map<String, String> toMap();
+
+
+    /**
      * Reloads the {@link PropertySource}.
      */
-    default ConfigChangeSet load(){
+    default ConfigChangeSet load() {
         // by default do nothing
         return ConfigChangeSet.emptyChangeSet(this);
     }
 
     /**
      * Allows to evaluate if the provider is mutable.
+     *
      * @return true, if the provider is mutable.
      * @see #apply(ConfigChangeSet)
      */
-    default boolean isMutable(){
+    default boolean isMutable() {
         return false;
     }
 
     /**
      * Apply a config change to this item. Hereby the change must be related to the same instance.
+     *
      * @param change the config change
-     * @throws ConfigException if an unrelated change was passed.
+     * @throws ConfigException               if an unrelated change was passed.
      * @throws UnsupportedOperationException when the configuration is not writable.
      * @see #isMutable()
      */
-    default void apply(ConfigChangeSet change){
-        throw new UnsupportedOperationException("Config/properties not mutable: "+ this);
-    }
-
-    /**
-     * Allows to quickly check, if a provider is empty.
-     * @return true, if the provier is empty.
-     */
-    default boolean isEmpty(){
-        return keySet().isEmpty();
+    default void apply(ConfigChangeSet change) {
+        throw new UnsupportedOperationException("Config/properties not mutable: " + this);
     }
 
     /**
      * Convert the this PropertyProvider instance to a {@link org.apache.tamaya.Configuration}.
+     *
      * @return the configuration, never null.
      */
-    default Configuration toConfiguration(){
-        return new Configuration(){
+    default Configuration toConfiguration() {
+        return new Configuration() {
             @Override
             public Optional<String> get(String key) {
                 return PropertySource.this.get(key);
@@ -177,7 +175,7 @@ public interface PropertySource {
             }
             @Override
             public String toString() {
-                return "Configuration [source: PropertyProvider "+getMetaInfo()+"]";
+                return "Configuration [source: PropertySource "+getMetaInfo()+"]";
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/Bootstrap.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/Bootstrap.java b/api/src/main/java/org/apache/tamaya/spi/Bootstrap.java
deleted file mode 100644
index 891e680..0000000
--- a/api/src/main/java/org/apache/tamaya/spi/Bootstrap.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.spi;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.ServiceLoader;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This singleton provides access to the services available in the current runtime environment and context. The
- * behaviour can be adapted, by calling {@link org.apache.tamaya.spi.Bootstrap#init(ServiceProvider)} before accessing any moneteray
- * services.
- */
-public final class Bootstrap{
-    /**
-     * The ServiceProvider used.
-     */
-    private static volatile ServiceProvider serviceProviderDelegate;
-    /**
-     * The shared lock instance user.
-     */
-    private static final Object LOCK = new Object();
-
-    /**
-     * Private singletons constructor.
-     */
-    private Bootstrap(){
-    }
-
-    /**
-     * Load the {@link ServiceProvider} to be used.
-     *
-     * @return {@link ServiceProvider} to be used for loading the services.
-     */
-    private static ServiceProvider loadDefaultServiceProvider(){
-        try{
-
-            for(ServiceProvider sp : ServiceLoader.load(ServiceProvider.class)){
-                return sp;
-            }
-        }
-        catch(Exception e){
-            Logger.getLogger(Bootstrap.class.getName()).log(Level.INFO, "No ServiceProvider loaded, using default.");
-        }
-        return new DefaultServiceProvider();
-    }
-
-    /**
-     * Replace the current {@link ServiceProvider} in use.
-     *
-     * @param serviceProvider the new {@link ServiceProvider}
-     */
-    public static void init(ServiceProvider serviceProvider){
-        Objects.requireNonNull(serviceProvider);
-        synchronized(LOCK){
-            if (Bootstrap.serviceProviderDelegate==null) {
-                Bootstrap.serviceProviderDelegate = serviceProvider;
-                Logger.getLogger(Bootstrap.class.getName())
-                        .log(Level.INFO, "Money Bootstrap: new ServiceProvider set: " + serviceProvider.getClass().getName());
-            } else {
-                throw new IllegalStateException("Services are already initialized.");
-            }
-        }
-    }
-
-    /**
-     * Ge {@link ServiceProvider}. If necessary the {@link ServiceProvider} will be laziliy loaded.
-     *
-     * @return the {@link ServiceProvider} used.
-     */
-    static ServiceProvider getServiceProvider(){
-        if (serviceProviderDelegate==null) {
-            synchronized(LOCK){
-                if (serviceProviderDelegate==null) {
-                    serviceProviderDelegate = loadDefaultServiceProvider();
-                }
-            }
-        }
-        return serviceProviderDelegate;
-    }
-
-    /**
-     * Delegate method for {@link ServiceProvider#getServices(Class)}.
-     *
-     * @param serviceType the service type.
-     * @return the services found.
-     * @see ServiceProvider#getServices(Class)
-     */
-    public static <T> Collection<T> getServices(Class<T> serviceType){
-        return getServiceProvider().getServices(serviceType);
-    }
-
-    /**
-     * Delegate method for {@link ServiceProvider#getServices(Class)}.
-     *
-     * @param serviceType     the service type.
-     * @param defaultServices the default service list.
-     * @return the services found.
-     * @see ServiceProvider#getServices(Class, java.util.List)
-     */
-    public static <T> List<T> getServices(Class<T> serviceType, List<T> defaultServices){
-        return getServiceProvider().getServices(serviceType, defaultServices);
-    }
-
-    /**
-     * Delegate method for {@link ServiceProvider#getServices(Class)}.
-     *
-     * @param serviceType the service type.
-     * @return the service found, never {@code null}.
-     * @see ServiceProvider#getServices(Class)
-     */
-    public static <T> T getService(Class<T> serviceType){
-        List<T> services = getServiceProvider().getServices(serviceType);
-        if(services.isEmpty()){
-            throw new IllegalStateException("No such service found: " + serviceType);
-        }
-        return services.get(0);
-    }
-
-    /**
-     * Delegate method for {@link ServiceProvider#getServices(Class)}.
-     *
-     * @param serviceType    the service type.
-     * @param defaultService returned if no service was found.
-     * @return the service found, only {@code null}, if no service was found and
-     * {@code defaultService==null}.
-     * @see ServiceProvider#getServices(Class, java.util.List)
-     */
-    public static <T> T getService(Class<T> serviceType, T defaultService){
-        List<T> services = getServiceProvider().getServices(serviceType);
-        if(services.isEmpty()){
-            return defaultService;
-        }
-        return services.get(0);
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
index 86b52a4..46f9a10 100644
--- a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
+++ b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
@@ -27,12 +27,12 @@ import java.util.function.Predicate;
 
 /**
  * Manager for {@link org.apache.tamaya.Configuration} instances. Implementations must register an instance
- * using the {@link Bootstrap} mechanism in place (by default this is based on the {@link java.util.ServiceLoader}.
+ * using the {@link ServiceContextManager} mechanism in place (by default this is based on the {@link java.util.ServiceLoader}.
  * The {@link org.apache.tamaya.ConfigurationManager} Singleton in the API delegates its corresponding calls to the
  * instance returned by the current bootstrap service in place.
  *
  * @see org.apache.tamaya.ConfigurationManager
- * @see Bootstrap
+ * @see ServiceContextManager
  */
 public interface ConfigurationManagerSingletonSpi{
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/DefaultServiceComparator.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/DefaultServiceComparator.java b/api/src/main/java/org/apache/tamaya/spi/DefaultServiceComparator.java
new file mode 100644
index 0000000..c53a52d
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/spi/DefaultServiceComparator.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.util.*;
+
+/**
+ * Simple comparator based on a Collection of {@link org.apache.tamaya.spi.OrdinalProvider} instances.
+ */
+final class DefaultServiceComparator implements Comparator<Object>{
+
+    /**
+     * List of ordinal providers loaded.
+     */
+    private List<OrdinalProvider> ordinalProviders = new ArrayList<>();
+
+    DefaultServiceComparator(Collection<? extends OrdinalProvider> providers){
+        ordinalProviders.addAll(Objects.requireNonNull(providers));
+        ordinalProviders.sort(this::compare);
+    }
+
+    private int compare(OrdinalProvider provider1, OrdinalProvider provider2){
+        int o1 = getOrdinal(provider1);
+        int o2 = getOrdinal(provider2);
+        int order = o1-o2;
+        if(order < 0){
+            return -1;
+        }
+        else if(order > 0){
+            return 1;
+        }
+        return 0;
+    }
+
+    private int getOrdinal(OrdinalProvider provider){
+        if(provider instanceof Orderable){
+            return ((Orderable)provider).order();
+        }
+        return 0;
+    }
+
+    public int getOrdinal(Object service){
+        for(OrdinalProvider provider: ordinalProviders){
+            OptionalInt ord = provider.getOrdinal(service.getClass());
+            if(ord.isPresent()){
+                return ord.getAsInt();
+            }
+        }
+        if(service instanceof Orderable){
+            return ((Orderable)service).order();
+        }
+        return 0;
+    }
+
+
+    @Override
+    public int compare(Object o1, Object o2) {
+        int ord1 = getOrdinal(o1);
+        int ord2 = getOrdinal(o2);
+        int order = ord1-ord2;
+        if(order < 0){
+            return -1;
+        }
+        else if(order > 0){
+            return 1;
+        }
+        return 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/DefaultServiceContextProvider.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/DefaultServiceContextProvider.java b/api/src/main/java/org/apache/tamaya/spi/DefaultServiceContextProvider.java
new file mode 100644
index 0000000..8ac1cd6
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/spi/DefaultServiceContextProvider.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link ServiceContext} interface and hereby uses the JDK
+ * {@link java.util.ServiceLoader} to load the services required.
+ */
+class DefaultServiceContextProvider implements ServiceContext {
+    /** List current services loaded, per class. */
+    private final ConcurrentHashMap<Class, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+    /** Singletons. */
+    private final ConcurrentHashMap<Class, Optional<?>> singletons = new ConcurrentHashMap<>();
+    /** Comparator for ordering of multiple services found. */
+    private DefaultServiceComparator serviceComparator;
+
+    public DefaultServiceContextProvider(){
+        serviceComparator = new DefaultServiceComparator(getServices(OrdinalProvider.class, Collections.emptyList()));
+    }
+
+    @Override
+    public <T> Optional<T> getService(Class<T> serviceType) {
+        Optional<T> cached = (Optional<T>)singletons.get(serviceType);
+        if(cached==null) {
+            List<? extends T> services = getServices(serviceType, Collections.emptyList());
+            if (services.isEmpty()) {
+                cached = Optional.empty();
+            }
+            else{
+                cached = Optional.of(services.get(0));
+            }
+            singletons.put(serviceType, cached);
+        }
+        return cached;
+    }
+
+    /**
+     * Loads and registers services.
+     *
+     * @param serviceType
+     *            The service type.
+     * @param <T>
+     *            the concrete type.
+     * @param defaultList
+     *            the list current items returned, if no services were found.
+     * @return the items found, never {@code null}.
+     */
+    @Override
+    public <T> List<? extends T> getServices(final Class<T> serviceType, final List<? extends T> defaultList) {
+        @SuppressWarnings("unchecked")
+        List<T> found = (List<T>) servicesLoaded.get(serviceType);
+        if (found != null) {
+            return found;
+        }
+        return loadServices(serviceType, defaultList);
+    }
+
+    /**
+     * Loads and registers services.
+     *
+     * @param   serviceType  The service type.
+     * @param   <T>          the concrete type.
+     * @param   defaultList  the list current items returned, if no services were found.
+     *
+     * @return  the items found, never {@code null}.
+     */
+    private <T> List<? extends T> loadServices(final Class<T> serviceType, final List<? extends T> defaultList) {
+        try {
+            List<T> services = new ArrayList<>();
+            for (T t : ServiceLoader.load(serviceType)) {
+                services.add(t);
+            }
+            if(services.isEmpty()){
+                services.addAll(defaultList);
+            }
+            if(!serviceType.equals(OrdinalProvider.class)) {
+                services.sort(serviceComparator);
+            }
+            services = Collections.unmodifiableList(services);
+            final List<T> previousServices = (List<T>) servicesLoaded.putIfAbsent(serviceType, (List<Object>)services);
+            return previousServices != null ? previousServices : services;
+        } catch (Exception e) {
+            Logger.getLogger(DefaultServiceContextProvider.class.getName()).log(Level.WARNING,
+                                                                         "Error loading services current type " + serviceType, e);
+            return defaultList;
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/DefaultServiceProvider.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/DefaultServiceProvider.java b/api/src/main/java/org/apache/tamaya/spi/DefaultServiceProvider.java
deleted file mode 100644
index 9f24b38..0000000
--- a/api/src/main/java/org/apache/tamaya/spi/DefaultServiceProvider.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.spi;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ServiceLoader;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class implements the (default) {@link ServiceProvider} interface and hereby uses the JDK
- * {@link java.util.ServiceLoader} to load the services required.
- */
-class DefaultServiceProvider implements ServiceProvider {
-    /** List current services loaded, per class. */
-    private final ConcurrentHashMap<Class, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
-
-    /**
-     * Loads and registers services.
-     *
-     * @param serviceType
-     *            The service type.
-     * @param <T>
-     *            the concrete type.
-     * @param defaultList
-     *            the list current items returned, if no services were found.
-     * @return the items found, never {@code null}.
-     */
-    @Override
-    public <T> List<T> getServices(final Class<T> serviceType, final List<T> defaultList) {
-        @SuppressWarnings("unchecked")
-        List<T> found = (List<T>) servicesLoaded.get(serviceType);
-        if (found != null) {
-            return found;
-        }
-
-        return loadServices(serviceType, defaultList);
-    }
-
-    /**
-     * Loads and registers services.
-     *
-     * @param   serviceType  The service type.
-     * @param   <T>          the concrete type.
-     * @param   defaultList  the list current items returned, if no services were found.
-     *
-     * @return  the items found, never {@code null}.
-     */
-    private <T> List<T> loadServices(final Class<T> serviceType, final List<T> defaultList) {
-        try {
-            List<T> services = new ArrayList<>();
-            for (T t : ServiceLoader.load(serviceType)) {
-                services.add(t);
-            }
-            if(services.isEmpty()){
-                services.addAll(defaultList);
-            }
-            @SuppressWarnings("unchecked")
-            final List<T> previousServices = (List<T>) servicesLoaded.putIfAbsent(serviceType, (List<Object>) services);
-            return Collections.unmodifiableList(previousServices != null ? previousServices : services);
-        } catch (Exception e) {
-            Logger.getLogger(DefaultServiceProvider.class.getName()).log(Level.WARNING,
-                                                                         "Error loading services current type " + serviceType, e);
-            return defaultList;
-        }
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/Orderable.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/Orderable.java b/api/src/main/java/org/apache/tamaya/spi/Orderable.java
new file mode 100644
index 0000000..401d181
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/spi/Orderable.java
@@ -0,0 +1,9 @@
+package org.apache.tamaya.spi;
+
+/**
+ * Created by Anatole on 14.12.2014.
+ */
+@FunctionalInterface
+public interface Orderable {
+    int order();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/OrdinalProvider.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/OrdinalProvider.java b/api/src/main/java/org/apache/tamaya/spi/OrdinalProvider.java
new file mode 100644
index 0000000..7d0c205
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/spi/OrdinalProvider.java
@@ -0,0 +1,19 @@
+package org.apache.tamaya.spi;
+
+import java.util.OptionalInt;
+
+/**
+ * The ordinal provider is an optional component that provides an abstraction for ordering/prioritizing
+ * services loaded. This can be used to determine, which SPI should be used, if multiple instances are
+ * available, or for ordering chain of services.
+ * @see ServiceContext
+ */
+public interface OrdinalProvider {
+    /**
+     * Evaluate the ordinal number for the given type.
+     * @param type the target type, not null.
+     * @return the ordinal, if not defined, 0 should be returned.
+     */
+     OptionalInt getOrdinal(Class<?> type);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java b/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
new file mode 100644
index 0000000..aeacade
--- /dev/null
+++ b/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * This class models the component that is managing the lifecycle current the
+ * services used by the Configuration API.
+ */
+public interface ServiceContext {
+
+    /**
+     * Delegate method for {@link ServiceContext#getService(Class)}.
+     *
+     * @param serviceType the service type.
+     * @return the service found, never {@code null}.
+     * @see ServiceContext#getService(Class)
+     */
+    default <T> T getSingleton(Class<T> serviceType) {
+        return getService(serviceType)
+                .orElseThrow(() -> new IllegalStateException("Singleton missing: " + serviceType.getName()));
+    }
+    /**
+     * Access a singleton, given its type.
+     *
+     * @param serviceType
+     *            the service type.
+     * @return The instance to be used, never {@code null}
+     */
+    <T> Optional<T> getService(Class<T> serviceType);
+
+	/**
+	 * Access a list current services, given its type. The bootstrap mechanism should
+	 * order the instance for precedence, hereby the most significant should be
+	 * first in order.
+	 * 
+	 * @param serviceType
+	 *            the service type.
+	 * @param defaultList
+	 *            the lis returned, if no services could be found.
+	 * @return The instance to be used, never {@code null}
+	 */
+    <T> List<? extends T> getServices(Class<T> serviceType, List<? extends T> defaultList);
+
+    /**
+     * Access a list current services, given its type. The bootstrap mechanism should
+     * order the instance for precedence, hereby the most significant should be
+     * first in order.
+     *
+     * @param serviceType
+     *            the service type.
+     * @return The instance to be used, never {@code null}
+     */
+    default <T> List<? extends T> getServices(Class<T> serviceType){
+        return getServices(serviceType, Collections.emptyList());
+    }
+
+    /**
+     * Get the current {@link ServiceContext}. If necessary the {@link ServiceContext} will be laziliy loaded.
+     *
+     * @return the {@link ServiceContext} to be used.
+     */
+    public static ServiceContext getInstance(){
+        return ServiceContextManager.getServiceContext();
+    }
+
+    /**
+     * Replace the current {@link ServiceContext} in use.
+     *
+     * @param serviceContext the new {@link ServiceContext}, not null.
+     */
+    public static ServiceContext set(ServiceContext serviceContext){
+        return ServiceContextManager.set(Objects.requireNonNull(serviceContext));
+    }
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/api/src/main/java/org/apache/tamaya/spi/ServiceProvider.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/ServiceProvider.java b/api/src/main/java/org/apache/tamaya/spi/ServiceProvider.java
deleted file mode 100644
index 2c5da59..0000000
--- a/api/src/main/java/org/apache/tamaya/spi/ServiceProvider.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.spi;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * This class models the component that is managing the lifecycle current the
- * services used by the Configuration API.
- */
-public interface ServiceProvider {
-
-	/**
-	 * Access a list current services, given its type. The bootstrap mechanism should
-	 * order the instance for precedence, hereby the most significant should be
-	 * first in order.
-	 * 
-	 * @param serviceType
-	 *            the service type.
-	 * @return The instance to be used, never {@code null}
-	 */
-	@SuppressWarnings("unchecked")
-    default <T> List<T> getServices(Class<T> serviceType){
-          return getServices(serviceType, Collections.emptyList());
-    }
-
-	/**
-	 * Access a list current services, given its type. The bootstrap mechanism should
-	 * order the instance for precedence, hereby the most significant should be
-	 * first in order.
-	 * 
-	 * @param serviceType
-	 *            the service type.
-	 * @param defaultList
-	 *            the lis returned, if no services could be found.
-	 * @return The instance to be used, never {@code null}
-	 */
-    <T> List<T> getServices(Class<T> serviceType, List<T> defaultList);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java b/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
index e0ab2fb..4a9c331 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
@@ -21,7 +21,7 @@ package org.apache.tamaya.core.config;
 import org.apache.tamaya.*;
 import org.apache.tamaya.core.properties.AbstractPropertySource;
 import org.apache.tamaya.core.spi.AdapterProviderSpi;
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 
 import java.util.*;
 import java.util.logging.Logger;
@@ -43,7 +43,7 @@ public abstract class AbstractConfiguration extends AbstractPropertySource imple
 
     @Override
     public <T> Optional<T> get(String key, Class<T> type){
-        AdapterProviderSpi as = Bootstrap.getService(AdapterProviderSpi.class);
+        AdapterProviderSpi as = ServiceContext.getInstance().getSingleton(AdapterProviderSpi.class);
         PropertyAdapter<T> adapter = as.getAdapter(type);
         if(adapter == null){
             throw new ConfigException(
@@ -70,19 +70,19 @@ public abstract class AbstractConfiguration extends AbstractPropertySource imple
     public ConfigChangeSet load(){
         Configuration oldState;
         Configuration newState;
+        ConfigChangeSet changeSet = null;
         synchronized(LOCK) {
             oldState = FreezedConfiguration.of(this);
             reload();
             newState = FreezedConfiguration.of(this);
-            if(oldState.hasSameProperties(newState)){
-                return ConfigChangeSet.emptyChangeSet(this);
-            }
-            this.version = UUID.randomUUID().toString();
+            changeSet = ConfigChangeSetBuilder.of(oldState).addChanges(newState).build();
         }
-        ConfigChangeSet changeSet = ConfigChangeSetBuilder.of(oldState).addChanges(newState).build();
+        if(changeSet.isEmpty()){
+            return ConfigChangeSet.emptyChangeSet(this);
+        }
+        this.version = UUID.randomUUID().toString();
         Configuration.publishChange(changeSet);
         return changeSet;
     }
 
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java b/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
index e28da5e..3075f8c 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
@@ -64,7 +64,7 @@ public final class ConfigFunctions {
                             .collect(Collectors.toMap(
                                     e -> stripKeys ? e.getKey().substring(areaKey.length() + 1) : e.getKey(),
                                     e -> e.getValue())));
-            return PropertySourceBuilder.create("area: " + areaKey).addMap(area).build().toConfiguration();
+            return PropertySourceBuilder.of("area: " + areaKey).addMap(area).build().toConfiguration();
         };
     }
 
@@ -111,7 +111,7 @@ public final class ConfigFunctions {
                             .collect(Collectors.toMap(
                                     e -> stripKeys ? e.getKey().substring(areaKey.length() + 1) : e.getKey(),
                                     e -> e.getValue())));
-            return PropertySourceBuilder.create("area (recursive): " + areaKey).addMap(area).build().toConfiguration();
+            return PropertySourceBuilder.of("area (recursive): " + areaKey).addMap(area).build().toConfiguration();
         };
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormats.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormats.java b/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormats.java
index 4e6e772..26f053d 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormats.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/ConfigurationFormats.java
@@ -18,16 +18,13 @@
  */
 package org.apache.tamaya.core.config;
 
-import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.core.internal.format.DefaultConfigFormatsSingletonSpi;
 import org.apache.tamaya.core.resource.Resource;
 import org.apache.tamaya.core.spi.ConfigurationFormat;
 import org.apache.tamaya.core.spi.ConfigurationFormatsSingletonSpi;
 
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 
 import java.util.Collection;
-import java.util.Optional;
 
 /**
  * Singleton accessor for accessing {@link org.apache.tamaya.core.spi.ConfigurationFormat} instances.
@@ -36,25 +33,6 @@ import java.util.Optional;
 public final class ConfigurationFormats{
 
     /**
-     * Spi to which calls are effectively delegated, never null.
-     */
-    private static final ConfigurationFormatsSingletonSpi spi = loadSpi();
-
-    /**
-     * Method to load the spi fromMap the Bootstrap component.
-     *
-     * @return an instance current ConfigurationFormatsSingletonSpi, never null.
-     */
-    private static ConfigurationFormatsSingletonSpi loadSpi(){
-        try{
-            return Bootstrap.getService(ConfigurationFormatsSingletonSpi.class);
-        }
-        catch(Exception e){
-            return new DefaultConfigFormatsSingletonSpi();
-        }
-    }
-
-    /**
      * Private singleton constructor.
      */
     private ConfigurationFormats(){
@@ -68,9 +46,7 @@ public final class ConfigurationFormats{
      * not available for the given environment.
      */
     public static ConfigurationFormat getFormat(String formatName){
-        return Optional.ofNullable(spi)
-                .orElseThrow(() -> new ConfigException("No ConfigurationFormatsSingletonSpi loaded."))
-                .getFormat(formatName);
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatsSingletonSpi.class).getFormat(formatName);
     }
 
     /**
@@ -79,8 +55,7 @@ public final class ConfigurationFormats{
      * @return a collection current the keys current the registered {@link ConfigurationFormat} instances.
      */
     public static Collection<String> getFormatNames(){
-        return Optional.ofNullable(spi)
-                .orElseThrow(() -> new ConfigException("No ConfigurationFormatsSingletonSpi loaded.")).getFormatNames();
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatsSingletonSpi.class).getFormatNames();
     }
 
     /**
@@ -90,9 +65,7 @@ public final class ConfigurationFormats{
      * @return a matching configuration format, or {@code null} if no matching format could be determined.
      */
     public static ConfigurationFormat getFormat(Resource resource){
-        return Optional.ofNullable(spi)
-                .orElseThrow(() -> new ConfigException("No ConfigurationFormatsSingletonSpi loaded."))
-                .getFormat(resource);
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatsSingletonSpi.class).getFormat(resource);
 
     }
 
@@ -103,9 +76,7 @@ public final class ConfigurationFormats{
      * @return a format instance for reading configuration fromMap a {@code .properties} file, never null.
      */
     public static ConfigurationFormat getPropertiesFormat(){
-        return Optional.ofNullable(spi)
-                .orElseThrow(() -> new ConfigException("No ConfigurationFormatsSingletonSpi loaded."))
-                .getPropertiesFormat();
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatsSingletonSpi.class).getPropertiesFormat();
     }
 
     /**
@@ -115,9 +86,7 @@ public final class ConfigurationFormats{
      * @return a format instance for reading configuration fromMap a {@code .xml} properties file, never null.
      */
     public static ConfigurationFormat getXmlPropertiesFormat(){
-        return Optional.ofNullable(spi)
-                .orElseThrow(() -> new ConfigException("No ConfigurationFormatsSingletonSpi loaded."))
-                .getXmlPropertiesFormat();
+        return ServiceContext.getInstance().getSingleton(ConfigurationFormatsSingletonSpi.class).getXmlPropertiesFormat();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java b/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
index 86030bc..48c0cd1 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/FreezedConfiguration.java
@@ -38,7 +38,7 @@ final class FreezedConfiguration extends AbstractConfiguration implements Serial
 
     private FreezedConfiguration(Configuration config){
         super(MetaInfoBuilder.of(config.getMetaInfo()).set("freezedAt", Instant.now().toString()).build());
-        this.properties = PropertySourceBuilder.create(config).buildFreezed();
+        this.properties = PropertySourceBuilder.of(config).buildFreezed();
         this.version = Objects.requireNonNull(config.getVersion());
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.java b/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.java
index 9ad862c..6a98fb8 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/MetaConfig.java
@@ -20,7 +20,7 @@ package org.apache.tamaya.core.internal;
 
 import org.apache.tamaya.core.config.ConfigurationFormats;
 import org.apache.tamaya.core.resource.Resource;
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.core.spi.ConfigurationFormat;
 import org.apache.tamaya.core.resource.ResourceLoader;
 
@@ -45,7 +45,7 @@ public final class MetaConfig {
     private Map<String,String> properties = new HashMap<>();
 
     private MetaConfig(){
-        List<Resource> resources = Bootstrap.getService(ResourceLoader.class).getResources(MetaConfig.class.getClassLoader(),
+        List<Resource> resources = ServiceContext.getInstance().getSingleton(ResourceLoader.class).getResources(MetaConfig.class.getClassLoader(),
                 "classpath:META-INF/config.properties");
         for(Resource res:resources){
             try{

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java b/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
index 1576cf0..7234ec6 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
@@ -25,7 +25,7 @@ import org.apache.tamaya.core.properties.PropertySourceBuilder;
 import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
 import org.apache.tamaya.core.spi.ExpressionEvaluator;
 
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.spi.ConfigurationManagerSingletonSpi;
 
 import java.lang.annotation.Annotation;
@@ -47,7 +47,7 @@ public class DefaultConfigurationManagerSingletonSpi implements ConfigurationMan
     private ExpressionEvaluator expressionEvaluator = loadEvaluator();
 
     private ExpressionEvaluator loadEvaluator() {
-        ExpressionEvaluator eval = Bootstrap.getService(ExpressionEvaluator.class, null);
+        ExpressionEvaluator eval = ServiceContext.getInstance().getService(ExpressionEvaluator.class).orElse(null);
         if (eval == null) {
             eval = new DefaultExpressionEvaluator();
         }
@@ -55,7 +55,7 @@ public class DefaultConfigurationManagerSingletonSpi implements ConfigurationMan
     }
 
     public DefaultConfigurationManagerSingletonSpi() {
-        for (ConfigurationProviderSpi spi : Bootstrap.getServices(ConfigurationProviderSpi.class)) {
+        for (ConfigurationProviderSpi spi : ServiceContext.getInstance().getServices(ConfigurationProviderSpi.class, Collections.emptyList())) {
             configProviders.put(spi.getConfigName(), spi);
         }
     }
@@ -188,12 +188,12 @@ public class DefaultConfigurationManagerSingletonSpi implements ConfigurationMan
         @Override
         public void reload() {
             this.configuration =
-                    PropertySourceBuilder.create(DEFAULT_CONFIG_NAME)
-                            .addProviders(PropertySourceBuilder.create("CL default")
+                    PropertySourceBuilder.of(DEFAULT_CONFIG_NAME)
+                            .addProviders(PropertySourceBuilder.of("CL default")
                                     .withAggregationPolicy(AggregationPolicy.LOG_ERROR)
                                     .addPaths("META-INF/cfg/default/**/*.xml", "META-INF/cfg/default/**/*.properties", "META-INF/cfg/default/**/*.ini")
                                     .build())
-                            .addProviders(PropertySourceBuilder.create("CL default")
+                            .addProviders(PropertySourceBuilder.of("CL default")
                                     .withAggregationPolicy(AggregationPolicy.LOG_ERROR)
                                     .addPaths("META-INF/cfg/config/**/*.xml", "META-INF/cfg/config/**/*.properties", "META-INF/cfg/config/**/*.ini")
                                     .build())

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java
index 5f2263e..1494e7a 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/config/EnvPropertiesConfigProvider.java
@@ -34,7 +34,7 @@ public class EnvPropertiesConfigProvider implements ConfigurationProviderSpi{
     private Configuration envConfig;
 
     public EnvPropertiesConfigProvider(){
-        envConfig = PropertySourceBuilder.create("environment.properties").addEnvironmentProperties().build().toConfiguration();
+        envConfig = PropertySourceBuilder.of("environment.properties").addEnvironmentProperties().build().toConfiguration();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java
index 54453c5..4f42b95 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/config/SystemPropertiesConfigProvider.java
@@ -34,7 +34,7 @@ public class SystemPropertiesConfigProvider implements ConfigurationProviderSpi{
     private Configuration systemConfig;
 
     public SystemPropertiesConfigProvider(){
-        systemConfig = PropertySourceBuilder.create("system.properties").addSystemProperties().build().toConfiguration();
+        systemConfig = PropertySourceBuilder.of("system.properties").addSystemProperties().build().toConfiguration();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java b/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
index b42d568..e5baecc 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
@@ -19,8 +19,7 @@
 package org.apache.tamaya.core.internal.el;
 
 import org.apache.tamaya.ConfigException;
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.core.spi.ExpressionEvaluator;
 import org.apache.tamaya.core.spi.ExpressionResolver;
 
@@ -37,10 +36,10 @@ public final class DefaultExpressionEvaluator implements ExpressionEvaluator{
     private ExpressionResolver defaultResolver;
 
     public DefaultExpressionEvaluator() {
-        for(ExpressionResolver resolver: Bootstrap.getServices(ExpressionResolver.class)){
+        for(ExpressionResolver resolver: ServiceContext.getInstance().getServices(ExpressionResolver.class)){
             resolvers.put(resolver.getResolverId(), resolver);
         }
-        defaultResolver = Bootstrap.getService(ExpressionResolver.class);
+        defaultResolver = ServiceContext.getInstance().getSingleton(ExpressionResolver.class);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java
index f6afe65..b16ed8d 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentApplicationEnvironmentProvider.java
@@ -22,7 +22,7 @@ import org.apache.tamaya.Environment;
 import org.apache.tamaya.core.config.ConfigurationFormats;
 import org.apache.tamaya.core.env.EnvironmentBuilder;
 import org.apache.tamaya.core.resource.Resource;
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.core.spi.ConfigurationFormat;
 import org.apache.tamaya.core.spi.EnvironmentProvider;
 import org.apache.tamaya.core.resource.ResourceLoader;
@@ -65,7 +65,7 @@ public class ClassLoaderDependentApplicationEnvironmentProvider implements Envir
         if(available!=null && !available){
             return false;
         }
-        List<Resource> propertyUris = Bootstrap.getService(ResourceLoader.class).getResources(cl,
+        List<Resource> propertyUris = ServiceContext.getInstance().getSingleton(ResourceLoader.class).getResources(cl,
                 "classpath:META-INF/env/application.properties", "classpath:META-INF/env/application.xml", "classpath:META-INF/env/application.ini");
         available = !propertyUris.isEmpty();
         this.environmentAvailable.put(cl, available);
@@ -82,7 +82,7 @@ public class ClassLoaderDependentApplicationEnvironmentProvider implements Envir
         if(environment!=null){
             return environment;
         }
-        List<Resource> propertyUris = Bootstrap.getService(ResourceLoader.class).getResources(cl,
+        List<Resource> propertyUris = ServiceContext.getInstance().getSingleton(ResourceLoader.class).getResources(cl,
                 "classpath:META-INF/env/application.properties", "classpath:META-INF/env/application.xml", "classpath:META-INF/env/application.ini");
         Map<String,String> data = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java b/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java
index e1d30a3..e389156 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/env/ClassLoaderDependentEarEnvironmentProvider.java
@@ -23,7 +23,7 @@ import org.apache.tamaya.Stage;
 import org.apache.tamaya.core.config.ConfigurationFormats;
 import org.apache.tamaya.core.env.EnvironmentBuilder;
 import org.apache.tamaya.core.resource.Resource;
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.core.spi.ConfigurationFormat;
 import org.apache.tamaya.core.spi.EnvironmentProvider;
 import org.apache.tamaya.core.resource.ResourceLoader;
@@ -68,7 +68,7 @@ public class ClassLoaderDependentEarEnvironmentProvider implements EnvironmentPr
         if(available!=null && !available){
             return false;
         }
-        List<Resource> propertyUris = Bootstrap.getService(ResourceLoader.class).getResources(cl,
+        List<Resource> propertyUris = ServiceContext.getInstance().getSingleton(ResourceLoader.class).getResources(cl,
                 "classpath:META-INF/env/ear.properties", "classpath:META-INF/env/ear.xml", "classpath:META-INF/env/ear.ini");
         available = !propertyUris.isEmpty();
         this.environmentAvailable.put(cl, available);
@@ -85,7 +85,7 @@ public class ClassLoaderDependentEarEnvironmentProvider implements EnvironmentPr
         if(environment!=null){
             return environment;
         }
-        List<Resource> resources = Bootstrap.getService(ResourceLoader.class).getResources(cl,
+        List<Resource> resources = ServiceContext.getInstance().getSingleton(ResourceLoader.class).getResources(cl,
                 "classpath:META-INF/env/ear.properties", "classpath:META-INF/env/ear.xml", "classpath:META-INF/env/ear.ini");
         Map<String,String> data = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/123a4afc/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java b/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java
index 5c3d52a..6d75ac2 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/env/SingleEnvironmentManager.java
@@ -21,7 +21,7 @@ package org.apache.tamaya.core.internal.env;
 import org.apache.tamaya.Environment;
 
 import org.apache.tamaya.core.internal.MetaConfig;
-import org.apache.tamaya.spi.Bootstrap;
+import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.spi.EnvironmentManagerSingletonSpi;
 import org.apache.tamaya.core.spi.EnvironmentProvider;
 
@@ -46,7 +46,7 @@ public class SingleEnvironmentManager implements EnvironmentManagerSingletonSpi{
     private final List<EnvironmentProvider> environmentProviders = loadEnvironmentProviders();
 
     private List<EnvironmentProvider> loadEnvironmentProviders() {
-        for(EnvironmentProvider prov: Bootstrap.getServices(EnvironmentProvider.class)){
+        for(EnvironmentProvider prov: ServiceContext.getInstance().getServices(EnvironmentProvider.class)){
             providerMap.put(prov.getEnvironmentType(), prov);
         }
         String providerOrdering = MetaConfig.getOrDefault(ENVIRONMENT_ORDER_KEY, DEFAULT_ENVIRONMENT_ORDER);