http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
 
b/code/old/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
new file mode 100644
index 0000000..17c1bf4
--- /dev/null
+++ 
b/code/old/api/src/main/java/org/apache/tamaya/spi/ConfigurationContextBuilder.java
@@ -0,0 +1,336 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import org.apache.tamaya.TypeLiteral;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A builder for creating new or adapting instances of {@link 
ConfigurationContext}.
+ * Builders can be obtained in exactly two ways:
+ * <ol>
+ *     <li>By accessing a preinitialized builder from an existing {@link 
ConfigurationContext},
+ *     by calling {@link 
org.apache.tamaya.spi.ConfigurationContext#toBuilder()}.</li>
+ *     <li>By accessing an empty builder instance from
+ *     {@link 
org.apache.tamaya.ConfigurationProvider#getConfigurationContextBuilder()}.</li>
+ * </ol>
+ * After all changes are applied to a builder a new {@link 
ConfigurationContext} instance can
+ * be created and can be applied by calling
+ * {@link 
org.apache.tamaya.ConfigurationProvider#setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)}.
+ * @deprecated Use {@link ConfigurationBuilder} instead.
+ */
+@Deprecated
+public interface ConfigurationContextBuilder {
+
+    /**
+     * Init this builder instance with the given {@link ConfigurationContext} 
instance. This
+     * method will use any existing property sources, filters, converters and 
the combination
+     * policy of the given {@link ConfigurationContext} and initialize the 
current builder
+     * with them.
+     *
+     * @param context the {@link ConfigurationContext} instance to be used, 
not {@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder setContext(ConfigurationContext context);
+
+    /**
+     * This method can be used for adding {@link PropertySource}s.
+     * Hereby the property source is added to the tail of property sources with
+     * lowest priority  regardless of its current ordinal value. To sort the 
property
+     * sources based on their ordinals call {@link #sortPropertySources}.
+     *
+     * @param propertySources the PropertySources to add
+     * @return this builder, for chaining, never null.
+     * @throws IllegalArgumentException If a property source with a given name 
already
+     * exists.
+     */
+    ConfigurationContextBuilder addPropertySources(PropertySource... 
propertySources);
+
+    /**
+     * This method can be used for programmatically adding {@link 
PropertySource}s.
+     * Hereby the property source is added to the tail of property sources with
+     * lowest priority regardless of its current ordinal value. To sort the 
property
+     * sources based on their ordinals call {@link #sortPropertySources}.
+     *
+     * @param propertySources the PropertySources to add
+     * @return this builder, for chaining, never null.
+     * @throws IllegalArgumentException If a property source with a given name 
already
+     * exists.
+     */
+    ConfigurationContextBuilder addPropertySources(Collection<PropertySource> 
propertySources);
+
+    /**
+     * Add all registered (default) property sources to the context built. The 
sources are ordered
+     * based on their ordinal values and added to the chain of property 
sources with
+     * higher priority.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addDefaultPropertySources();
+
+    /**
+     * Removes the given property sources, if existing. The existing order of 
property
+     * sources is preserved.
+     *
+     * @param propertySources the property sources to remove, not {@code null}.
+     * @return the builder for chaining.
+     */
+    ConfigurationContextBuilder removePropertySources(PropertySource... 
propertySources);
+
+    /**
+     * Removes the given property sources, if existing. The existing order of 
property
+     * sources is preserved.
+     *
+     * @param propertySources the property sources to remove, not {@code null}.
+     * @return the builder for chaining.
+     */
+    ConfigurationContextBuilder 
removePropertySources(Collection<PropertySource> propertySources);
+
+    /**
+     * Access the current chain of property sources. Items at the end of the 
list have
+     * precedence/more significance.
+     *
+     * @return the property source chain, never {@code null}.
+     */
+    List<PropertySource> getPropertySources();
+
+    /**
+     * Access the current chain of property filters. Items at the end of the 
list have
+     * precedence/more significance.
+     *
+     * @return the property source chain, never {@code null}.
+     */
+    List<PropertyFilter> getPropertyFilters();
+
+    /**
+     * Access the current registered property converters.
+     *
+     * @return the current registered property converters.
+     */
+    Map<TypeLiteral<?>, Collection<PropertyConverter<?>>> 
getPropertyConverter();
+
+    /**
+     * Increases the priority of the given property source, by moving it 
towards the end
+     * of the chain of property sources. If the property source given is 
already at the end
+     * this method has no effect. This operation does not change any ordinal 
values.
+     *
+     * @param propertySource the property source to be incresed regarding its 
significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in 
the current
+     * chain.
+     */
+    ConfigurationContextBuilder increasePriority(PropertySource 
propertySource);
+
+    /**
+     * Decreases the priority of the given property source, by moving it 
towards the start
+     * of the chain of property sources. If the property source given is 
already the first
+     * this method has no effect. This operation does not change any ordinal 
values.
+     *
+     * @param propertySource the property source to be decresed regarding its 
significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in 
the current
+     * chain.
+     */
+    ConfigurationContextBuilder decreasePriority(PropertySource 
propertySource);
+
+    /**
+     * Increases the priority of the given property source to be maximal, by 
moving it to
+     * the tail of the of property source chain. If the property source given 
is
+     * already the last item this method has no effect. This operation does 
not change
+     * any ordinal values.
+     *
+     * @param propertySource the property source to be maximized regarding its 
significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in 
the current
+     * chain.
+     */
+    ConfigurationContextBuilder highestPriority(PropertySource propertySource);
+
+    /**
+     * Decreases the priority of the given property source to be minimal, by 
moving it to
+     * the start of the chain of property source chain. If the property source 
given is
+     * already the first item this method has no effect. This operation does 
not change
+     * any ordinal values.
+     *
+     * @param propertySource the property source to be minimized regarding its 
significance.
+     * @return the builder for chaining.
+     * @throws IllegalArgumentException If no such property source exists in 
the current
+     * chain.
+     */
+    ConfigurationContextBuilder lowestPriority(PropertySource propertySource);
+
+    /**
+     * Adds the given PropertyFilter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the property
+     * filters call {@link #sortPropertyFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters);
+
+    /**
+     * Adds the given PropertyFilter instances, hereby the instances are added
+     * to the end of the list with highest priority. The ordering of existing
+     * property filters remains unchanged. To sort the property
+     * filters call {@link #sortPropertyFilter}.
+     *
+     * @param filters the filters to add
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> 
filters);
+
+    /**
+     * Add all registered (default) property filters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addDefaultPropertyFilters();
+
+
+    /**
+     * Removes the given PropertyFilter instances, if existing. The order of 
the remaining
+     * filters is preserved.
+     *
+     * @param filters the filter to remove
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder removePropertyFilters(PropertyFilter... 
filters);
+
+    /**
+     * Removes the given PropertyFilter instances, if existing. The order of 
the remaining
+     * filters is preserved.
+     *
+     * @param filters the filter to remove
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder 
removePropertyFilters(Collection<PropertyFilter> filters);
+
+    /**
+     * This method can be used for adding {@link PropertyConverter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converters is for
+     * @param propertyConverters the PropertyConverters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> 
typeToConvert,
+                                                          
@SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters);
+
+    /**
+     * This method can be used for adding {@link PropertyConverter}s.
+     * Converters are added at the end after any existing converters.
+     * For converters already registered for the current target type the
+     * method has no effect.
+     *
+     * @param typeToConvert     the type for which the converters is for
+     * @param propertyConverters the PropertyConverters to add for this type
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> 
typeToConvert,
+                                                          
Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Add all registered (default) property converters to the context built.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder addDefaultPropertyConverters();
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param propertyConverters    the converters to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> 
typeToConvert,
+                                                             
@SuppressWarnings("unchecked") PropertyConverter<T>... propertyConverters);
+
+    /**
+     * Removes the given PropertyConverter instances for the given type,
+     * if existing.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @param propertyConverters    the converters to remove
+     * @param <T> the target type.
+     * @return this builder, for chaining, never null.
+     */
+    <T> ConfigurationContextBuilder removePropertyConverters(TypeLiteral<T> 
typeToConvert,
+                                                             
Collection<PropertyConverter<T>> propertyConverters);
+
+    /**
+     * Removes all converters for the given type, which actually renders a 
given type
+     * unsupported for type conversion.
+     *
+     * @param typeToConvert the type which the converters is for
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> 
typeToConvert);
+
+    /**
+     * Sorts the current registered property sources using the given 
comparator.
+     *
+     * NOTE: property sources at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not {@code null}.
+     * @return this instance for chaining.
+     */
+    ConfigurationContextBuilder sortPropertySources(Comparator<PropertySource> 
comparator);
+
+    /**
+     * Sorts the current registered property filters using the given 
comparator.
+     *
+     * NOTE: property filters at the beginning have minimal significance.
+     *
+     * @param comparator the comparator to be used, not {@code null}.
+     * @return this instance for chaining.
+     */
+    ConfigurationContextBuilder sortPropertyFilter(Comparator<PropertyFilter> 
comparator);
+
+    /**
+     * Sets the {@link PropertyValueCombinationPolicy} used to evaluate the 
final
+     * property values.
+     *
+     * @param policy the {@link PropertyValueCombinationPolicy} used, not 
{@code null}.
+     * @return this builder, for chaining, never null.
+     */
+    ConfigurationContextBuilder 
setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy);
+
+    /**
+     * Builds a new {@link ConfigurationContext} based on the data in this 
builder. The ordering of property
+     * sources and property filters is not changed, regardless of their 
ordinals. For ensure a certain
+     * ordering/significance call {@link #sortPropertyFilter(Comparator)} 
and/or {@link #sortPropertySources(Comparator)}
+     * before building the context.
+     *
+     * @return the final context to be used to create a configuration.
+     * @see 
org.apache.tamaya.ConfigurationProvider#createConfiguration(ConfigurationContext)
+     */
+    ConfigurationContext build();
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
 
b/code/old/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
new file mode 100644
index 0000000..fb93ab4
--- /dev/null
+++ 
b/code/old/api/src/main/java/org/apache/tamaya/spi/ConfigurationProviderSpi.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import org.apache.tamaya.Configuration;
+
+/**
+ * SPI that must be implemented to provide the component that manages all 
{@link org.apache.tamaya.Configuration}
+ * instances in a system. In SE this may be a true singleton containing exact 
one {@link org.apache.tamaya.Configuration}
+ * instance, whereas in Java EE and other more complex environments instances 
may be returned depending the current
+ * runtime context.
+ */
+public interface ConfigurationProviderSpi {
+
+    /**
+     * Access the current {@link org.apache.tamaya.Configuration}.
+     *
+     * @return the current {@link org.apache.tamaya.Configuration} instance, 
never null.
+     */
+    Configuration getConfiguration();
+
+    /**
+     * Create a {@link Configuration} instance using the given context. The 
configuration
+     * created hereby must respect the artifacts provided by its context 
(property sources,
+     * filters, converters, policies etc), including their ordering and 
significance.
+     * @param context the context to be used, not {@code null}.
+     * @return the corresponding configuration instance.
+     */
+    Configuration createConfiguration(ConfigurationContext context);
+
+    /**
+     * Creates a new {@link org.apache.tamaya.spi.ConfigurationContextBuilder} 
instance.
+     *
+     * @return a new {@link 
org.apache.tamaya.spi.ConfigurationContextBuilder}, never null.
+     * @deprecated Will be removed
+     */
+    @Deprecated
+    ConfigurationContextBuilder getConfigurationContextBuilder();
+
+    /**
+     * Creates a new {@link org.apache.tamaya.spi.ConfigurationBuilder} 
instance.
+     *
+     * @return a new {@link org.apache.tamaya.spi.ConfigurationBuilder}, never 
null.
+     */
+    ConfigurationBuilder getConfigurationBuilder();
+
+    /**
+     * This method allows to replace the current {@link 
org.apache.tamaya.Configuration} with a new
+     * instance. This can be used to update the configuration with a new one, 
e.g. because some of the
+     * data has changed and must be updated. It is the responsibility of the 
ConfigurationProvider to trigger
+     * corresponding update events for the current {@link 
org.apache.tamaya.Configuration}.
+     *
+     * @param config the new Configuration to be applied.
+     * @throws java.lang.UnsupportedOperationException if the current provider 
is read-only.
+     */
+    void setConfiguration(Configuration config);
+
+    /**
+     * Method that allows to determine if a new {@link 
org.apache.tamaya.Configuration} can be applied
+     * programmatically.
+     *
+     * @return true, if {@link 
#setConfiguration(org.apache.tamaya.Configuration)} is supported
+     * by the current implementation.
+     * @see #setConfiguration(org.apache.tamaya.Configuration)
+     */
+    default boolean isConfigurationSettable(){
+        return true;
+    }
+
+    /**
+     * Get access to the current {@link ConfigurationContext}.
+     *
+     * @return the current {@link ConfigurationContext}, never null.
+     * @deprecated Will be removed in favour of {@link 
Configuration#getContext()}.
+     */
+    @Deprecated
+    default ConfigurationContext getConfigurationContext(){
+        return getConfiguration().getContext();
+    }
+
+    /**
+     * This method allows to replace the current {@link 
org.apache.tamaya.spi.ConfigurationContext} with a new
+     * instance. This can be used to update the context with a new one, e.g. 
because some of the configuration
+     * data has changed and must be updated. It is the responsibility of the 
ConfigurationProvider to trigger
+     * corresponding update event for the current {@link 
org.apache.tamaya.spi.ConfigurationContext} or
+     * {@link org.apache.tamaya.Configuration}.
+     *
+     * @param context the new ConfigurationContext to be applied.
+     * @throws java.lang.UnsupportedOperationException if the current provider 
is read-only.
+     * @deprecated use {@link #setConfiguration(Configuration)}
+     */
+    @Deprecated
+    default void setConfigurationContext(ConfigurationContext context){
+        setConfiguration(createConfiguration(context));
+    }
+
+    /**
+     * Method that allows to determine if a new {@link 
org.apache.tamaya.spi.ConfigurationContext} can be applied
+     * programmatically.
+     *
+     * @return true, if {@link 
#setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)} is 
supported
+     * by the current implementation.
+     * @see 
#setConfigurationContext(org.apache.tamaya.spi.ConfigurationContext)
+     * @deprecated use {@link #isConfigurationSettable()}
+     */
+    @Deprecated
+    default boolean isConfigurationContextSettable(){
+        return isConfigurationSettable();
+    }
+
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/Experimental.java
----------------------------------------------------------------------
diff --git a/code/old/api/src/main/java/org/apache/tamaya/spi/Experimental.java 
b/code/old/api/src/main/java/org/apache/tamaya/spi/Experimental.java
new file mode 100644
index 0000000..9831820
--- /dev/null
+++ b/code/old/api/src/main/java/org/apache/tamaya/spi/Experimental.java
@@ -0,0 +1,32 @@
+/*
+ * 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.lang.annotation.*;
+
+/**
+ * This is a simple annotation for flaging out functionality or features the 
Tamaya team is not sure if it is already
+ * stabilized, so use it with some caution.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, 
ElementType.CONSTRUCTOR, ElementType.FIELD,
+        ElementType.TYPE})
+public @interface Experimental {
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java 
b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java
new file mode 100644
index 0000000..ab96b6b
--- /dev/null
+++ b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyConverter.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+/**
+ * Interface for an property that converts a configured String into something 
else.
+ * This is used for implementing type conversion from a property (String) to a 
certain target
+ * type. Hereby the target type can be multi-value (e.g. collections) or 
complex if needed.
+ * 
+ * @param <T> the type of the type literal
+ */
+@FunctionalInterface
+public interface PropertyConverter<T>{
+
+    /**
+     * Convert the given configuration keys from its String representation 
into the required target type.
+     * The context instance passed also allows to add a list of supported 
formats, which is very handy in case a
+     * value could not be converted. This list of supported formats can then 
shown to the user to give some hints
+     * how a value could be configured.
+     * 
+     * @param value configuration key that needs to be converted
+     * @param context the {@link ConversionContext}, containing the String 
value and the requested configuration key.
+     * @return converted keys
+     * @see ConversionContext#addSupportedFormats(Class, String...)
+     */
+    T convert(String value, ConversionContext context);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java 
b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
new file mode 100644
index 0000000..3054496
--- /dev/null
+++ b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+
+/**
+ * <p>Interface for filtering the current map of properties during the 
evaluation of the chain of PropertySources.
+ * Filters can be registered using the {@link 
org.apache.tamaya.spi.ServiceContext}. The ordinal
+ * hereby is defined by the corresponding {@code @Priority} annotation.</p>
+ * <p>Filters </p>
+ */
+@FunctionalInterface
+public interface PropertyFilter {
+
+    /**
+     * <p>Maps the current {@code valueToBeFiltered} value to a new value. The 
resulting value will be used as the result
+     * passed to the user.</p>
+     * <p>If a filter is currently not available, it should just pass the 
input map to the method's
+     * output.</p>
+     * <p>Returning {@code null} will remove the entry.</p>
+     * <h3>Implementation specification</h3>
+     * Implementations of this class must be
+     * <ul>
+     *     <li>reentrant</li>
+     *     <li>thread-safe</li>
+     * </ul>
+     * @param value the value to be filtered, which also can be {@code null} 
if removed by another filter.
+     * @param context the filter context, not {@code null}.
+     * @return the filtered value, or {@code null} if the value should be 
removed alltogether.
+     * @see PropertyValue
+     * @see PropertyValueBuilder
+     */
+    PropertyValue filterProperty(PropertyValue value, FilterContext context);
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java 
b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
new file mode 100644
index 0000000..3f7beea
--- /dev/null
+++ 
b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertySourceProvider.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * <p>Implement this interfaces to provide a PropertySource provider which
+ * is able to register multiple PropertySources. This is e.g. needed if
+ * there are multiple property files of a given config file name.</p>
+ * 
+ * <p>If a PropertySource like JNDI only exists once, then there is no need
+ * to implement it via the PropertySourceProvider but should directly
+ * expose a {@link PropertySource}.</p>
+ *
+ * <p>A PropertySourceProvider will get picked up via the
+ * {@link java.util.ServiceLoader} mechanism and must get registered via
+ * META-INF/services/org.apache.tamaya.spi.PropertySourceProvider</p>
+ */
+@FunctionalInterface
+public interface PropertySourceProvider {
+
+    /**
+     * A resusable instance of an empty PropertySource.
+     */
+    PropertySourceProvider EMPTY = new PropertySourceProvider() {
+
+        @Override
+        public Collection<PropertySource> getPropertySources() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public String toString(){
+            return "PropertySourceProvider(empty)";
+        }
+    };
+
+    /**
+     * @return For each e.g. property file, we return a single PropertySource
+     *         or an empty list if no PropertySource exists.
+     */
+    Collection<PropertySource> getPropertySources();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java 
b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
new file mode 100644
index 0000000..c538de7
--- /dev/null
+++ b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Class modelling the result of a request for a property value. A property 
value is basically identified by its key.
+ * There might be reasons, where one want to further analyze, which 
PropertySources provided a value and which not, so
+ * it is possible to create a PropertyValue with a null value. Nevertheless in 
all cases the provider source (typically
+ * the name of the PropertySource) must be set.
+ */
+public final class PropertyValue implements Serializable{
+    private static final long serialVersionUID = 1L;
+    /** The requested key. */
+    private String key;
+    /** The value. */
+    private String value;
+    /** The source of the value. */
+    private String source;
+    /** Additional metadata provided by the provider. */
+    private Map<String,String> metaEntries = new HashMap<>();
+
+    PropertyValue(PropertyValueBuilder builder){
+        this.key = Objects.requireNonNull(builder.key);
+        this.value = builder.value;
+        this.source = Objects.requireNonNull(builder.source);
+        if(builder.metaEntries !=null) {
+            this.metaEntries.putAll(builder.metaEntries);
+        }
+    }
+
+    /**
+     * Creates a new instance
+     * @param key the key, not {@code null}.
+     * @param value the value, not {@code null}.
+     * @param source the source, typically the name of the {@link 
PropertySource} providing
+     *               the value, not {@code null}.
+     */
+    private PropertyValue(String key, String value, String source){
+        this.key = Objects.requireNonNull(key, "Key is required.");
+        this.value = Objects.requireNonNull(value, "Value is required.");
+        this.source = Objects.requireNonNull(source, "Source is required.");
+    }
+
+    /**
+     * The requested key.
+     * @return the, key never {@code null}.
+     */
+    public String getKey() {
+        return key;
+    }
+
+    /**
+     * The source.
+     * @return the source, which provided the value, not {@code null}.
+     * @see PropertySource#getName() .
+     */
+    public String getSource() {
+        return this.source;
+    }
+
+
+    /**
+     * The value.
+     * @return the value, in case a value is null it is valid to return {#code 
null} as result for
+     * {@link PropertySource#get(String)}.
+     */
+    public String getValue() {
+        return this.value;
+    }
+
+    /**
+     * Creates a full configuration map for this key, value pair and all its 
meta context data. This map
+     * is also used for subsequent processing, like value filtering.
+     * @return the property value entry map.
+     */
+    public Map<String, String> getMetaEntries() {
+        return Collections.unmodifiableMap(metaEntries);
+    }
+
+    /**
+     * Creates a new builder instance.
+     * @param key the key, not {@code null}.
+     * @param source the source, typically the name of the {@link 
PropertySource}
+     *               providing the value, not {@code null}.
+     * @return a new builder instance.
+     */
+    public static PropertyValueBuilder builder(String key, String source){
+        Objects.requireNonNull(key, "Key must be given.");
+        Objects.requireNonNull(source, "Source must be given");
+
+        return new PropertyValueBuilder(key, source);
+    }
+
+    /**
+     * Creates a new builder instance.
+     * @param key the key, not {@code null}.
+     * @param value the property value, not {@code null}.
+     * @param source the source, typically the name of the {@link 
PropertySource}
+     *               providing the value, not {@code null}.
+     * @return a new builder instance.
+     */
+    public static PropertyValueBuilder builder(String key, String value, 
String source) {
+        Objects.requireNonNull(key, "Key must be given.");
+        Objects.requireNonNull(value, "Value must be given");
+        Objects.requireNonNull(source, "Source must be given.");
+
+        return new PropertyValueBuilder(key, value, source);
+    }
+
+
+    /**
+     * Creates a new PropertyValue without any metadata..
+     * @param key the key, not {@code null}.
+     * @param value the value.
+     * @param source the source, typically the name of the {@link 
PropertySource}
+     *               providing the value, not  {@code null}.
+     * @return a new property value instance, or {@code null},
+     *         if the value passed is {@code null}..
+     */
+    public static PropertyValue of(String key, String value, String source) {
+        if (value==null) {
+            return null;
+        }
+        return new PropertyValue(key, value, source);
+    }
+
+    /**
+     * Access the given key from this value. Valid keys are the key or any 
meta-context key.
+     * @param key the key, not {@code null}.
+     * @return the value found, or {@code null}.
+     */
+    public String getMetaEntry(String key) {
+        return this.metaEntries.get(Objects.requireNonNull(key));
+    }
+
+    /**
+     * Creates a new builder instance based on this item.
+     * @return a new builder, never null.
+     */
+    public PropertyValueBuilder toBuilder() {
+        return new PropertyValueBuilder(this.getKey(), this.getSource())
+                .setValue(this.getValue())
+        .setMetaEntries(this.metaEntries);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PropertyValue)) return false;
+        PropertyValue that = (PropertyValue) o;
+        return Objects.equals(getKey(), that.getKey()) &&
+                Objects.equals(getValue(), that.getValue()) &&
+                Objects.equals(getSource(), that.getSource()) &&
+                Objects.equals(getMetaEntries(), that.getMetaEntries());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getKey(), getValue(), getSource(),
+                getMetaEntries());
+    }
+
+    @Override
+    public String toString() {
+        return "PropertyValue{" +
+                "key='" + key + '\'' +
+                ", value='" + value + '\'' +
+                ", source='" + source + '\'' +
+                (metaEntries.isEmpty()?"":", metaEntries=" + metaEntries) +
+                '}';
+    }
+
+    /**
+     * Maps a map of {@code Map<String,String>} to a {@code 
Map<String,PropertyValue>}.
+     * @param config the String based map, not {@code null}.
+     * @param source the source name, not {@code null}.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,PropertyValue> map(Map<String, String> config, 
String source) {
+        Map<String,PropertyValue> result = new HashMap<>(config.size());
+        for(Map.Entry<String,String> en:config.entrySet()){
+            result.put(en.getKey(), PropertyValue.of(en.getKey(), 
en.getValue(), source));
+        }
+        return result;
+    }
+
+    /**
+     * Maps a map of {@code Map<String,String>} to a {@code 
Map<String,PropertyValue>}.
+     *
+     * @param config the String based map, not {@code null}.
+     * @param source the source name, not {@code null}.
+     * @param metaData additional metadata, not {@code null}.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,PropertyValue> map(Map<String, String> config, 
String source,
+                                                Map<String,String> metaData) {
+        Objects.requireNonNull(config, "Config must be given.");
+        Objects.requireNonNull(source, "Source must be given.");
+        Objects.requireNonNull(metaData, "Meta data must be given.");
+
+        Map<String,PropertyValue> result = new HashMap<>(config.size());
+
+        for(Map.Entry<String,String> en:config.entrySet()){
+            PropertyValue value = new PropertyValueBuilder(en.getKey(), 
source).setValue(en.getValue())
+                                                                               
.addMetaEntries(metaData).build();
+            result.put(en.getKey(), value);
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java 
b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
new file mode 100644
index 0000000..af01987
--- /dev/null
+++ b/code/old/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Builder to create a {@link PropertyValue} instance.
+ */
+public class PropertyValueBuilder {
+    /** The key accessed. */
+    String key;
+    /** The property value. */
+    String value;
+    /** The property vaoue source. */
+    String source;
+    /** additional metadata entries (optional). */
+    Map<String,String> metaEntries = new HashMap<>();
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
+     * Before calling build at least a {@link #value} and its {@link #source}
+     * must be set.
+     */
+    PropertyValueBuilder(String key){
+        this.key = Objects.requireNonNull(key);
+    }
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
+     * @param key to access a property value, not  {@code null}.
+     * @param source property source.
+     */
+    PropertyValueBuilder(String key, String source) {
+        this.key = Objects.requireNonNull(key);
+        this.source = Objects.requireNonNull(source);
+    }
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
+     *
+     * @param key to access a property value.
+     * @param value the value, not {@code null}. If a value is  {@code null}
+     *              {@link PropertySource#get(String)} should return {@code 
null}.
+     * @param source property source.
+     */
+    PropertyValueBuilder(String key, String value, String source) {
+        this.key = Objects.requireNonNull(key);
+        this.value = value;
+        this.source = Objects.requireNonNull(source);
+    }
+
+    /**
+     * Replaces/sets the context data.
+     * @param metaEntries the context data to be applied, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setMetaEntries(Map<String, String> 
metaEntries) {
+        this.metaEntries.clear();
+        this.metaEntries.putAll(metaEntries);
+        return this;
+    }
+
+    /**
+     * Add an additional context data information.
+     * @param key the context data key, not {@code null}.
+     * @param value the context value, not {@code null} (will be converted to 
String).
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder addMetaEntry(String key, Object value) {
+        Objects.requireNonNull(key, "Meta key must be given.");
+        Objects.requireNonNull(value, "Meta value must be given.");
+
+        this.metaEntries.put(key, String.valueOf(value));
+        return this;
+    }
+
+    /**
+     * Adds the context data given.
+     * @param metaEntries the context data to be applied, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder addMetaEntries(Map<String, String> 
metaEntries) {
+        this.metaEntries.putAll(metaEntries);
+        return this;
+    }
+
+    /**
+     * Removes a meta entry.
+     * @param key the entry's key, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder removeMetaEntry(String key) {
+        Objects.requireNonNull(key, "Key must be given.");
+
+        this.metaEntries.remove(key);
+        return this;
+    }
+
+    /**
+     * Get the value's context data.
+     * @return the context data, not {@code null}.
+     */
+    public Map<String,String> getMetaEntries() {
+        return Collections.unmodifiableMap(this.metaEntries);
+    }
+
+    /**
+     * Changes the entry's key, mapping also corresponding context entries.
+     * @param key the new key, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder mapKey(String key) {
+        // todo obf if (1==1) throw new RuntimeException("No tests written.");
+        Map<String,String> newContext = new HashMap<>();
+        for(Map.Entry<String,String> en:this.metaEntries.entrySet()){
+            if(en.getKey().startsWith("_"+this.key)){
+                newContext.put("_"+key+'.'+ 
en.getKey().substring(this.key.length()+1), en.getValue());
+            }else{
+                newContext.put(en.getKey(), en.getValue());
+            }
+        }
+        this.metaEntries = newContext;
+        this.key = key;
+        return this;
+    }
+
+    /**
+     * Sets a new key.
+     * @param key the new key, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setKey(String key) {
+        this.key = Objects.requireNonNull(key);
+        return this;
+    }
+
+    /**
+     * Sets a new value.
+     * @param value the new value, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setValue(String value) {
+        this.value = Objects.requireNonNull(value, "Value must be given.");
+
+        return this;
+    }
+
+    /**
+     * Sets a new source.
+     * @param source the new source, not {@code null}.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setSource(String source) {
+        // todo obf if (1==1) throw new RuntimeException("No tests written.");
+        this.source = Objects.requireNonNull(source);
+        return this;
+    }
+
+    /**
+     * Creates a new immutable {@link PropertyValue}.
+     * @return a new immutable {@link PropertyValue}, never {@code null}.
+     */
+    public PropertyValue build(){
+        return new PropertyValue(this);
+    }
+
+    @Override
+    public String toString() {
+        return "PropertyValueBuilder{" +
+                "key='" + key + '\'' +
+                "value='" + value + '\'' +
+                ", metaEntries=" + metaEntries +
+                '}';
+    }
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java 
b/code/old/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
new file mode 100644
index 0000000..9eb18e8
--- /dev/null
+++ b/code/old/api/src/main/java/org/apache/tamaya/spi/ServiceContext.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.spi;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.List;
+
+
+/**
+ * This class models the component that is managing the lifecycle current the
+ * services used by the Configuration API.
+ */
+public interface ServiceContext {
+
+    /**
+     * @return ordinal of the ServiceContext. The one with the highest ordinal 
will be taken.
+     */
+    int ordinal();
+
+    /**
+     * Access a service singleton via its type.
+     * If multiple implementations for the very serviceType exist then
+     * the one with the highest {@link javax.annotation.Priority} will be used.
+     *
+     * @param <T> the type of the service type.
+     * @param serviceType the service type.
+     * @return The instance to be used, or {@code null}
+     * @throws org.apache.tamaya.ConfigException if there are multiple service 
implementations with the maximum priority.
+     */
+    <T> T getService(Class<T> serviceType);
+
+    /**
+     * Factory method to create a type, hereby a new instance is created on 
each access.
+     * If multiple implementations for the very serviceType exist then
+     * the one with the highest {@link javax.annotation.Priority} will be used 
as the base
+     * for creating subsequent instances.
+     *
+     * @param <T> the type of the service type.
+     * @param serviceType the service type.
+     * @return The new instance to be used, or {@code null}
+     * @throws org.apache.tamaya.ConfigException if there are multiple service 
implementations with the maximum priority.
+     */
+    <T> T create(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 <T> the type of the list element returned by this method
+     * @return The instance to be used, never {@code null}
+     */
+     <T> List<T> getServices(Class<T> serviceType);
+
+    /**
+     * Loads resources from the current runtime context. This method allows to 
use runtime
+     * specific code to load resources, e.g. within OSGI environments.
+     * @param resource the resource, not {@code null}.
+     * @param cl the desired classloader context, if null, the current thread 
context classloader is used.
+     * @return the resources found
+     * @throws IOException if load fails.
+     */
+    Enumeration<URL> getResources(String resource, ClassLoader cl) throws 
IOException;
+
+    /**
+     * Loads a resource from the current runtime context. This method allows 
to use runtime
+     * specific code to load a resource, e.g. within OSGI environments.
+     * @param resource the resource, not {@code null}.
+     * @param cl the desired classloader context, if null, the current thread 
context classloader is used.
+     * @return the resource found, or {@code null}.
+     */
+    URL getResource(String resource, ClassLoader cl);
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/9bc56a38/code/old/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
----------------------------------------------------------------------
diff --git 
a/code/old/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java 
b/code/old/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
new file mode 100644
index 0000000..f58c27a
--- /dev/null
+++ 
b/code/old/api/src/main/java/org/apache/tamaya/spi/ServiceContextManager.java
@@ -0,0 +1,118 @@
+/*
+ * 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.Objects;
+import java.util.ServiceLoader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.ConfigException;
+
+
+/**
+ * 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.
+ */
+public final class ServiceContextManager {
+
+    /** The logger used. */
+    private static final Logger LOG = 
Logger.getLogger(ServiceContextManager.class.getName());
+
+    /**
+     * The ServiceProvider used.
+     */
+    private static volatile ServiceContext serviceContextProviderDelegate;
+
+    /**
+     * 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() {
+        ServiceContext highestServiceContext = null;
+        try {
+            int highestOrdinal = 0;
+            for (ServiceContext serviceContext : 
ServiceLoader.load(ServiceContext.class)) {
+                if(highestServiceContext==null){
+                    highestServiceContext = serviceContext;
+                }else if (serviceContext.ordinal() > highestOrdinal) {
+                    highestServiceContext = serviceContext;
+                    highestOrdinal = serviceContext.ordinal();
+                }
+            }
+        } catch (Exception e) {
+            throw new ConfigException("ServiceContext not loadable", e);
+        }
+        if (highestServiceContext==null){
+            throw new ConfigException("No ServiceContext found");
+        }
+        LOG.info("Using Service Context of type: " + 
highestServiceContext.getClass().getName());
+        return highestServiceContext;
+    }
+
+    /**
+     * Replace the current {@link ServiceContext} in use.
+     *
+     * @param serviceContextProvider the new {@link ServiceContext}, not 
{@code null}.
+     * @return the currently used context after setting it.
+     */
+    public static ServiceContext set(ServiceContext serviceContextProvider) {
+        Objects.requireNonNull(serviceContextProvider);
+        ServiceContext currentContext = 
ServiceContextManager.serviceContextProviderDelegate;
+
+        synchronized (ServiceContextManager.class) {
+            if (ServiceContextManager.serviceContextProviderDelegate == null) {
+                ServiceContextManager.serviceContextProviderDelegate = 
serviceContextProvider;
+                LOG.log(Level.INFO, "Using ServiceProvider: " + 
serviceContextProvider.getClass().getName());
+            } else {
+                LOG.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 (ServiceContextManager.class) {
+                if (serviceContextProviderDelegate == null) {
+                    serviceContextProviderDelegate = 
loadDefaultServiceProvider();
+                }
+            }
+        }
+        return serviceContextProviderDelegate;
+    }
+
+}

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

Reply via email to