tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ple...@apache.org
Subject [01/23] incubator-tamaya-sandbox git commit: TAMAYA 111: Add Classloader aware ServiceContext.
Date Sun, 25 Sep 2016 21:35:41 GMT
Repository: incubator-tamaya-sandbox
Updated Branches:
  refs/heads/master 7acfa8070 -> 30633b6e6


TAMAYA 111: Add Classloader aware ServiceContext.


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

Branch: refs/heads/master
Commit: 9c922df1e01f232848ede24e5cb448a9b3297f94
Parents: 
Author: anatole <anatole@apache.org>
Authored: Fri Sep 25 20:23:06 2015 +0200
Committer: anatole <anatole@apache.org>
Committed: Fri Sep 25 20:23:06 2015 +0200

----------------------------------------------------------------------
 pom.xml                                         |  53 +++
 .../AbstractClassloaderAwareItemLoader.java     | 267 ++++++++++++
 .../internal/CLAwareConfigurationContext.java   | 106 +++++
 .../internal/CLAwareServiceContext.java         | 224 ++++++++++
 .../clsupport/internal/ServiceContainer.java    | 311 +++++++++++++
 .../ctx/DefaultConfigurationContext.java        | 256 +++++++++++
 .../clsupport/internal/ctx/EnumConverter.java   |  67 +++
 .../internal/ctx/PropertyConverterManager.java  | 434 +++++++++++++++++++
 .../tamaya/clsupport/internal/package-info.java |  22 +
 .../apache/tamaya/clsupport/package-info.java   |  22 +
 .../tamaya/clsupport/spi/package-info.java      |  22 +
 .../org.apache.tamaya.spi.ServiceContext        |  19 +
 ...he.tamaya.environment.spi.ContextProviderSpi |  23 +
 ...org.apache.tamaya.environment.spi.ContextSpi |  19 +
 14 files changed, 1845 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4aef40b
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,53 @@
+<!-- 
+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 current 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.tamaya.ext</groupId>
+        <artifactId>tamaya-extensions</artifactId>
+        <version>0.2-incubating-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <artifactId>tamaya-classloader-support</artifactId>
+    <name>Apache Tamaya Modules -Classloader Support</name>
+    <description>Apache Tamaya Classloader Support registers a ConfigurationContext that leverages
+    classloader hierarchies. Also visibility of features and components is aligned with the
+    corresponding hierarchy of classloaders.</description>
+    <packaging>jar</packaging>
+
+    <properties>
+        <jdkVersion>1.7</jdkVersion>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-java7-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java b/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.java
new file mode 100644
index 0000000..0c90653
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/AbstractClassloaderAwareItemLoader.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.clsupport;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * This class implements an abstract base class, which basically provides a loading mechanism that supports
+ * loading and managing resources along the classloader hierarchies individually. It ensures resources are loaded
+ * and stored related to the each target classloader within the hierarchy individually. Additionally it enables
+ * mechanisms to ensure an item T is not loaded multiple times, when traversing up the classloader hierarchy.<p/>
+ * Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * Instead this class uses the fully qualified class name of the loader and the corresponsing hashCode as returned
+ * by {@link Objects#hashCode(Object)}.
+ * @param <T> the managed item type.
+ */
+public abstract class AbstractClassloaderAwareItemLoader<T> {
+    /**
+     * The logger used.
+     */
+    private static final Logger LOG = Logger.getLogger(AbstractClassloaderAwareItemLoader.class.getName());
+    /**
+     * The items managed, related to their classloader.
+     */
+    private Map<String, T> items = new ConcurrentHashMap<>();
+
+    /**
+     * Creates a new instance, using the current Thread context classloader, or - if null - the classloader that
+     * loaded this class for initially initializing the loader instance.
+     */
+    public AbstractClassloaderAwareItemLoader() {
+        this(getDefaultClassLoader());
+    }
+
+    /**
+     * Creates a new instance, using the class loader given for initializing the resources loaded.
+     *
+     * @param classLoader the target top level classloader, not null.
+     */
+    public AbstractClassloaderAwareItemLoader(ClassLoader classLoader) {
+        loadItems(classLoader);
+    }
+
+    /**
+     * Loads the items for the given classloader and all its parent classloaders. This method will not update
+     * the items already found for any class loader involved.
+     *
+     * @param classLoader the target top level classloader, not null.
+     */
+    public void loadItems(ClassLoader classLoader) {
+        loadItems(classLoader, false);
+    }
+
+    /**
+     * Loads the items for the given classloader and all its parent classloaders.
+     *
+     * @param classLoader the target top level classloader, not null.
+     * @param update      if set to true, resources not visible on former runs are added during this load.
+     */
+    public void loadItems(ClassLoader classLoader, boolean update) {
+        this.items.clear();
+        List<ClassLoader> cls = new ArrayList<>();
+        cls.add(classLoader);
+        ClassLoader cl = classLoader.getParent();
+        while (cl != null) {
+            cls.add(cl);
+            cl = cl.getParent();
+        }
+        // Start with the parent classloader and then go up...
+        for (int i = cls.size() - 1; i <= 0; i--) {
+            ClassLoader curCL = cls.get(i);
+            String clKey = getClassLoaderID(curCL);
+            T itemFound = items.get(clKey);
+            try {
+                if (itemFound != null) {
+                    updateItem(itemFound, curCL);
+                } else {
+                    items.put(clKey, createItem(curCL));
+                }
+            } catch (Exception e) {
+                LOG.log(Level.SEVERE,
+                        "Error loading from classloader: " + curCL, e);
+            }
+        }
+    }
+
+    /**
+     * Creates a new item for being stored linked with the given lassloader.
+     *
+     * @param classLoader the classloader, not null.
+     * @return
+     */
+    protected abstract T createItem(ClassLoader classLoader);
+
+    /**
+     * Creates a new item for being stored linked with the given lassloader.
+     *
+     * @param currentItemSet the current found ItemContainer instance to be updated.
+     * @param classLoader    the classloader, not null.
+     * @return
+     */
+    protected abstract void updateItem(T currentItemSet, ClassLoader classLoader);
+
+    /**
+     * Evaluates a String key for identfying a classloader instance, based on the loader class and its hashCode.
+     * This prevents the storage of classloader references as keys and therefore enables classloaders not used anymore
+     * to be garbage collected.
+     *
+     * @param classLoader
+     * @return the unique key for the given classloader
+     */
+    public static String getClassLoaderID(ClassLoader classLoader) {
+        return classLoader.getClass().getName() + Objects.hash(classLoader);
+    }
+
+    /**
+     * Evaluates a String key for identfying a classloader instance, based on the loader class and its hashCode.
+     * This prevents the storage of classloader references as keys and therefore enables classloaders not used anymore
+     * to be garbage collected.
+     *
+     * @return the unique key for the current default classloader as returned by #getDefaultClassLoader.
+     */
+    public static String getClassLoaderID() {
+        return getClassLoaderID(getDefaultClassLoader());
+    }
+
+    /**
+     * Get all items valid for the current thread context class loader, or - if null - the classloader that loaded
+     * this class.
+     *
+     * @return the items found, never null.
+     */
+    public Set<T> getItems() {
+        return getItems(getDefaultClassLoader());
+    }
+
+    /**
+     * Get all items found for the given classloader and all its parent classloaders.
+     *
+     * @param classLoader the target top level classloader, not null.
+     * @return the items found, never null.
+     */
+    public Set<T> getItems(ClassLoader classLoader) {
+        Set<T> result = new HashSet<>();
+        ClassLoader cl = classLoader;
+        while (cl != null) {
+            T item = getItemNoParent(cl, true);
+            result.add(item);
+            cl = cl.getParent();
+        }
+        return result;
+    }
+
+    /**
+     * Get all items valid for the parent class loader of the current thread context class loader, or - if null - the
+     * parent of the classloader that loaded this class. This allows
+     * to build a delta list of instances only visible on the target classloader given.
+     *
+     * @return the items found, never null.
+     */
+    public Set<T> getParentItems() {
+        return getParentItems(getDefaultClassLoader());
+    }
+
+    /**
+     * Get all items found for the parent of the given classloader and all its parent classloaders. This allows
+     * to build a delta list of instances only visible on the target classloader given.
+     *
+     * @param classLoader the target top level classloader, not null.
+     * @return the items found, never null.
+     */
+    public Set<T> getParentItems(ClassLoader classLoader) {
+        Set<T> result = new HashSet<>();
+        ClassLoader cl = classLoader.getParent();
+        while (cl != null) {
+            T item = getItemNoParent(cl, true);
+            result.add(item);
+            cl = cl.getParent();
+        }
+        return result;
+    }
+
+    /**
+     * Return the item assigned to the current thread context class loader or - if null - the class that loaded
+     * this class. If not yet loaded this method will NOT trigger a load.
+     *
+     * @return the item attached, or null.
+     */
+    public T getItemNoParent() {
+        return getItemNoParent(getDefaultClassLoader(), false);
+    }
+
+    /**
+     * Return the item assigned to the current thread context class loader or - if null - the class that loaded
+     * this class.
+     *
+     * @param loadIfMissing Flag that allows to define if this method will trigger an item load, when no item is loaded
+     *                      for the current class loader.
+     * @return the item attached, or null.
+     */
+    public T getItemNoParent(boolean loadIfMissing) {
+        return getItemNoParent(getDefaultClassLoader(), loadIfMissing);
+    }
+
+    /**
+     * Return the item assigned to the current thread context class loader or - if null - the class that loaded
+     * this class.
+     *
+     * @param classLoader   the target top level classloader, not null.
+     * @param loadIfMissing Flag that allows to define if this method will trigger an item load, when no item is loaded
+     *                      for the current class loader.
+     * @return the item attached, or null. If {@code loadIfMissing} is set to true, the result is normally not to be
+     * expected to be null.
+     */
+    public T getItemNoParent(ClassLoader classLoader, boolean loadIfMissing) {
+        String clKey = getClassLoaderID(classLoader);
+        T item = items.get(clKey);
+        if (item == null) {
+            if (loadIfMissing) {
+                item = createItem(classLoader);
+                this.items.put(clKey, item);
+            }
+        }
+        return item;
+    }
+
+
+    /**
+     * Utility method that either returns the current thread context classloader or
+     * - if not available - the classloader that loaded this class.
+     * @return the default classloader to be used, if no explicit classloader has been passed.
+     */
+    public static ClassLoader getDefaultClassLoader() {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if (cl == null) {
+            cl = AbstractClassloaderAwareItemLoader.class.getClassLoader();
+        }
+        return cl;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
new file mode 100644
index 0000000..8575393
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareConfigurationContext.java
@@ -0,0 +1,106 @@
+/*
+ * 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.clsupport.internal;
+
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.clsupport.AbstractClassloaderAwareItemLoader;
+import org.apache.tamaya.clsupport.internal.ctx.DefaultConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+
+import javax.annotation.Priority;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+@Priority(100)
+public class CLAwareConfigurationContext implements ConfigurationContext {
+
+    /** The logger used. */
+    private final static Logger LOG = Logger.getLogger(CLAwareConfigurationContext.class.getName());
+
+    private ContextManager contextManager = new ContextManager();
+
+
+    @Override
+    public void addPropertySources(PropertySource... propertySourcesToAdd) {
+        contextManager.getItemNoParent(true).addPropertySources(propertySourcesToAdd);
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return contextManager.getItemNoParent(true).getPropertySources();
+    }
+
+    @Override
+    public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+        contextManager.getItemNoParent(true).addPropertyConverter(typeToConvert, propertyConverter);
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+        return contextManager.getItemNoParent(true).getPropertyConverters();
+    }
+
+    @Override
+    public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+        return contextManager.getItemNoParent(true).getPropertyConverters(targetType);
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return contextManager.getItemNoParent(true).getPropertyFilters();
+    }
+
+    @Override
+    public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+        return contextManager.getItemNoParent(true).getPropertyValueCombinationPolicy();
+    }
+
+    @Override
+    public ConfigurationContextBuilder toBuilder() {
+        return contextManager.getItemNoParent(true).toBuilder();
+    }
+
+
+    /**
+     * Subcomponent managing {@link ConfigurationContext} instances, one per classloader.
+     */
+    private static final class ContextManager extends AbstractClassloaderAwareItemLoader<ConfigurationContext>{
+
+        @Override
+        protected ConfigurationContext createItem(ClassLoader classLoader) {
+            // Simply create a complete configuration manager for every classloader. Maybe we will optimize this at a
+            // later stage in the project but as for now it is the most simple working solution.
+            return new DefaultConfigurationContext();
+        }
+
+        @Override
+        protected void updateItem(ConfigurationContext currentItemSet, ClassLoader classLoader) {
+            // ignore, currently not supported.
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
new file mode 100644
index 0000000..c023cff
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/CLAwareServiceContext.java
@@ -0,0 +1,224 @@
+/*
+ * 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.clsupport.internal;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.clsupport.AbstractClassloaderAwareItemLoader;
+import org.apache.tamaya.spi.ServiceContext;
+
+import javax.annotation.Priority;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used
+ * by the {@link java.util.ServiceLoader}. Whereas the {@link java.util.ServiceLoader} only loads configurations
+ * and instances from one classloader, this loader manages configs found and the related instances for each
+ * classloader along the classloader hierarchies individually. It ensures instances are loaded on the classloader
+ * level, where they first are visible. Additionally it ensures the same configuration resource (and its
+ * declared services) are loaded multiple times, when going up the classloader hierarchy.<p/>
+ * Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected.
+ * Refer also the inherited parent class for further details.<p/>
+ * This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations
+ * provided with the Tamaya core modules.
+ */
+@Priority(10)
+public class CLAwareServiceContext extends AbstractClassloaderAwareItemLoader<ServiceContainer>
+        implements ServiceContext{
+    /**
+     * Default location for service loader files.
+     */
+    private static final String PREFIX = "META-INF/services/";
+
+    /**
+     * Constructor, using the current default classloader as defined by
+     * {@link AbstractClassloaderAwareItemLoader#getDefaultClassLoader()}.
+     */
+    public CLAwareServiceContext(){
+        super();
+    }
+
+    /**
+     * Constructor, using the given classloader.
+     * @param classLoader the target classloader for initializing of services, not null.
+     */
+    public CLAwareServiceContext(ClassLoader classLoader) {
+        super(classLoader);
+    }
+
+
+    /**
+     * Implementation that creates a {@link ServiceContainer}, which manages all configs and instances loaded
+     * for a given classloader.
+     * @param classLoader the classloader, not null.
+     * @return a new empty, {@link ServiceContainer} instance.
+     */
+    @Override
+    protected ServiceContainer createItem(ClassLoader classLoader) {
+        return new ServiceContainer(classLoader);
+    }
+
+    @Override
+    protected void updateItem(ServiceContainer currentContainer, ClassLoader classLoader) {
+        // nothing to be done here, since we dont have a specific target type.
+    }
+
+    @Override
+    public int ordinal() {
+        return 10;
+    }
+
+    /**
+     * This method tries to evaluate the current singleton from the {@link ServiceContainer} attached to the
+     * current classloader. If not found the singleton instance is evaluated based on the priorities
+     * assigned for all known providers. The resulting instance is then cached and always returned as
+     * singleton instance fomr this loader, when the same current classloader instance is active.
+     * @param serviceType the service type.
+     * @param <T> the type
+     * @return the item found, or null.
+     */
+    @Override
+    public <T> T getService(Class<T> serviceType) {
+        return getService(serviceType, getDefaultClassLoader());
+    }
+
+    /**
+     * Evaluates the current singleton instance using the given classloader context.
+     * @param serviceType the service type.
+     * @param classLoader the classloader, not null.
+     * @param <T> the type
+     * @return the item found, or null.
+     */
+    public <T> T getService(Class<T> serviceType, ClassLoader classLoader) {
+        ServiceContainer container = getItemNoParent(classLoader, true);
+        T singleton = container.getSingleton(serviceType);
+        if(singleton!=null){
+            return singleton;
+        }
+        Collection<? extends T> services = getServices(serviceType, classLoader);
+        if (services.isEmpty()) {
+            singleton = null;
+        } else {
+            singleton = getServiceWithHighestPriority(services, serviceType);
+        }
+        if(singleton!=null) {
+            container.setSingleton(serviceType, singleton);
+        }
+        return singleton;
+    }
+
+    /**
+     * Gets the services visible.
+     * @param serviceType
+     *            the service type.
+     * @param <T> the type param
+     * @return the services visible for the current classloader.
+     */
+    @Override
+    public <T> List<T> getServices(Class<T> serviceType) {
+        return getServices(serviceType, AbstractClassloaderAwareItemLoader.getDefaultClassLoader());
+    }
+
+    /**
+     * Gets the services visible.
+     * @param serviceType the service type.
+     * @param classLoader the classloader
+     * @param <T> the type param
+     * @return the services visible for the current classloader.
+     */
+    public <T> List<T> getServices(Class<T> serviceType, ClassLoader classLoader) {
+        List<T> services = new ArrayList<>();
+        ClassLoader cl = classLoader;
+        List<ServiceContainer> containers = new ArrayList<>();
+        while(cl!=null) {
+            ServiceContainer container = getItemNoParent(cl, true);
+            containers.add(container);
+            cl = cl.getParent();
+        }
+        List<ServiceContainer> prevContainers = new ArrayList<>();
+        Collections.reverse(containers);
+        for(ServiceContainer container: containers) {
+            if (!container.isTypeLoaded(serviceType)) {
+                container.loadServices(serviceType, prevContainers);
+            }
+            services.addAll(container.getServices(serviceType));
+            prevContainers.add(container);
+        }
+        return services;
+    }
+
+    /**
+     * @param services to scan
+     * @param <T>      type of the service
+     *
+     * @return the service with the highest {@link javax.annotation.Priority#value()}
+     *
+     * @throws ConfigException if there are multiple service implementations with the maximum priority
+     */
+    private <T> T getServiceWithHighestPriority(Collection<? extends T> services, Class<T> serviceType) {
+
+        // we do not need the priority stuff if the list contains only one element
+        if (services.size() == 1) {
+            return services.iterator().next();
+        }
+
+        Integer highestPriority = null;
+        int highestPriorityServiceCount = 0;
+        T highestService = null;
+
+        for (T service : services) {
+            int prio = getPriority(service);
+            if (highestPriority == null || highestPriority < prio) {
+                highestService = service;
+                highestPriorityServiceCount = 1;
+                highestPriority = prio;
+            } else if (highestPriority == prio) {
+                highestPriorityServiceCount++;
+            }
+        }
+        if (highestPriorityServiceCount > 1) {
+            throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}",
+                    highestPriorityServiceCount,
+                    serviceType.getName(),
+                    highestPriority,
+                    services));
+        }
+        return highestService;
+    }
+
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+     * annotation is present, a default priority is returned (1);
+     * @param o the instance, not null.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o){
+        int prio = 0;
+        Priority priority = o.getClass().getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java b/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
new file mode 100644
index 0000000..713b292
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/ServiceContainer.java
@@ -0,0 +1,311 @@
+/*
+ * 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.clsupport.internal;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceConfigurationError;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Created by Anatole on 08.09.2015.
+ */
+class ServiceContainer {
+
+    private static final Logger LOG = Logger.getLogger(ServiceContainer.class.getName());
+
+    private static final String PREFIX = "META-INF/services/";
+
+    // The access control context taken when the ServiceLoader is created
+    private final AccessControlContext acc;
+
+    private WeakReference<ClassLoader> classLoaderRef;
+
+    /**
+     * List current services loaded using this classloader, per class.
+     */
+    private final Map<Class<?>, Map<String, Object>> servicesLoaded = new ConcurrentHashMap<>();
+    /**
+     * The cached singletons for the given classloader.
+     */
+    private final Map<Class, Object> singletons = new ConcurrentHashMap<>();
+
+    /**
+     * List current services loaded using this classloader, per class.
+     */
+    private final Map<Class, List<URL>> configsLoaded = new ConcurrentHashMap<>();
+
+    ServiceContainer(ClassLoader classLoader) {
+        acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
+        this.classLoaderRef = new WeakReference<>(classLoader);
+    }
+
+    public ClassLoader getClassLoader() {
+        ClassLoader cl = classLoaderRef.get();
+        if (cl == null) {
+            throw new IllegalStateException("Classloader reference removed, not active anynire.");
+        }
+        return cl;
+    }
+
+
+    public <T> void loadServices(Class<?> type,
+                                 Collection<ServiceContainer> preceedingContainers) {
+        Map<String, Object> services = (Map<String, Object>) this.servicesLoaded.get(type);
+        if (services == null) {
+            services = new LinkedHashMap<>();
+            this.servicesLoaded.put(type, services);
+        }
+        loop:
+        for (URL config : getConfigs(type)) {
+            for (ServiceContainer cont : preceedingContainers) {
+                if (cont.getConfigs(type).contains(config)) {
+                    LOG.finer("Ignoring already loaded config: " + config);
+                    continue loop;
+                }
+            }
+            Collection<String> serviceNames = parse(type, config);
+            for (String s : serviceNames) {
+                for (ServiceContainer cont : preceedingContainers) {
+                    if (cont.containsService(type, s)) {
+                        LOG.finest("Ignoring duplicate service: " + s);
+                        continue;
+                    }
+                }
+                LOG.info("Loading component: " + s);
+                services.put(s, create(type, s));
+            }
+        }
+    }
+
+    private Collection<URL> getConfigs(Class<?> type) {
+        List<URL> result = this.configsLoaded.get(type);
+        if (result == null) {
+            ClassLoader cl = this.classLoaderRef.get();
+            if (cl == null) {
+                throw new IllegalStateException("CLassLoader dereferenced already.");
+            }
+            result = new ArrayList<>();
+            try {
+                Enumeration<URL> resources = cl.getResources(PREFIX + type.getName());
+                while (resources.hasMoreElements()) {
+                    result.add(resources.nextElement());
+                }
+            } catch (Exception e) {
+                LOG.log(Level.WARNING, "Failed to read service config for " + type.getName() + " from " + cl, e);
+            }
+            this.configsLoaded.put(type, result);
+            LOG.log(Level.FINE, "Found service config for " + type.getName() + ": " + result);
+        }
+        return result;
+    }
+
+    private boolean containsService(Class<?> type, String serviceClassName) {
+        Map<String, Object> services = servicesLoaded.get(type);
+        if (services == null) {
+            return false;
+        }
+        return services.containsKey(serviceClassName);
+    }
+
+
+    private <S> S create(Class<S> serviceType, String className) {
+        Class<?> c = null;
+        ClassLoader classLoader = getClassLoader();
+        try {
+            c = Class.forName(className, false, classLoader);
+        } catch (ClassNotFoundException x) {
+            fail(serviceType,
+                    "Provider " + className + " not found");
+        }
+        if (!serviceType.isAssignableFrom(c)) {
+            fail(serviceType,
+                    "Provider " + className + " not a subtype");
+        }
+        try {
+            S p = serviceType.cast(c.newInstance());
+            return p;
+        } catch (Throwable x) {
+            fail(serviceType,
+                    "Provider " + className + " could not be instantiated",
+                    x);
+        }
+        throw new Error();          // This cannot happen
+    }
+
+    public <T> Collection<T> getServices(Class<T> serviceType) {
+        Map<String, Object> services = this.servicesLoaded.get(serviceType);
+        if (services != null) {
+            return (Collection<T>) services.values();
+        }
+        return Collections.emptySet();
+    }
+
+    public boolean isTypeLoaded(Class<?> serviceType) {
+        return this.servicesLoaded.containsKey(serviceType);
+    }
+
+    public Collection<URL> load(Class<?> serviceType) {
+        return load(serviceType, Collection.class.cast(Collections.emptySet()));
+    }
+
+    public Collection<URL> load(Class<?> serviceType, Collection<URL> configsLoaded) {
+        List<URL> result = new ArrayList<>();
+        try {
+            Enumeration<URL> resources = getClassLoader().getResources(PREFIX + serviceType.getName());
+            while (resources.hasMoreElements()) {
+                URL res = resources.nextElement();
+                if (!configsLoaded.contains(res)) {
+                    result.add(res);
+                }
+            }
+            return result;
+        } catch (Exception e) {
+            fail(serviceType, "Failed to load service config: " + PREFIX + serviceType.getName(), e);
+        }
+        return result;
+    }
+
+
+    // Parse a single line from the given configuration file, adding the name
+    // on the line to the names list.
+    //
+    private int parseLine(Class<?> serviceType, URL u, BufferedReader r, int lc,
+                          List<String> names)
+            throws IOException, ServiceConfigurationError {
+        String ln = r.readLine();
+        if (ln == null) {
+            return -1;
+        }
+        int ci = ln.indexOf('#');
+        if (ci >= 0) {
+            ln = ln.substring(0, ci);
+        }
+        ln = ln.trim();
+        int n = ln.length();
+        if (n != 0) {
+            if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
+                fail(serviceType, u, lc, "Illegal configuration-file syntax");
+            }
+            int cp = ln.codePointAt(0);
+            if (!Character.isJavaIdentifierStart(cp)) {
+                fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
+            }
+            for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
+                cp = ln.codePointAt(i);
+                if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
+                    fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
+                }
+            }
+            Map<String, Object> services = this.servicesLoaded.get(serviceType);
+            if (services == null || !services.containsKey(ln) && !names.contains(ln)) {
+                names.add(ln);
+            }
+        }
+        return lc + 1;
+    }
+
+
+    // Parse the content of the given URL as a provider-configuration file.
+    //
+    // @param  service
+    //         The service type for which providers are being sought;
+    //         used to construct error detail strings
+    //
+    // @param  u
+    //         The URL naming the configuration file to be parsed
+    //
+    // @return A (possibly empty) iterator that will yield the provider-class
+    //         names in the given configuration file that are not yet members
+    //         of the returned set
+    //
+    // @throws ServiceConfigurationError
+    //         If an I/O error occurs while reading from the given URL, or
+    //         if a configuration-file format error is detected
+    //
+    private Collection<String> parse(Class<?> service, URL u)
+            throws ServiceConfigurationError {
+        InputStream in = null;
+        BufferedReader r = null;
+        ArrayList<String> names = new ArrayList<>();
+        try {
+            in = u.openStream();
+            r = new BufferedReader(new InputStreamReader(in, "utf-8"));
+            int lc = 1;
+            while ((lc = parseLine(service, u, r, lc, names)) >= 0) {
+                // go ahead
+            }
+        } catch (IOException x) {
+            fail(service, "Error reading configuration file", x);
+        } finally {
+            try {
+                if (r != null) {
+                    r.close();
+                }
+                if (in != null) {
+                    in.close();
+                }
+            } catch (IOException y) {
+                fail(service, "Error closing configuration file", y);
+            }
+        }
+        return names;
+    }
+
+
+    private static void fail(Class<?> service, String msg, Throwable cause)
+            throws ServiceConfigurationError {
+        LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg, cause);
+    }
+
+    private static void fail(Class<?> service, String msg)
+            throws ServiceConfigurationError {
+        LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg);
+    }
+
+    private static void fail(Class<?> service, URL u, int line, String msg)
+            throws ServiceConfigurationError {
+        fail(service, u + ":" + line + ": " + msg);
+    }
+
+    public <T> T getSingleton(Class<T> serviceType) {
+        return (T) this.singletons.get(serviceType);
+    }
+
+    <T> void setSingleton(Class<T> type, T instance) {
+        LOG.info("Caching singleton for " + type.getName() + " and classloader: " +
+                getClassLoader().toString() + ": " + instance);
+        this.singletons.put(type, instance);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
new file mode 100644
index 0000000..978dbb7
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/DefaultConfigurationContext.java
@@ -0,0 +1,256 @@
+/*
+ * 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.clsupport.internal.ctx;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.annotation.Priority;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+public class DefaultConfigurationContext implements ConfigurationContext {
+    /** The logger used. */
+    private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName());
+    /**
+     * Cubcomponent handling {@link PropertyConverter} instances.
+     */
+    private PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
+
+    /**
+     * The current unmodifiable list of loaded {@link PropertySource} instances.
+     */
+    private List<PropertySource> immutablePropertySources;
+
+    /**
+     * The current unmodifiable list of loaded {@link PropertyFilter} instances.
+     */
+    private List<PropertyFilter> immutablePropertyFilters;
+
+    /**
+     * The overriding policy used when combining PropertySources registered to evalute the final configuration
+     * values.
+     */
+    private PropertyValueCombinationPolicy propertyValueCombinationPolicy;
+
+    /**
+     * Lock for internal synchronization.
+     */
+    private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
+
+    /** Comparator used for ordering property sources. */
+    private final PropertySourceComparator propertySourceComparator = new PropertySourceComparator();
+
+    /** Comparator used for ordering property filters. */
+    private final PropertyFilterComparator propertyFilterComparator = new PropertyFilterComparator();
+
+
+    /**
+     * The first time the Configuration system gets invoked we do initialize
+     * all our {@link PropertySource}s and
+     * {@link PropertyFilter}s which are known at startup.
+     */
+    public DefaultConfigurationContext() {
+        List<PropertySource> propertySources = new ArrayList<>();
+
+        // first we load all PropertySources which got registered via java.util.ServiceLoader
+        propertySources.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class));
+
+        // after that we add all PropertySources which get dynamically registered via their PropertySourceProviders
+        propertySources.addAll(evaluatePropertySourcesFromProviders());
+
+        // now sort them according to their ordinal values
+        Collections.sort(propertySources, new PropertySourceComparator());
+
+        immutablePropertySources = Collections.unmodifiableList(propertySources);
+        LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
+                immutablePropertySources);
+
+        // as next step we pick up the PropertyFilters pretty much the same way
+        List<PropertyFilter> propertyFilters = new ArrayList<>();
+        propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
+        Collections.sort(propertyFilters, new PropertyFilterComparator());
+        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+        LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+                immutablePropertyFilters);
+
+        immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+        LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+                immutablePropertyFilters);
+        propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+        if(propertyValueCombinationPolicy==null) {
+            propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+        }
+        LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+    }
+
+    /**
+     * Pick up all {@link PropertySourceProvider}s and return all the
+     * {@link PropertySource}s they like to register.
+     */
+    private Collection<? extends PropertySource> evaluatePropertySourcesFromProviders() {
+        List<PropertySource> propertySources = new ArrayList<>();
+        Collection<PropertySourceProvider> propertySourceProviders = ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class);
+        for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
+            Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
+            LOG.finer("PropertySourceProvider " + propertySourceProvider.getClass().getName() +
+                    " provided the following property sources: " + sources);
+                propertySources.addAll(sources);
+        }
+
+        return propertySources;
+    }
+
+    @Override
+    public void addPropertySources(PropertySource... propertySourcesToAdd) {
+        Lock writeLock = propertySourceLock.writeLock();
+        try {
+            writeLock.lock();
+            List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources);
+            newPropertySources.addAll(Arrays.asList(propertySourcesToAdd));
+            Collections.sort(newPropertySources, new PropertySourceComparator());
+
+            this.immutablePropertySources = Collections.unmodifiableList(newPropertySources);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Comparator used for comparing PropertySources.
+     */
+    private static class PropertySourceComparator implements Comparator<PropertySource>, Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * Order property source reversely, the most important come first.
+         *
+         * @param source1 the first PropertySource
+         * @param source2 the second PropertySource
+         * @return the comparison result.
+         */
+        private int comparePropertySources(PropertySource source1, PropertySource source2) {
+            if (source1.getOrdinal() < source2.getOrdinal()) {
+                return -1;
+            } else if (source1.getOrdinal() > source2.getOrdinal()) {
+                return 1;
+            } else {
+                return source1.getClass().getName().compareTo(source2.getClass().getName());
+            }
+        }
+
+        @Override
+        public int compare(PropertySource source1, PropertySource source2) {
+            return comparePropertySources(source1, source2);
+        }
+    }
+
+    /**
+     * Comparator used for comparing PropertyFilters.
+     */
+    private static class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable{
+
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * Compare 2 filters for ordering the filter chain.
+         *
+         * @param filter1 the first filter
+         * @param filter2 the second filter
+         * @return the comparison result
+         */
+        private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) {
+            Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
+            Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
+            int ord1 = prio1 != null ? prio1.value() : 0;
+            int ord2 = prio2 != null ? prio2.value() : 0;
+
+            if (ord1 < ord2) {
+                return -1;
+            } else if (ord1 > ord2) {
+                return 1;
+            } else {
+                return filter1.getClass().getName().compareTo(filter2.getClass().getName());
+            }
+        }
+
+        @Override
+        public int compare(PropertyFilter filter1, PropertyFilter filter2) {
+            return comparePropertyFilters(filter1, filter2);
+        }
+    }
+
+    @Override
+    public List<PropertySource> getPropertySources() {
+        return immutablePropertySources;
+    }
+
+    @Override
+    public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+        propertyConverterManager.register(typeToConvert, propertyConverter);
+        LOG.info("Added PropertyConverter: " + propertyConverter.getClass().getName());
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+        return propertyConverterManager.getPropertyConverters();
+    }
+
+    @Override
+    public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+        return propertyConverterManager.getPropertyConverters(targetType);
+    }
+
+    @Override
+    public List<PropertyFilter> getPropertyFilters() {
+        return immutablePropertyFilters;
+    }
+
+    @Override
+    public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+        return propertyValueCombinationPolicy;
+    }
+
+    @Override
+    public ConfigurationContextBuilder toBuilder() {
+        return ConfigurationProvider.getConfigurationContextBuilder().setContext(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
new file mode 100644
index 0000000..a75de75
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/EnumConverter.java
@@ -0,0 +1,67 @@
+/*
+ * 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.clsupport.internal.ctx;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to tge given enum type.
+ * @param <T> the enum type.
+ */
+class EnumConverter<T> implements PropertyConverter<T> {
+    private Logger LOG = Logger.getLogger(EnumConverter.class.getName());
+    private Class<T> enumType;
+    private Method factory;
+
+    public EnumConverter(Class<T> enumType) {
+        if (!Enum.class.isAssignableFrom(enumType)) {
+            throw new IllegalArgumentException("Not an Enum: " + enumType.getName());
+        }
+        this.enumType = Objects.requireNonNull(enumType);
+        try {
+            this.factory = enumType.getMethod("valueOf", String.class);
+        } catch (NoSuchMethodException e) {
+            throw new ConfigException("Uncovertible enum type without valueOf method found, please provide a custom " +
+                    "PropertyConverter for: " + enumType.getName());
+        }
+    }
+
+    @Override
+    public T convert(String value) {
+        try {
+            return (T) factory.invoke(null, value);
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+        }
+        try {
+            return (T) factory.invoke(null, value.toUpperCase(Locale.ENGLISH));
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
new file mode 100644
index 0000000..848fe78
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/internal/ctx/PropertyConverterManager.java
@@ -0,0 +1,434 @@
+/*
+ * 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.clsupport.internal.ctx;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.annotation.Priority;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+/**
+ * Manager that deals with {@link PropertyConverter} instances.
+ * This class is thread-safe.
+ */
+class PropertyConverterManager {
+    /**
+     * The logger used.
+     */
+    private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName());
+    /**
+     * The registered converters.
+     */
+    private Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>();
+    /**
+     * The transitive converters.
+     */
+    private Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>();
+    /**
+     * The lock used.
+     */
+    private ReadWriteLock lock = new ReentrantReadWriteLock();
+
+    private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() {
+
+        @Override
+        public int compare(Object o1, Object o2) {
+            int prio = getPriority(o1) - getPriority(o2);
+            if (prio < 0) {
+                return 1;
+            } else if (prio > 0) {
+                return -1;
+            } else {
+                return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+            }
+        }
+    };
+
+    /**
+     * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such
+     * annotation is present, a default priority is returned (1);
+     * @param o the instance, not null.
+     * @return a priority, by default 1.
+     */
+    public static int getPriority(Object o){
+        int prio = 1;
+        Priority priority = o.getClass().getAnnotation(Priority.class);
+        if (priority != null) {
+            prio = priority.value();
+        }
+        return prio;
+    }
+
+    /**
+     * Constructor.
+     */
+    public PropertyConverterManager() {
+        this(true);
+    }
+
+    public PropertyConverterManager(boolean init) {
+        if (init) {
+            initConverters();
+        }
+    }
+
+    /**
+     * Registers the default converters provided out of the box.
+     */
+    protected void initConverters() {
+        for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(PropertyConverter.class)) {
+            Type type = TypeLiteral.getGenericInterfaceTypeParameters(conv.getClass(), PropertyConverter.class)[0];
+            register(TypeLiteral.of(type), conv);
+        }
+    }
+
+    /**
+     * Registers a ew converter instance.
+     *
+     * @param targetType the target type, not null.
+     * @param converter  the converter, not null.
+     * @param <T>        the type.
+     */
+    public <T> void register(TypeLiteral<T> targetType, PropertyConverter<T> converter) {
+        Objects.requireNonNull(converter);
+        Lock writeLock = lock.writeLock();
+        try {
+            writeLock.lock();
+            List converters = List.class.cast(this.converters.get(targetType));
+            List<PropertyConverter<?>> newConverters = new ArrayList<>();
+            if (converters != null) {
+                newConverters.addAll(converters);
+            }
+            newConverters.add(converter);
+            Collections.sort(newConverters, PRIORITY_COMPARATOR);
+            this.converters.put(targetType, Collections.unmodifiableList(newConverters));
+            // evaluate transitive closure for all inherited supertypes and implemented interfaces
+            // direct implemented interfaces
+            for (Class<?> ifaceType : targetType.getRawType().getInterfaces()) {
+                converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType)));
+                newConverters = new ArrayList<>();
+                if (converters != null) {
+                    newConverters.addAll(converters);
+                }
+                newConverters.add(converter);
+                Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+            }
+            Class<?> superClass = targetType.getRawType().getSuperclass();
+            while (superClass != null && !superClass.equals(Object.class)) {
+                converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(superClass)));
+                newConverters = new ArrayList<>();
+                if (converters != null) {
+                    newConverters.addAll(converters);
+                }
+                newConverters.add(converter);
+                Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                this.transitiveConverters.put(TypeLiteral.of(superClass), Collections.unmodifiableList(newConverters));
+                for (Class<?> ifaceType : superClass.getInterfaces()) {
+                    converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType)));
+                    newConverters = new ArrayList<>();
+                    if (converters != null) {
+                        newConverters.addAll(converters);
+                    }
+                    newConverters.add(converter);
+                    Collections.sort(newConverters, PRIORITY_COMPARATOR);
+                    this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+                }
+                superClass = superClass.getSuperclass();
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Allows to evaluate if a given target type is supported.
+     *
+     * @param targetType the target type, not null.
+     * @return true, if a converter for the given type is registered, or a default one can be created.
+     */
+    public boolean isTargetTypeSupported(TypeLiteral<?> targetType) {
+        if (converters.containsKey(targetType) || transitiveConverters.containsKey(targetType)) {
+            return true;
+        }
+        return createDefaultPropertyConverter(targetType) != null;
+    }
+
+    /**
+     * Get a map of all property converters currently registered. This will not contain the converters that
+     * may be created, when an instance is adapted, which provides a String constructor or compatible
+     * factory methods taking a single String instance.
+     *
+     * @return the current map of instantiated and registered converters.
+     * @see #createDefaultPropertyConverter(TypeLiteral)
+     */
+    public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+        Lock readLock = lock.readLock();
+        try {
+            readLock.lock();
+            return new HashMap<>(this.converters);
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * Get the list of all current registered converters for the given target type.
+     * If not converters are registered, they component tries to create and register a dynamic
+     * converter based on String costructor or static factory methods available.<br/>
+     * The converters provided are of the following type and returned in the following order:
+     * <ul>
+     *     <li>Converters mapped explicitly to the required target type are returned first, ordered
+     *     by decreasing priority. This means, if explicit converters are registered these are used
+     *     primarly for converting a value.</li>
+     *     <li>The target type of each explicitly registered converter also can be transitively mapped to
+     *     1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces
+     *     implemented by its superclasses. These groups of transitive converters is returned similarly in the
+     *     order as mentioned, whereas also here a priority based decreasing ordering is applied.</li>
+     *     <li>java.lang wrapper classes and native types are automatically mapped.</li>
+     *     <li>If no explicit converters are registered, for Enum types a default implementation is provided that
+     *     compares the configuration values with the different enum members defined (cases sensitive mapping).</li>
+     * </ul>
+     *
+     * So given that list above directly registered mappings always are tried first, before any transitive mapping
+     * should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place.
+     * Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and
+     * the inheritance hierarchy (exception Object). Superinterfaces of implemented interfaces are ignored.
+     *
+     *
+     * @param targetType the target type, not null.
+     * @param <T>        the type class
+     * @return the ordered list of converters (may be empty for not convertible types).
+     * @see #createDefaultPropertyConverter(TypeLiteral)
+     */
+    public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+        Lock readLock = lock.readLock();
+        List<PropertyConverter<T>> converterList = new ArrayList<>();
+        List<PropertyConverter<T>> converters;
+        // direct mapped converters
+        try {
+            readLock.lock();
+            converters = List.class.cast(this.converters.get(targetType));
+        } finally {
+            readLock.unlock();
+        }
+        if (converters != null) {
+            converterList.addAll(converters);
+        }
+        // transitive converter
+        try {
+            readLock.lock();
+            converters = List.class.cast(this.transitiveConverters.get(targetType));
+        } finally {
+            readLock.unlock();
+        }
+        if (converters != null) {
+            converterList.addAll(converters);
+        }
+        // handling of java.lang wrapper classes
+        TypeLiteral<T> boxedType = mapBoxedType(targetType);
+        if (boxedType != null) {
+            try {
+                readLock.lock();
+                converters = List.class.cast(this.converters.get(boxedType));
+            } finally {
+                readLock.unlock();
+            }
+            if (converters != null) {
+                converterList.addAll(converters);
+            }
+        }
+        if (converterList.isEmpty()) {
+            // adding any converters created on the fly, e.g. for enum types.
+            PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
+            if (defaultConverter != null) {
+                register(targetType, defaultConverter);
+                try {
+                    readLock.lock();
+                    converters = List.class.cast(this.converters.get(targetType));
+                } finally {
+                    readLock.unlock();
+                }
+            }
+            if (converters != null) {
+                converterList.addAll(converters);
+            }
+        }
+        return converterList;
+    }
+
+    /**
+     * Maps native types to the corresponding boxed types.
+     *
+     * @param targetType the native type.
+     * @param <T>        the type
+     * @return the boxed type, or null.
+     */
+    private <T> TypeLiteral<T> mapBoxedType(TypeLiteral<T> targetType) {
+        Type parameterType = targetType.getType();
+        if (parameterType == int.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Integer.class));
+        }
+        if (parameterType == short.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Short.class));
+        }
+        if (parameterType == byte.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Byte.class));
+        }
+        if (parameterType == long.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Long.class));
+        }
+        if (parameterType == boolean.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
+        }
+        if (parameterType == char.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Character.class));
+        }
+        if (parameterType == float.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Float.class));
+        }
+        if (parameterType == double.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Double.class));
+        }
+        if (parameterType == int[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Integer[].class));
+        }
+        if (parameterType == short[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Short[].class));
+        }
+        if (parameterType == byte[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Byte[].class));
+        }
+        if (parameterType == long[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Long[].class));
+        }
+        if (parameterType == boolean.class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
+        }
+        if (parameterType == char[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Character[].class));
+        }
+        if (parameterType == float[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Float[].class));
+        }
+        if (parameterType == double[].class) {
+            return TypeLiteral.class.cast(TypeLiteral.of(Double[].class));
+        }
+        return null;
+    }
+
+    /**
+     * Creates a dynamic PropertyConverter for the given target type.
+     *
+     * @param targetType the target type
+     * @param <T>        the type class
+     * @return a new converter, or null.
+     */
+    protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) {
+        if (Enum.class.isAssignableFrom(targetType.getRawType())) {
+            return new EnumConverter<T>(targetType.getRawType());
+        }
+        PropertyConverter<T> converter = null;
+        final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse");
+        if (factoryMethod != null) {
+            converter = new PropertyConverter<T>() {
+                @Override
+                public T convert(String value) {
+                    try {
+                        if (!Modifier.isStatic(factoryMethod.getModifiers())) {
+                            throw new ConfigException(factoryMethod.toGenericString() +
+                                    " is not a static method. Only static " +
+                                    "methods can be used as factory methods.");
+                        }
+                        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                            public Object run() {
+                                factoryMethod.setAccessible(true);
+                                return null;
+                            }
+                        });
+                        Object invoke = factoryMethod.invoke(null, value);
+                        return targetType.getRawType().cast(invoke);
+                    } catch (Exception e) {
+                        throw new ConfigException("Failed to decode '" + value + "'", e);
+                    }
+                }
+            };
+        }
+        if (converter == null) {
+            try {
+                final Constructor<T> constr = targetType.getRawType().getDeclaredConstructor(String.class);
+                converter = new PropertyConverter<T>() {
+                    @Override
+                    public T convert(String value) {
+                        try {
+                            constr.setAccessible(true);
+                            return constr.newInstance(value);
+                        } catch (Exception e) {
+                            throw new ConfigException("Failed to decode '" + value + "'", e);
+                        }
+                    }
+                };
+            } catch (Exception e) {
+                LOG.finest("Failed to construct instance of type: " + targetType.getRawType().getName() + ": " + e);
+            }
+        }
+        return converter;
+    }
+
+    /**
+     * Tries to evaluate a factory method that can be used to create an instance based on a String.
+     *
+     * @param type        the target type
+     * @param methodNames the possible static method names
+     * @return the first method found, or null.
+     */
+    private Method getFactoryMethod(Class<?> type, String... methodNames) {
+        Method m;
+        for (String name : methodNames) {
+            try {
+                m = type.getDeclaredMethod(name, String.class);
+                return m;
+            } catch (NoSuchMethodException | RuntimeException e) {
+                LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name);
+            }
+        }
+        return null;
+    }
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/package-info.java b/src/main/java/org/apache/tamaya/clsupport/package-info.java
new file mode 100644
index 0000000..d8e3953
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * Programmatic API of the classloader support.
+ */
+package org.apache.tamaya.clsupport;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java b/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
new file mode 100644
index 0000000..6eb85d3
--- /dev/null
+++ b/src/main/java/org/apache/tamaya/clsupport/spi/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * Defines the SPI of the classloader support module.
+ */
+package org.apache.tamaya.clsupport.spi;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
new file mode 100644
index 0000000..c3b6acd
--- /dev/null
+++ b/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.clsupport.internal.CLAwareServiceContext

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
----------------------------------------------------------------------
diff --git a/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi b/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
new file mode 100644
index 0000000..7f71c15
--- /dev/null
+++ b/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current 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.
+#
+org.apache.tamaya.environment.internal.ClassLoaderDependentAppEnvironmentProvider
+org.apache.tamaya.environment.internal.ClassLoaderDependentEarEnvironmentProvider
+org.apache.tamaya.environment.internal.InitialEnvironmentProviderSpi
+org.apache.tamaya.environment.internal.SystemClassLoaderEnvironmentProviderSpi
+org.apache.tamaya.metamodel.environment.TestEnvironmentProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/9c922df1/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
----------------------------------------------------------------------
diff --git a/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi b/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
new file mode 100644
index 0000000..166dd67
--- /dev/null
+++ b/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
@@ -0,0 +1,19 @@
+#
+# 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 current 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.
+#
+org.apache.tamaya.environment.internal.SingleEnvironmentManager


Mime
View raw message