http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
----------------------------------------------------------------------
diff --git 
a/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java 
b/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
index d044982..43c6248 100644
--- a/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
+++ b/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
@@ -36,53 +36,54 @@ public class TestConfigServiceSingletonSpi implements 
ConfigurationManagerSingle
 
     public TestConfigServiceSingletonSpi(){
         Map<String,String> config = new HashMap<>();
-        config.put("a.b.c.key1", "value current a.b.c.key1");
-        config.put("a.b.c.key2", "value current a.b.c.key2");
-        config.put("a.b.key3", "value current a.b.key3");
-        config.put("a.b.key4", "value current a.b.key4");
-        config.put("a.key5", "value current a.key5");
-        config.put("a.key6", "value current a.key6");
+        config.put("a.b.c.key1", "keys current a.b.c.key1");
+        config.put("a.b.c.key2", "keys current a.b.c.key2");
+        config.put("a.b.key3", "keys current a.b.key3");
+        config.put("a.b.key4", "keys current a.b.key4");
+        config.put("a.key5", "keys current a.key5");
+        config.put("a.key6", "keys current a.key6");
         config.put("int1", "123456");
         config.put("int2", "111222");
         config.put("booleanT", "true");
         config.put("double1", "1234.5678");
         config.put("BD", 
"123456789123456789123456789123456789.123456789123456789123456789123456789");
-        config.put("testProperty", "value current testProperty");
+        config.put("testProperty", "keys current testProperty");
         config.put("runtimeVersion", "${java.version}");
         // configs.put("test", new 
MapConfiguration(MetaInfoBuilder.current().setName("test").build(), config));
     }
 
+
+
     @Override
     public boolean isConfigurationDefined(String name){
         return configs.containsKey(name);
     }
 
     @Override
-    public <T> T getConfiguration(String name, Class<T> type){
-        if(type.equals(Configuration.class)) {
-            Configuration config = configs.get(name);
-            return (T)Optional.ofNullable(config).orElseThrow(() -> new 
ConfigException("No such config: " + name));
-        }
-        throw new ConfigException("Not such config name="+name+", type="+ 
type.getName());
+    public Configuration getConfiguration(String name) {
+        // TODO
+        throw new UnsupportedOperationException("Not yet implemented");
     }
 
     @Override
-    public <T> T getConfiguration(Class<T> type) {
+    public <T> T createTemplate(Class<T> type, Configuration... 
configurations) {
         // TODO
         throw new UnsupportedOperationException("Not yet implemented");
     }
 
     @Override
-    public void configure(Object instance) {
+    public void configure(Object instance, Configuration... configurations) {
         // TODO
         throw new UnsupportedOperationException("Not yet implemented");
     }
 
     @Override
-    public String evaluateValue(Configuration config, String expression){
+    public String evaluateValue(String expression, Configuration... 
configurations) {
         // TODO improve this ugly implementation...
-        for(Map.Entry<String, String> en: config.toMap().entrySet()){
-            expression = expression.replaceAll("\\$\\{"+en.getKey()+"\\}", 
en.getValue());
+        for (Configuration config : configurations) {
+            for (Map.Entry<String, String> en : config.toMap().entrySet()) {
+                expression = expression.replaceAll("\\$\\{" + en.getKey() + 
"\\}", en.getValue());
+            }
         }
         return expression;
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/api/src/test/java/org/apache/tamaya/TestPropertyAdaptersSingletonSpi.java
----------------------------------------------------------------------
diff --git 
a/api/src/test/java/org/apache/tamaya/TestPropertyAdaptersSingletonSpi.java 
b/api/src/test/java/org/apache/tamaya/TestPropertyAdaptersSingletonSpi.java
index 2d3cfbc..b05c356 100644
--- a/api/src/test/java/org/apache/tamaya/TestPropertyAdaptersSingletonSpi.java
+++ b/api/src/test/java/org/apache/tamaya/TestPropertyAdaptersSingletonSpi.java
@@ -18,8 +18,9 @@
  */
 package org.apache.tamaya;
 
-import org.apache.tamaya.annotation.WithPropertyAdapter;
-import org.apache.tamaya.spi.PropertyAdaptersSingletonSpi;
+import org.apache.tamaya.annotation.WithCodec;
+import org.apache.tamaya.spi.CodecsSingletonSpi;
+
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.time.LocalDate;
@@ -32,66 +33,66 @@ import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * Test implementation current {@link PropertyAdaptersSingletonSpi}, which 
provides adapters
+ * Test implementation current {@link 
org.apache.tamaya.spi.CodecsSingletonSpi}, which provides codecs
  * for some basic types.
  */
-public final class TestPropertyAdaptersSingletonSpi implements 
PropertyAdaptersSingletonSpi{
+public final class TestPropertyAdaptersSingletonSpi implements 
CodecsSingletonSpi {
 
-    private Map<Class, PropertyAdapter<?>> adapters = new 
ConcurrentHashMap<>();
+    private Map<Class, Codec<?>> codecs = new ConcurrentHashMap<>();
 
     private TestPropertyAdaptersSingletonSpi(){
-        register(char.class, (s) -> s.charAt(0));
-        register(int.class, Integer::parseInt);
-        register(byte.class, Byte::parseByte);
-        register(short.class, Short::parseShort);
-        register(boolean.class, Boolean::parseBoolean);
-        register(float.class, Float::parseFloat);
-        register(double.class, Double::parseDouble);
+        register(char.class, (s) -> s.charAt(0), (ch) -> String.valueOf(ch));
+        register(int.class, Integer::parseInt, Object::toString);
+        register(byte.class, Byte::parseByte, Object::toString);
+        register(short.class, Short::parseShort, Object::toString);
+        register(boolean.class, Boolean::parseBoolean, b -> String.valueOf(b));
+        register(float.class, Float::parseFloat, f -> String.valueOf(f));
+        register(double.class, Double::parseDouble, d -> String.valueOf(d));
 
-        register(Character.class, (s) -> s.charAt(0));
-        register(Integer.class, Integer::parseInt);
-        register(Byte.class, Byte::parseByte);
-        register(Short.class, Short::parseShort);
-        register(Boolean.class, Boolean::parseBoolean);
-        register(Float.class, Float::parseFloat);
-        register(Double.class, Double::parseDouble);
-        register(BigDecimal.class, BigDecimal::new);
-        register(BigInteger.class, BigInteger::new);
+        register(Character.class, (s) -> s.charAt(0), Object::toString);
+        register(Integer.class, Integer::valueOf, Object::toString);
+        register(Byte.class, Byte::valueOf, Object::toString);
+        register(Short.class, Short::valueOf, String::valueOf);
+        register(Boolean.class, Boolean::valueOf, String::valueOf);
+        register(Float.class, Float::valueOf, String::valueOf);
+        register(Double.class, Double::valueOf, String::valueOf);
+        register(BigDecimal.class, BigDecimal::new, String::valueOf);
+        register(BigInteger.class, BigInteger::new, String::valueOf);
 
-        register(Currency.class, Currency::getInstance);
+        register(Currency.class, Currency::getInstance, Object::toString);
 
-        register(LocalDate.class, LocalDate::parse);
-        register(LocalTime.class, LocalTime::parse);
-        register(LocalDateTime.class, LocalDateTime::parse);
-        register(ZoneId.class, ZoneId::of);
+        register(LocalDate.class, LocalDate::parse, Object::toString);
+        register(LocalTime.class, LocalTime::parse, Object::toString);
+        register(LocalDateTime.class, LocalDateTime::parse, Object::toString);
+        register(ZoneId.class, ZoneId::of, ZoneId::getId);
     }
 
 
     @Override
-    public <T> PropertyAdapter<T> register(Class<T> targetType, 
PropertyAdapter<T> adapter){
+    public <T> Codec<T> register(Class<T> targetType, Codec<T> codec){
         Objects.requireNonNull(targetType);
-        Objects.requireNonNull(adapter);
-        return (PropertyAdapter<T>)adapters.put(targetType, adapter);
+        Objects.requireNonNull(codec);
+        return (Codec<T>) codecs.put(targetType, codec);
     }
 
     @Override
-    public <T> PropertyAdapter<T> getAdapter(Class<T> targetType, 
WithPropertyAdapter annotation){
+    public <T> Codec<T> getCodec(Class<T> targetType, WithCodec annotation){
         if(annotation!=null){
             Class<?> adapterType = annotation.value();
-            if(!adapterType.equals(PropertyAdapter.class)){
+            if(!adapterType.equals(Codec.class)){
                 try{
-                    return (PropertyAdapter<T>)adapterType.newInstance();
+                    return (Codec<T>)adapterType.newInstance();
                 }
                 catch(Exception e){
                     throw new ConfigException("Failed to load PropertyAdapter: 
" + adapterType, e);
                 }
             }
         }
-        return (PropertyAdapter<T>) adapters.get(targetType);
+        return (Codec<T>) codecs.get(targetType);
     }
 
     @Override
     public boolean isTargetTypeSupported(Class<?> targetType){
-        return adapters.containsKey(targetType);
+        return codecs.containsKey(targetType);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.CodecsSingletonSpi
----------------------------------------------------------------------
diff --git 
a/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.CodecsSingletonSpi
 
b/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.CodecsSingletonSpi
new file mode 100644
index 0000000..e9b04b4
--- /dev/null
+++ 
b/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.CodecsSingletonSpi
@@ -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.TestPropertyAdaptersSingletonSpi

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyAdaptersSingletonSpi
----------------------------------------------------------------------
diff --git 
a/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyAdaptersSingletonSpi
 
b/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyAdaptersSingletonSpi
deleted file mode 100644
index e9b04b4..0000000
--- 
a/api/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertyAdaptersSingletonSpi
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy 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.TestPropertyAdaptersSingletonSpi

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java 
b/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
index cfd0da3..836db3f 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/config/AbstractConfiguration.java
@@ -48,10 +48,10 @@ public abstract class AbstractConfiguration extends 
AbstractPropertySource imple
     @Override
     public <T> Optional<T> get(String key, Class<T> type){
         AdapterProviderSpi as = 
ServiceContext.getInstance().getSingleton(AdapterProviderSpi.class);
-        PropertyAdapter<T> adapter = as.getAdapter(type);
+        Codec<T> adapter = as.getAdapter(type);
         if(adapter == null){
             throw new ConfigException(
-                    "Can not adapt config property '" + key + "' to " + 
type.getName() + ": no such " +
+                    "Can not deserialize config property '" + key + "' to " + 
type.getName() + ": no such " +
                             "adapter.");
         }
         return getAdapted(key, adapter);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java 
b/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
index c9d924f..ddd83e2 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/ConfigFunctions.java
@@ -132,7 +132,7 @@ public final class ConfigFunctions {
     /**
      * Creates a {@link UnaryOperator} that creates a {@link 
org.apache.tamaya.Configuration} that maps any keys as
      * defined by the {@code keyMapper} given. If the {@code keyMapper} returns
-     * {@code null} for a value, it is removed from the resulting map.
+     * {@code null} for a keys, it is removed from the resulting map.
      *
      * @param keyMapper the key mapper, not null
      * @return the area configuration, with the areaKey stripped away.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java 
b/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java
index 3355e6b..176cc38 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/ConfigurationBuilder.java
@@ -108,7 +108,7 @@ public final class ConfigurationBuilder {
 
     /**
      * Sets the aggregation policy to be used, when adding additional property 
sets. The policy will
-     * be active a slong as the builder is used or it is reset to another 
value.
+     * be active a slong as the builder is used or it is reset to another keys.
      *
      * @param aggregationPolicy the aggregation policy, not null.
      * @return the builder for chaining.
@@ -341,7 +341,7 @@ public final class ConfigurationBuilder {
      * created.
      *
      * @param key the key to be added, not null.
-     * @param value the value to be added, not null.
+     * @param value the keys to be added, not null.
      * @return this builder for chaining
      */
     public ConfigurationBuilder setMeta(String key, String value){

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java 
b/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java
index 24c715e..8d1207f 100644
--- a/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java
+++ b/core/src/main/java/org/apache/tamaya/core/config/MappedConfiguration.java
@@ -3,8 +3,6 @@ package org.apache.tamaya.core.config;
 import org.apache.tamaya.*;
 
 import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 
 /**
@@ -46,8 +44,8 @@ class MappedConfiguration extends AbstractConfiguration 
implements Configuration
     }
 
     @Override
-    public void apply(ConfigChangeSet change) {
-        this.config.apply(change);
+    public void applyChanges(ConfigChangeSet change) {
+        this.config.applyChanges(change);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/env/EnvironmentBuilder.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/env/EnvironmentBuilder.java 
b/core/src/main/java/org/apache/tamaya/core/env/EnvironmentBuilder.java
index 7445430..895ac76 100644
--- a/core/src/main/java/org/apache/tamaya/core/env/EnvironmentBuilder.java
+++ b/core/src/main/java/org/apache/tamaya/core/env/EnvironmentBuilder.java
@@ -52,7 +52,7 @@ public final class EnvironmentBuilder{
     /**
      * Sets a new environment property.
      * @param key the key, not null.
-     * @param value the value, not null.
+     * @param value the keys, not null.
      * @return the builder for chaining
      */
     public EnvironmentBuilder set(String key, String value){

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/Utils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/Utils.java 
b/core/src/main/java/org/apache/tamaya/core/internal/Utils.java
index 6990de2..0089b8f 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/Utils.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/Utils.java
@@ -57,7 +57,7 @@ public final class Utils {
         if(containerAnnot!=null){
             Method valueMethod;
             try {
-                valueMethod = annotationContainer.getMethod("value");
+                valueMethod = annotationContainer.getMethod("keys");
                 
result.addAll(Arrays.asList((T[])valueMethod.invoke(containerAnnot)));
             } catch (Exception e) {
                 LOG.log(Level.SEVERE, "Failed to evaluate repeatable 
annotation.", e);
@@ -90,7 +90,7 @@ public final class Utils {
         if(containerAnnot!=null){
             Method valueMethod;
             try {
-                valueMethod = annotationContainer.getMethod("value");
+                valueMethod = annotationContainer.getMethod("keys");
                 
result.addAll(Arrays.asList((T[])valueMethod.invoke(containerAnnot)));
             } catch (Exception e) {
                 LOG.log(Level.SEVERE, "Failed to evaluate repeatable 
annotation.", e);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/config/ConfigTemplateInvocationHandler.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/config/ConfigTemplateInvocationHandler.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/config/ConfigTemplateInvocationHandler.java
deleted file mode 100644
index 18e9d03..0000000
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/config/ConfigTemplateInvocationHandler.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.core.internal.config;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.core.internal.inject.ConfiguredType;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.util.Objects;
-
-/**
- * Invocation handler that handles request against a configuration template.
- */
-class ConfigTemplateInvocationHandler implements InvocationHandler {
-    /** The underlying configuration. */
-    private Configuration config;
-    /** The configured type. */
-    private ConfiguredType type;
-
-    public ConfigTemplateInvocationHandler(Class<?> type, Configuration 
config) {
-        this.config = Objects.requireNonNull(config);
-        this.type = new ConfiguredType(Objects.requireNonNull(type));
-        if(!type.isInterface()){
-            throw new IllegalArgumentException("Can only proxy interfaces as 
configuration templates.");
-        }
-    }
-
-    @Override
-    public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable {
-        if("toString".equals(method.getName())){
-            return "Configured Proxy -> " + this.type.getType().getName();
-        }
-        return this.type.getConfiguredValue(method, args);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
index 1a04cef..e3e0bba 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
@@ -20,6 +20,7 @@ package org.apache.tamaya.core.internal.config;
 
 import org.apache.tamaya.*;
 import org.apache.tamaya.core.internal.el.DefaultExpressionEvaluator;
+import org.apache.tamaya.core.internal.inject.ConfigTemplateInvocationHandler;
 import org.apache.tamaya.core.internal.inject.ConfigurationInjector;
 import org.apache.tamaya.core.properties.PropertySourceBuilder;
 import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
@@ -64,43 +65,21 @@ public class DefaultConfigurationManagerSingletonSpi 
implements ConfigurationMan
     }
 
     @Override
-    public <T> T getConfiguration(String name, Class<T> type) {
-        ConfigurationProviderSpi provider = configProviders.get(name);
-        if (provider == null) {
-            if (DEFAULT_CONFIG_NAME.equals(name)) {
-                provider = new FallbackSimpleConfigProvider();
-                configProviders.put(DEFAULT_CONFIG_NAME, provider);
-            } else {
-                throw new ConfigException("No such config: " + name);
-            }
-        }
-        Configuration config = provider.getConfiguration();
-        if (config == null) {
-            throw new ConfigException("No such config: " + name);
-        }
-        if (Configuration.class.equals(type)) {
-            return (T) config;
-        }
-        return createAdapterProxy(config, type);
+    public <T> T createTemplate(Class<T> type, Configuration... 
configurations) {
+        ClassLoader cl = Optional.ofNullable(Thread.currentThread()
+                .getContextClassLoader()).orElse(getClass().getClassLoader());
+        return (T) Proxy.newProxyInstance(cl, new Class[]{type}, new 
ConfigTemplateInvocationHandler(type, configurations));
     }
 
     /**
-     * Creates a proxy implementing the given target interface.
      *
-     * @param config the configuration to be used for providing values.
-     * @param type   the target interface.
-     * @param <T>    the target interface type.
-     * @return the corresponding implementing proxy, never null.
+     * @param instance the instance with configuration annotations, not null.
+     * @param configurations the configurations to be used for evaluating the 
values for injection into {@code instance}.
+     *                If no items are passed, the default configuration is 
used.
      */
-    private <T> T createAdapterProxy(Configuration config, Class<T> type) {
-        ClassLoader cl = Optional.ofNullable(Thread.currentThread()
-                .getContextClassLoader()).orElse(getClass().getClassLoader());
-        return (T) Proxy.newProxyInstance(cl, new Class[]{type}, new 
ConfigTemplateInvocationHandler(type, config));
-    }
-
     @Override
-    public void configure(Object instance) {
-        ConfigurationInjector.configure(instance);
+    public void configure(Object instance, Configuration... configurations) {
+        ConfigurationInjector.configure(instance, configurations);
     }
 
     private String getConfigId(Annotation... qualifiers) {
@@ -119,8 +98,8 @@ public class DefaultConfigurationManagerSingletonSpi 
implements ConfigurationMan
     }
 
     @Override
-    public String evaluateValue(Configuration config, String expression) {
-        return expressionEvaluator.evaluate(expression);
+    public String evaluateValue(String expression, Configuration... 
configurations) {
+        return expressionEvaluator.evaluate(expression, configurations);
     }
 
     @Override
@@ -162,9 +141,34 @@ public class DefaultConfigurationManagerSingletonSpi 
implements ConfigurationMan
         return spi != null;
     }
 
+    @Override
+    public Configuration getConfiguration(String name) {
+        ConfigurationProviderSpi provider = configProviders.get(name);
+        if (provider == null) {
+            if (DEFAULT_CONFIG_NAME.equals(name)) {
+                provider = new FallbackSimpleConfigProvider();
+                configProviders.put(DEFAULT_CONFIG_NAME, provider);
+            } else {
+                throw new ConfigException("No such config: " + name);
+            }
+        }
+        Configuration config = provider.getConfiguration();
+        if (config == null) {
+            throw new ConfigException("No such config: " + name);
+        }
+        return config;
+    }
+
     /**
      * Implementation of a default config provider used as fallback, if no 
{@link org.apache.tamaya.core.spi.ConfigurationProviderSpi}
-     * instance is registered for providing the {@code default} {@link 
org.apache.tamaya.Configuration}.
+     * instance is registered for providing the {@code default} {@link 
org.apache.tamaya.Configuration}. The providers loads the follwing
+     * config resources:
+     * <ul>
+     *     <li>Classpath: META-INF/cfg/default/&#42;&#42;/&#42;.xml, 
META-INF/cfg/default/&#42;&#42;/&#42;.properties, 
META-INF/cfg/default/&#42;&#42;/&#42;.ini</li>
+     *     <li>Classpath: META-INF/cfg/config/#42;#42;/#42;.xml, 
META-INF/cfg/config/#42;#42;/#42;.properties, 
META-INF/cfg/config/#42;#42;/#42;.ini</li>
+     *     <li>Files: defined by the system property -Dconfig.dir</li>
+     *     <li>system properties</li>
+     * </ul>
      */
     private static final class FallbackSimpleConfigProvider implements 
ConfigurationProviderSpi {
         /**
@@ -190,19 +194,22 @@ public class DefaultConfigurationManagerSingletonSpi 
implements ConfigurationMan
 
         @Override
         public void reload() {
-            this.configuration =
+            PropertySourceBuilder builder =
                     PropertySourceBuilder.of(DEFAULT_CONFIG_NAME)
                             .addProviders(PropertySourceBuilder.of("CL 
default")
                                     
.withAggregationPolicy(AggregationPolicy.LOG_ERROR)
-                                    .addPaths("META-INF/cfg/default/**/*.xml", 
"META-INF/cfg/default/**/*.properties", "META-INF/cfg/default/**/*.ini")
+                                    
.addPaths("classpath:META-INF/cfg/default/**/*.xml", 
"classpath:META-INF/cfg/default/**/*.properties", 
"classpath:META-INF/cfg/default/**/*.ini")
                                     .build())
                             .addProviders(PropertySourceBuilder.of("CL 
default")
                                     
.withAggregationPolicy(AggregationPolicy.LOG_ERROR)
-                                    .addPaths("META-INF/cfg/config/**/*.xml", 
"META-INF/cfg/config/**/*.properties", "META-INF/cfg/config/**/*.ini")
-                                    .build())
-                            .addSystemProperties()
-                            .addEnvironmentProperties()
-                            .build().toConfiguration();
+                                    
.addPaths("classpath:META-INF/cfg/config/**/*.xml", 
"classpath:META-INF/cfg/config/**/*.properties", 
"classpath:META-INF/cfg/config/**/*.ini")
+                                    .build());
+            String configDir = System.getProperty("config.dir");
+            if(configDir!=null && !configDir.trim().isEmpty()){
+                builder.addPaths("file:"+configDir);
+            }
+            builder.addSystemProperties();
+            this.configuration = builder.build().toConfiguration();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
index e5baecc..457aa6c 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/el/DefaultExpressionEvaluator.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.core.internal.el;
 
 import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
 import org.apache.tamaya.spi.ServiceContext;
 import org.apache.tamaya.core.spi.ExpressionEvaluator;
 import org.apache.tamaya.core.spi.ExpressionResolver;
@@ -27,7 +28,9 @@ import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * Created by Anatole on 28.09.2014.
+ * Default expression evaluator that manages several instances of {@link 
org.apache.tamaya.core.spi.ExpressionResolver}.
+ * Each resolver is identified by a resolver id. Each expression passed has 
the form resolverId:resolverExpression, which
+ * has the advantage that different resolvers can be active in parallel.
  */
 public final class DefaultExpressionEvaluator implements ExpressionEvaluator{
 
@@ -61,11 +64,14 @@ public final class DefaultExpressionEvaluator implements 
ExpressionEvaluator{
      * </ul>
      *
      * @param expression the expression to be evaluated, not null
+     * @param configurations overriding configurations to be used for 
evaluating the values for injection into {@code instance}.
+     *                If no such config is passed, the default configurations 
provided by the current
+     *                registered providers are used.
      * @return the evaluated expression.
      * @throws org.apache.tamaya.ConfigException if resolution fails.
      */
     @Override
-    public String evaluate(String expression) {
+    public String evaluate(String expression, Configuration... configurations) 
{
         StringTokenizer tokenizer = new StringTokenizer(expression, "${}\\", 
true);
         boolean escaped = false;
         StringBuilder resolvedValue = new StringBuilder();
@@ -106,7 +112,7 @@ public final class DefaultExpressionEvaluator implements 
ExpressionEvaluator{
                     if (!"}".equals(tokenizer.nextToken())) {
                         throw new ConfigException("Invalid expression 
encountered: " + expression);
                     }
-                    // evalute subexpression
+                    // evaluate sub-expression
                     current.append(evaluteInternal(subExpression));
                     break;
                 default:

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
index 4aa41ab..68d37a4 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/el/EnvironmentPropertyResolver.java
@@ -19,12 +19,13 @@
 package org.apache.tamaya.core.internal.el;
 
 import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
 import org.apache.tamaya.core.spi.ExpressionResolver;
 
 import java.util.Optional;
 
 /**
- * Created by Anatole on 28.09.2014.
+ * Property resolver implementation that interprets the resolver expressions 
as environment properties.
  */
 public final class EnvironmentPropertyResolver implements ExpressionResolver{
 
@@ -34,7 +35,7 @@ public final class EnvironmentPropertyResolver implements 
ExpressionResolver{
     }
 
     @Override
-    public String resolve(String expression){
+    public String resolve(String expression, Configuration... configurations){
         return Optional.ofNullable(System.getenv(expression)).orElseThrow(
                 () -> new ConfigException("No such environment property: " + 
expression)
         );

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
index 450504e..ef1ffc6 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/el/SystemPropertyResolver.java
@@ -25,7 +25,7 @@ import org.apache.tamaya.core.spi.ExpressionResolver;
 import java.util.*;
 
 /**
- * Created by Anatole on 28.09.2014.
+ * Property resolver implementation that interprets the resolver expression as 
system property name.
  */
 public final class SystemPropertyResolver implements ExpressionResolver{
 
@@ -35,7 +35,7 @@ public final class SystemPropertyResolver implements 
ExpressionResolver{
     }
 
     @Override
-    public String resolve(String expression){
+    public String resolve(String expression, Configuration... configurations){
         return Optional.ofNullable(System.getProperty(expression)).orElseThrow(
                 () -> new ConfigException("No such system property: " + 
expression)
         );

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
new file mode 100644
index 0000000..70070c5
--- /dev/null
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.internal.inject;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.core.internal.inject.ConfiguredType;
+import org.apache.tamaya.core.internal.inject.InjectionUtils;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * Invocation handler that handles request against a configuration template.
+ */
+public final class ConfigTemplateInvocationHandler implements 
InvocationHandler {
+    /**
+     * Any overriding configurations.
+     */
+    private Configuration[] configurations;
+    /**
+     * The configured type.
+     */
+    private ConfiguredType type;
+
+    /**
+     * Creates a new handler instance.
+     * @param type           the target type, not null.
+     * @param configurations overriding configurations to be used for 
evaluating the values for injection into {@code instance}, not null.
+     *                       If no such config is passed, the default 
configurationa provided by the current
+     *                       registered providers are used.
+     */
+    public ConfigTemplateInvocationHandler(Class<?> type, Configuration... 
configurations) {
+        this.configurations = Objects.requireNonNull(configurations).clone();
+        this.type = new ConfiguredType(Objects.requireNonNull(type));
+        if (!type.isInterface()) {
+            throw new IllegalArgumentException("Can only proxy interfaces as 
configuration templates.");
+        }
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable {
+        if ("toString".equals(method.getName())) {
+            return "Configured Proxy -> " + this.type.getType().getName();
+        }
+        String configValue = InjectionUtils.getConfigValue(method, 
configurations);
+        return InjectionUtils.adaptValue(method, method.getReturnType(), 
configValue);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigurationInjector.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigurationInjector.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigurationInjector.java
index 10d2374..026b4e0 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigurationInjector.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigurationInjector.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tamaya.core.internal.inject;
 
+import org.apache.tamaya.Configuration;
+
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
@@ -31,6 +33,11 @@ public final class ConfigurationInjector {
 
     private Map<Class, ConfiguredType> configuredTypes = new 
ConcurrentHashMap<>();
 
+    /**
+     * Extract the configuration annotation config and registers it per class, 
for later reuse.
+     * @param type the type to be configured.
+     * @return the configured type registered.
+     */
     public static ConfiguredType registerType(Class<?> type){
         if (!ConfiguredType.isConfigured(type)) {
             return null;
@@ -38,20 +45,22 @@ public final class ConfigurationInjector {
         return INSTANCE.configuredTypes.computeIfAbsent(type, 
ConfiguredType::new);
     }
 
-    public static void configure(Object instance){
+    /**
+     * Configured the current instance and reigsterd necessary listener to 
forward config change events as
+     * defined by the current annotations in place.
+     * @param instance the instance to be configured
+     * @param configurations Configuration instances that replace 
configuration served by services. This allows
+     *                       more easily testing and adaption.
+     */
+    public static void configure(Object instance, Configuration... 
configurations){
         Class type = Objects.requireNonNull(instance).getClass();
         if (!ConfiguredType.isConfigured(type)) {
             throw new IllegalArgumentException("Not a configured type: " + 
type.getName());
         }
-        ConfiguredType configType = registerType(type);
-        initializeConfiguredFields(configType, instance);
+        ConfiguredType configuredType = registerType(type);
+        Objects.requireNonNull(configuredType).configure(instance, 
configurations);
     }
 
-    private static <T> void initializeConfiguredFields(final ConfiguredType 
configuredType, Object instance) {
-        Objects.requireNonNull(configuredType).configure(instance);
-        ConfiguredInstancesManager.register(configuredType, instance);
-
-    }
 
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java
index ee5aeda..581021b 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredField.java
@@ -18,9 +18,9 @@
  */
 package org.apache.tamaya.core.internal.inject;
 
+import org.apache.tamaya.Codec;
 import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.Configuration;
-import org.apache.tamaya.PropertyAdapter;
 import org.apache.tamaya.annotation.*;
 import org.apache.tamaya.core.internal.Utils;
 
@@ -31,8 +31,8 @@ import java.util.stream.Collectors;
 
 /**
  * Small class that contains and manages all information anc access to a 
configured field and a concrete instance current
- * it (referenced by a weak reference). It also implements all aspects current 
value filtering, converting any applying the
- * final value by reflection.
+ * it (referenced by a weak reference). It also implements all aspects current 
keys filtering, converting any applying the
+ * final keys by reflection.
  */
 @SuppressWarnings("UnusedDeclaration")
 public class ConfiguredField {
@@ -55,133 +55,44 @@ public class ConfiguredField {
     }
 
     /**
-     * Evaluate the initial value fromMap the configuration and apply it to 
the field.
+     * Evaluate the initial keys fromMap the configuration and applyChanges it 
to the field.
      *
      * @param target the target instance.
+     * @param configurations Configuration instances that replace 
configuration served by services. This allows
+     *                       more easily testing and adaption.
      * @throws ConfigException if evaluation or conversion failed.
      */
-    public void applyInitialValue(Object target) throws ConfigException {
-        Collection<ConfiguredProperty> configuredProperties = 
Utils.getAnnotations(
-                annotatedField, ConfiguredProperty.class, 
ConfiguredProperties.class);
-        DefaultAreas areasAnnot = 
this.annotatedField.getDeclaringClass().getAnnotation(DefaultAreas.class);
-        WithLoadPolicy loadPolicy = Utils.getAnnotation(WithLoadPolicy.class, 
this.annotatedField, this.annotatedField.getDeclaringClass());
-        DefaultValue defaultValue = 
this.annotatedField.getAnnotation(DefaultValue.class);
-        String configValue = getConfigValue(loadPolicy, areasAnnot, 
configuredProperties, defaultValue);
-        applyValue(target, configValue, false);
+    public void applyInitialValue(Object target, Configuration... 
configurations) throws ConfigException {
+        String configValue = 
InjectionUtils.getConfigValue(this.annotatedField, configurations);
+        applyValue(target, configValue, false, configurations);
     }
 
-    /**
-     * Internally evaluated the current vaslid configuration value based on 
the given annotations present.
-     *
-     * @param loadPolicyAnnot The load policy, determining any explicit 
listeners to be informed.
-     * @param areasAnnot      Any default areas to be looked up.
-     * @param propertiesAnnot The configured property keys (qualified or 
relative).
-     * @param defaultAnnot    any configured default value.
-     * @return the value to be applied, or null.
-     */
-    private String getConfigValue(WithLoadPolicy loadPolicyAnnot, DefaultAreas 
areasAnnot, Collection<ConfiguredProperty> propertiesAnnot, DefaultValue 
defaultAnnot) {
-        List<String> keys = evaluateKeys(areasAnnot, propertiesAnnot);
-        annotatedField.setAccessible(true);
-        Configuration config = getConfiguration();
-        String configValue = null;
-        for (String key : keys) {
-            if (config.containsKey(key)) {
-                configValue = config.get(key).orElse(null);
-            }
-            if (configValue != null) {
-                break;
-            }
-        }
-        if (configValue == null && defaultAnnot != null) {
-            configValue = defaultAnnot.value();
-        }
-        if (configValue != null) {
-            // net step perform expression resolution, if any
-            return Configuration.evaluateValue(configValue);
-        }
-        return null;
-    }
 
     /**
-     * This method reapplies a changed configuration value to the field.
+     * This method reapplies a changed configuration keys to the field.
      *
      * @param target      the target instance, not null.
-     * @param configValue the new value to be applied, null will trigger the 
evaluation current the configured default value.
-     * @param resolve     set to true, if expression resolution should be 
applied on the value passed.
+     * @param configValue the new keys to be applied, null will trigger the 
evaluation current the configured default keys.
+     * @param resolve     set to true, if expression resolution should be 
applied on the keys passed.
      * @throws ConfigException if the configuration required could not be 
resolved or converted.
      */
-    public void applyValue(Object target, String configValue, boolean resolve) 
throws ConfigException {
+    public void applyValue(Object target, String configValue, boolean resolve, 
Configuration... configurations) throws ConfigException {
         Objects.requireNonNull(target);
         try {
             if (resolve && configValue != null) {
                 // net step perform exression resolution, if any
-                configValue = Configuration.evaluateValue(configValue);
+                configValue = Configuration.evaluateValue(configValue, 
configurations);
             }
             // Check for adapter/filter
-            WithPropertyAdapter adapterAnnot = 
this.annotatedField.getAnnotation(WithPropertyAdapter.class);
-            Class<? extends PropertyAdapter> propertyAdapterType;
-            if (adapterAnnot != null) {
-                propertyAdapterType = adapterAnnot.value();
-                if (!propertyAdapterType.equals(PropertyAdapter.class)) {
-                    // TODO cache here...
-                    PropertyAdapter<String> filter = 
propertyAdapterType.newInstance();
-                    configValue = filter.adapt(configValue);
-                }
-            }
-            if (configValue == null) {
-                // TODO Check for optional injection!
-                // annotatedField.set(target, null);
-                LOG.info("No config found for " +
-                        this.annotatedField.getDeclaringClass().getName() + 
'#' +
-                        this.annotatedField.getName());
-            } else {
-                Class baseType = annotatedField.getType();
-                if (String.class.equals(baseType) || 
baseType.isAssignableFrom(configValue.getClass())) {
-                    annotatedField.set(target, configValue);
-                } else {
-                    PropertyAdapter<?> adapter = 
PropertyAdapter.getAdapter(baseType);
-                    annotatedField.set(target, adapter.adapt(configValue));
-                }
-            }
+            Object value = InjectionUtils.adaptValue(this.annotatedField, 
this.annotatedField.getType(), configValue);
+            annotatedField.setAccessible(true);
+            annotatedField.set(target, value);
         } catch (Exception e) {
             throw new ConfigException("Failed to annotation configured field: 
" + this.annotatedField.getDeclaringClass()
                     .getName() + '.' + annotatedField.getName(), e);
         }
     }
 
-    /**
-     * Evaluates all absolute configuration key based on the annotations found 
on a class.
-     *
-     * @param areasAnnot          the (optional) annotation definining areas 
to be looked up.
-     * @param propertyAnnotations the annotation on field/method level that 
may defined the
-     *                            exact key to be looked up (in absolute or 
relative form).
-     * @return the list current keys in order how they should be 
processed/looked up.
-     */
-    private List<String> evaluateKeys(DefaultAreas 
areasAnnot,Collection<ConfiguredProperty> propertyAnnotations) {
-        Objects.requireNonNull(propertyAnnotations);
-        List<String> keys = 
propertyAnnotations.stream().map(ConfiguredProperty::value).filter(s -> 
!s.isEmpty())
-                .collect(Collectors.toList());
-        if (keys.isEmpty()) //noinspection UnusedAssignment
-            keys.add(annotatedField.getName());
-        ListIterator<String> iterator = keys.listIterator();
-        while (iterator.hasNext()) {
-            String next = iterator.next();
-            if (next.startsWith("[") && next.endsWith("]")) {
-                // absolute key, strip away brackets, take key as is
-                iterator.set(next.substring(1, next.length() - 1));
-            } else {
-                if (areasAnnot != null) {
-                    // Remove original entry, since it will be replaced with 
prefixed entries
-                    iterator.remove();
-                    // Add prefixed entries, including absolute (root) entry 
for "" area value.
-                    for (String area : areasAnnot.value()) {
-                        iterator.add(area.isEmpty() ? next : area + '.' + 
next);
-                    }
-                }
-            }
-        }
-        return keys;
-    }
 
     /**
      * This method checks if the given (qualified) configuration key is 
referenced fromMap this field.
@@ -191,26 +102,26 @@ public class ConfiguredField {
      * @param key the (qualified) configuration key, not null.
      * @return true, if the key is referenced.
      */
-    public boolean matchesKey(String key) {
-        DefaultAreas areasAnnot = 
this.annotatedField.getDeclaringClass().getAnnotation(DefaultAreas.class);
+    public boolean matchesKey(String configName, String key) {
         Collection<ConfiguredProperty> configuredProperties = 
Utils.getAnnotations(this.annotatedField, ConfiguredProperty.class,
                 ConfiguredProperties.class );
-        List<String> keys = evaluateKeys(areasAnnot, configuredProperties);
-        return keys.contains(key);
-    }
-
-    /**
-     * This method evaluates the {@link Configuration} that currently is valid 
for the given target field/method.
-     *
-     * @return the {@link Configuration} instance to be used, never null.
-     */
-    public Configuration getConfiguration() {
-        WithConfig name = annotatedField.getAnnotation(WithConfig.class);
-        if(name!=null) {
-            return Configuration.current(name.value());
+        for(ConfiguredProperty prop: configuredProperties){
+            String currentName = prop.config().trim();
+            if(currentName.isEmpty()){
+                if(!"default".equals(configName)){
+                    continue;
+                }
+            }
+            else if(!currentName.equals(configName)){
+                continue;
+            }
+            DefaultAreas areasAnnot = 
this.annotatedField.getDeclaringClass().getAnnotation(DefaultAreas.class);
+            List<String> keys = 
InjectionUtils.evaluateKeys(this.annotatedField, areasAnnot, prop);
+            if( keys.contains(key)){
+                return true;
+            }
         }
-        return Configuration.current();
+        return false;
     }
 
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredInstancesManager.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredInstancesManager.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredInstancesManager.java
deleted file mode 100644
index 2153777..0000000
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredInstancesManager.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.core.internal.inject;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.PropertySource;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.lang.ref.WeakReference;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * This service class manages the configured instances that are currently 
attached to the configuration
- * system. References to instances are rest as WeakReference instances, and 
cleanup current internal structures
- * is performed implictly during event triggering for configuration changes.
- * Created by Anatole on 03.10.2014.
- */
-public final class ConfiguredInstancesManager implements 
PropertyChangeListener{
-
-    private static final ConfiguredInstancesManager INSTANCE = new 
ConfiguredInstancesManager();
-    private Map<ConfiguredType,List<WeakReference<Object>>> 
configuredInstances = new ConcurrentHashMap<>();
-    private final Object LOCK = new Object();
-
-    private ConfiguredInstancesManager(){
-//        Configuration.addConfigChangeListener(this);
-    }
-
-    public static <T> void register(ConfiguredType configuredType, Object 
instance) {
-        List<WeakReference<Object>> instances = 
INSTANCE.configuredInstances.get(configuredType);
-        if(instances==null){
-            synchronized(INSTANCE.configuredInstances){
-                instances = INSTANCE.configuredInstances.get(configuredType);
-                if(instances==null){
-                    instances = Collections.synchronizedList(new 
ArrayList<>());
-                    INSTANCE.configuredInstances.put(configuredType, 
instances);
-                }
-            }
-        }
-        synchronized(instances) {
-            instances.add(new WeakReference<>(instance));
-        }
-    }
-
-    @Override
-    public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
-        for(Map.Entry<ConfiguredType,List<WeakReference<Object>>> en: 
configuredInstances.entrySet()){
-            PropertySource propertyProvider = 
(PropertySource)propertyChangeEvent.getSource();
-            if((propertyProvider instanceof Configuration) && 
en.getKey().isConfiguredBy((Configuration)propertyProvider)){
-                List<WeakReference<Object>> instances = en.getValue();
-                synchronized (instances){
-                    Iterator<WeakReference<Object>> iterator = 
instances.iterator();
-                    while (iterator.hasNext()) {
-                        WeakReference<Object> ref = iterator.next();
-                        Object instance = ref.get();
-                        if(instance==null){
-                            iterator.remove();
-                        }
-                        else{
-                            
en.getKey().triggerConfigUpdate(propertyChangeEvent, instance);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
index 3bc4472..3b83ee5 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
@@ -18,9 +18,9 @@
  */
 package org.apache.tamaya.core.internal.inject;
 
+import org.apache.tamaya.Codec;
 import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.Configuration;
-import org.apache.tamaya.PropertyAdapter;
 import org.apache.tamaya.annotation.*;
 import org.apache.tamaya.core.internal.Utils;
 
@@ -31,8 +31,8 @@ import java.util.stream.Collectors;
 
 /**
  * Small class that contains and manages all information anc access to a 
configured field and a concrete instance current
- * it (referenced by a weak reference). It also implements all aspects current 
value filtering, conversiong any applying the
- * final value by reflection.
+ * it (referenced by a weak reference). It also implements all aspects current 
keys filtering, conversiong any applying the
+ * final keys by reflection.
  * Created by Anatole on 01.10.2014.
  */
 @SuppressWarnings("UnusedDeclaration")
@@ -55,71 +55,9 @@ public class ConfiguredMethod {
     }
 
 
-    /**
-     * Internally evaluated the current valid configuration value based on the 
given annotations present.
-     *
-     * @return the value to be returned, or null.
-     */
-    private String getConfigValue() {
-        DefaultAreas areasAnnot = 
this.annotatedMethod.getDeclaringClass().getAnnotation(DefaultAreas.class);
-        DefaultValue defaultAnnot = 
this.annotatedMethod.getAnnotation(DefaultValue.class);
-        Collection<ConfiguredProperty> configuredProperties =
-                Utils.getAnnotations(this.annotatedMethod, 
ConfiguredProperty.class, ConfiguredProperties.class);
-        List<String> keys = evaluateKeys(areasAnnot, configuredProperties);
-        Configuration config = getConfiguration();
-        String configValue = null;
-        for (String key : keys) {
-            if (config.containsKey(key)) {
-                configValue = config.get(key).orElse(null);
-            }
-            if (configValue != null) {
-                break;
-            }
-        }
-        if (configValue == null && defaultAnnot != null) {
-            configValue = defaultAnnot.value();
-        }
-        if (configValue != null) {
-            // net step perform expression resolution, if any
-            return Configuration.evaluateValue(configValue);
-        }
-        return null;
-    }
 
-    /**
-     * Evaluates all absolute configuration key based on the annotations found 
on a class.
-     *
-     * @param areasAnnot          the (optional) annotation definining areas 
to be looked up.
-     * @param propertyAnnotations the annotation on field/method level that 
may defined the
-     *                            exact key to be looked up (in absolute or 
relative form).
-     * @return the list current keys in order how they should be 
processed/looked up.
-     */
-    private List<String> evaluateKeys(DefaultAreas areasAnnot, 
Collection<ConfiguredProperty> propertyAnnotations) {
-        List<String> keys =
-                Objects.requireNonNull(propertyAnnotations).stream()
-                        .filter(p -> !p.value().isEmpty())
-                        
.map(ConfiguredProperty::value).collect(Collectors.toList());
-        if (keys.isEmpty()) //noinspection UnusedAssignment
-            keys.add(annotatedMethod.getName());
-        ListIterator<String> iterator = keys.listIterator();
-        while (iterator.hasNext()) {
-            String next = iterator.next();
-            if (next.startsWith("[") && next.endsWith("]")) {
-                // absolute key, strip away brackets, take key as is
-                iterator.set(next.substring(1, next.length() - 1));
-            } else {
-                if (areasAnnot != null) {
-                    // Remove original entry, since it will be replaced with 
prefixed entries
-                    iterator.remove();
-                    // Add prefixed entries, including absolute (root) entry 
for "" area value.
-                    for (String area : areasAnnot.value()) {
-                        iterator.add(area.isEmpty() ? next : area + '.' + 
next);
-                    }
-                }
-            }
-        }
-        return keys;
-    }
+
+
 
     /**
      * This method checks if the given (qualified) configuration key is 
referenced fromMap this field.
@@ -133,62 +71,23 @@ public class ConfiguredMethod {
         DefaultAreas areasAnnot = 
this.annotatedMethod.getDeclaringClass().getAnnotation(DefaultAreas.class);
         Collection<ConfiguredProperty> configuredProperties =
                 Utils.getAnnotations(this.annotatedMethod, 
ConfiguredProperty.class, ConfiguredProperties.class);
-        List<String> keys = evaluateKeys(areasAnnot, configuredProperties);
-        return keys.contains(key);
-    }
-
-    /**
-     * This method evaluates the {@link org.apache.tamaya.Configuration} that 
currently is valid for the given target field/method.
-     *
-     * @return the {@link org.apache.tamaya.Configuration} instance to be 
used, never null.
-     */
-    public Configuration getConfiguration() {
-        WithConfig name = annotatedMethod.getAnnotation(WithConfig.class);
-        if (name != null) {
-            return Configuration.current(name.value());
-        }
-        return Configuration.current();
-    }
-
-    /**
-     * This method reapplies a changed configuration value to the field.
-     *
-     * @throws org.apache.tamaya.ConfigException if the configuration required 
could not be resolved or converted.
-     */
-    public Object getValue(Object[] args) throws ConfigException {
-        // TODO do something with additional args?
-        String configValue = getConfigValue();
-        try {
-            // Check for adapter/filter
-            WithPropertyAdapter adapterAnnot = 
this.annotatedMethod.getAnnotation(WithPropertyAdapter.class);
-            Class<? extends PropertyAdapter> propertyAdapterType;
-            if (adapterAnnot != null) {
-                propertyAdapterType = adapterAnnot.value();
-                if (!propertyAdapterType.equals(PropertyAdapter.class)) {
-                    // TODO cache here...
-                    PropertyAdapter<String> filter = 
propertyAdapterType.newInstance();
-                    configValue = filter.adapt(configValue);
-                }
-            }
-            if (configValue == null) {
-                // TODO optionally return null...
-                LOG.info("No config value found for " +
-                        this.annotatedMethod.getDeclaringClass().getName() + 
'#' +
-                        this.annotatedMethod.getName());
-                return null;
-            } else {
-                Class<?> baseType = annotatedMethod.getReturnType();
-                if (String.class.equals(baseType) || 
baseType.isAssignableFrom(configValue.getClass())) {
-                    return configValue;
-                } else {
-                    PropertyAdapter<?> adapter = 
PropertyAdapter.getAdapter(baseType);
-                    return adapter.adapt(configValue);
-                }
+        for(ConfiguredProperty prop: configuredProperties) {
+            if (InjectionUtils.evaluateKeys(this.annotatedMethod, areasAnnot, 
prop).contains(key)) {
+                return true;
             }
-        } catch (Exception e) {
-            throw new ConfigException("Failed to annotation configured field: 
" + this.annotatedMethod.getDeclaringClass()
-                    .getName() + '.' + annotatedMethod.getName(), e);
         }
+        return false;
     }
 
+
+//    /**
+//     * This method reapplies a changed configuration keys to the field.
+//     *
+//     * @throws org.apache.tamaya.ConfigException if the configuration 
required could not be resolved or converted.
+//     */
+//    public Object getValue(Object[] args, Configuration... configurations) 
throws ConfigException {
+//        // TODO do something with additional args?
+//        return InjectionUtils.adaptValue(this.annotatedMethod, 
this.annotatedMethod.getReturnType(), configValue);
+//    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
index b199c23..ad89c3d 100644
--- 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
@@ -20,6 +20,7 @@ package org.apache.tamaya.core.internal.inject;
 
 import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.Configuration;
+import org.apache.tamaya.PropertySource;
 import org.apache.tamaya.annotation.*;
 
 import java.beans.PropertyChangeEvent;
@@ -32,41 +33,30 @@ import java.util.*;
  * Created by Anatole on 03.10.2014.
  */
 public class ConfiguredType {
-
+    /** A list with all annotated instance variables. */
     private List<ConfiguredField> configuredFields = new ArrayList<>();
+    /** A list with all annotated methods (templates). */
     private Map<Method, ConfiguredMethod> configuredMethods = new HashMap<>();
+    /** A list with all callback methods listening to config changes. */
     private List<ConfigChangeCallbackMethod> callbackMethods = new 
ArrayList<>();
+    /** The basic type. */
     private Class type;
 
+    /**
+     * Creates an instance of this class hereby evaluating the config 
annotations given for later effective
+     * injection (configuration) of instances.
+     * @param type the instance type.
+     */
     public ConfiguredType(Class type) {
         this.type = Objects.requireNonNull(type);
-        for (Field f : type.getDeclaredFields()) {
-            ConfiguredProperties propertiesAnnot = 
f.getAnnotation(ConfiguredProperties.class);
-            if (propertiesAnnot != null) {
-                try {
-                    ConfiguredField configuredField = new ConfiguredField(f);
-                    configuredFields.add(configuredField);
-                } catch (Exception e) {
-                    throw new ConfigException("Failed to initialized 
configured field: " +
-                            f.getDeclaringClass().getName() + '.' + 
f.getName(), e);
-                }
-            }
-            else{
-                ConfiguredProperty propertyAnnot = 
f.getAnnotation(ConfiguredProperty.class);
-                if (propertyAnnot != null) {
-                    try {
-                        ConfiguredField configuredField = new 
ConfiguredField(f);
-                        configuredFields.add(configuredField);
-                    } catch (Exception e) {
-                        throw new ConfigException("Failed to initialized 
configured field: " +
-                                f.getDeclaringClass().getName() + '.' + 
f.getName(), e);
-                    }
-                }
-            }
-        }
+        initFields(type);
+        initMethods(type);
+    }
+
+    private void initMethods(Class type) {
         for (Method m : type.getDeclaredMethods()) {
             ObservesConfigChange mAnnot = 
m.getAnnotation(ObservesConfigChange.class);
-            if(mAnnot!=null) {
+            if (mAnnot != null) {
                 if (m.getParameterTypes().length != 1) {
                     continue;
                 }
@@ -82,8 +72,7 @@ public class ConfiguredType {
                     throw new ConfigException("Failed to initialized 
configured callback method: " +
                             m.getDeclaringClass().getName() + '.' + 
m.getName(), e);
                 }
-            }
-            else{
+            } else {
                 ConfiguredProperties propertiesAnnot = 
m.getAnnotation(ConfiguredProperties.class);
                 if (propertiesAnnot != null) {
                     try {
@@ -93,8 +82,7 @@ public class ConfiguredType {
                         throw new ConfigException("Failed to initialized 
configured method: " +
                                 m.getDeclaringClass().getName() + '.' + 
m.getName(), e);
                     }
-                }
-                else{
+                } else {
                     ConfiguredProperty propertyAnnot = 
m.getAnnotation(ConfiguredProperty.class);
                     if (propertyAnnot != null) {
                         try {
@@ -110,23 +98,59 @@ public class ConfiguredType {
         }
     }
 
-    public Object getConfiguredValue(Method method, Object[] args) {
-        ConfiguredMethod m = this.configuredMethods.get(method);
-        return m.getValue(args);
+    private void initFields(Class type) {
+        for (Field f : type.getDeclaredFields()) {
+            ConfiguredProperties propertiesAnnot = 
f.getAnnotation(ConfiguredProperties.class);
+            if (propertiesAnnot != null) {
+                try {
+                    ConfiguredField configuredField = new ConfiguredField(f);
+                    configuredFields.add(configuredField);
+                } catch (Exception e) {
+                    throw new ConfigException("Failed to initialized 
configured field: " +
+                            f.getDeclaringClass().getName() + '.' + 
f.getName(), e);
+                }
+            } else {
+                ConfiguredProperty propertyAnnot = 
f.getAnnotation(ConfiguredProperty.class);
+                if (propertyAnnot != null) {
+                    try {
+                        ConfiguredField configuredField = new 
ConfiguredField(f);
+                        configuredFields.add(configuredField);
+                    } catch (Exception e) {
+                        throw new ConfigException("Failed to initialized 
configured field: " +
+                                f.getDeclaringClass().getName() + '.' + 
f.getName(), e);
+                    }
+                }
+            }
+        }
     }
 
-    public void configure(Object instance) {
+    /**
+     * Method called to configure an instance.
+     *
+     * @param instance       The instance to be configured.
+     * @param configurations Configuration instances that replace 
configuration served by services. This allows
+     *                       more easily testing and adaption.
+     */
+    public void configure(Object instance, Configuration... configurations) {
         for (ConfiguredField field : configuredFields) {
             field.applyInitialValue(instance);
         }
     }
 
-    public void triggerConfigUpdate(PropertyChangeEvent configChangeEvent, 
Object instance) {
+    public void triggerConfigUpdate(PropertyChangeEvent evt, Object instance) {
         // TODO do check for right config ;)
-        configuredFields.stream().filter(field -> 
field.matchesKey(configChangeEvent.getPropertyName())).forEach(field -> 
field.applyValue(instance, (String) configChangeEvent.getNewValue(), false));
+        configuredFields.stream().filter(field -> 
field.matchesKey(getName(evt.getSource()), 
evt.getPropertyName())).forEach(field -> field.applyValue(instance, (String) 
evt.getNewValue(), false));
         for (ConfigChangeCallbackMethod callBack : this.callbackMethods) {
-            callBack.call(instance, configChangeEvent);
+            callBack.call(instance, evt);
+        }
+    }
+
+    private String getName(Object source){
+        if(source instanceof PropertySource){
+            PropertySource ps = (PropertySource)source;
+            return ps.getMetaInfo().getName();
         }
+        return "N/A";
     }
 
     public boolean isConfiguredBy(Configuration configuration) {
@@ -135,7 +159,7 @@ public class ConfiguredType {
     }
 
     public static boolean isConfigured(Class type) {
-        if(type.getAnnotation(DefaultAreas.class)!=null){
+        if (type.getAnnotation(DefaultAreas.class) != null) {
             return true;
         }
         // if no class level annotation is there we might have field level 
annotations only

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/c9e62e24/core/src/main/java/org/apache/tamaya/core/internal/inject/InjectionUtils.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/tamaya/core/internal/inject/InjectionUtils.java 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/InjectionUtils.java
new file mode 100644
index 0000000..3c073b6
--- /dev/null
+++ 
b/core/src/main/java/org/apache/tamaya/core/internal/inject/InjectionUtils.java
@@ -0,0 +1,170 @@
+package org.apache.tamaya.core.internal.inject;
+
+import org.apache.tamaya.Codec;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.annotation.*;
+import org.apache.tamaya.core.internal.Utils;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * Created by Anatole on 19.12.2014.
+ */
+final class InjectionUtils {
+
+    private InjectionUtils(){}
+
+    /**
+     * This method evaluates the {@link org.apache.tamaya.Configuration} that 
currently is valid for the given target field/method.
+     *
+     * @return the {@link org.apache.tamaya.Configuration} instance to be 
used, never null.
+     */
+    public static Configuration getConfiguration(ConfiguredProperty prop, 
Configuration... configuration) {
+        String name = prop.config();
+        if (name != null && !name.trim().isEmpty()) {
+            return Configuration.current(name.trim());
+        }
+        return Configuration.current();
+    }
+
+    /**
+     * Evaluates all absolute configuration key based on the annotations found 
on a class.
+     *
+     * @param areasAnnot          the (optional) annotation definining areas 
to be looked up.
+     * @param propertyAnnotation  the annotation on field/method level that 
may defined one or
+     *                            several keys to be looked up (in absolute or 
relative form).
+     * @return the list current keys in order how they should be 
processed/looked up.
+     */
+    public static List<String> evaluateKeys(Member member, DefaultAreas 
areasAnnot, ConfiguredProperty propertyAnnotation) {
+        List<String> keys = new 
ArrayList<>(Arrays.asList(propertyAnnotation.keys()));
+        if (keys.isEmpty()) //noinspection UnusedAssignment
+            keys.add(member.getName());
+        ListIterator<String> iterator = keys.listIterator();
+        while (iterator.hasNext()) {
+            String next = iterator.next();
+            if (next.startsWith("[") && next.endsWith("]")) {
+                // absolute key, strip away brackets, take key as is
+                iterator.set(next.substring(1, next.length() - 1));
+            } else {
+                if (areasAnnot != null) {
+                    // Remove original entry, since it will be replaced with 
prefixed entries
+                    iterator.remove();
+                    // Add prefixed entries, including absolute (root) entry 
for "" area keys.
+                    for (String area : areasAnnot.value()) {
+                        iterator.add(area.isEmpty() ? next : area + '.' + 
next);
+                    }
+                }
+            }
+        }
+        return keys;
+    }
+
+    /**
+     * Internally evaluated the current valid configuration keys based on the 
given annotations present.
+     *
+     * @return the keys to be returned, or null.
+     */
+    public static String getConfigValue(Method method, Configuration... 
configurations) {
+        DefaultAreas areasAnnot = 
method.getDeclaringClass().getAnnotation(DefaultAreas.class);
+        WithLoadPolicy loadPolicy = Utils.getAnnotation(WithLoadPolicy.class, 
method, method.getDeclaringClass());
+        return getConfigValueInternal(method, areasAnnot, loadPolicy, 
configurations);
+    }
+
+    /**
+     * Internally evaluated the current valid configuration keys based on the 
given annotations present.
+     *
+     * @return the keys to be returned, or null.
+     */
+    public static String getConfigValue(Field field, Configuration... 
configurations) {
+        DefaultAreas areasAnnot = 
field.getDeclaringClass().getAnnotation(DefaultAreas.class);
+        WithLoadPolicy loadPolicy = Utils.getAnnotation(WithLoadPolicy.class, 
field, field.getDeclaringClass());
+        return getConfigValueInternal(field, areasAnnot, loadPolicy, 
configurations);
+    }
+
+    /**
+     * Internally evaluated the current valid configuration keys based on the 
given annotations present.
+     *
+     * @return the keys to be returned, or null.
+     */
+    private static String getConfigValueInternal(AnnotatedElement element, 
DefaultAreas areasAnnot, WithLoadPolicy loadPolicy, Configuration... 
configurations) {
+        Collection<ConfiguredProperty> configuredProperties = 
Utils.getAnnotations(
+                element, ConfiguredProperty.class, ConfiguredProperties.class);
+        DefaultValue defaultAnnot = element.getAnnotation(DefaultValue.class);
+        String configValue = null;
+        for(ConfiguredProperty prop: configuredProperties){
+            List<String> keys = InjectionUtils.evaluateKeys((Member)element, 
areasAnnot, prop);
+            Configuration config = InjectionUtils.getConfiguration(prop, 
configurations);
+            for (String key : keys) {
+                if (config.containsKey(key)) {
+                    configValue = config.get(key).orElse(null);
+                }
+                if (configValue != null) {
+                    break;
+                }
+            }
+            if (configValue != null) {
+                // net step perform expression resolution, if any
+                return Configuration.evaluateValue(configValue, config);
+            }
+        }
+        if (configValue == null && defaultAnnot != null) {
+            return defaultAnnot.value();
+        }
+        return null;
+    }
+
+    public static <T> T adaptValue(AnnotatedElement element, Class<T> 
targetType, String configValue){
+        try {
+            // Check for adapter/filter
+            T adaptedValue = null;
+            WithCodec codecAnnot = element.getAnnotation(WithCodec.class);
+            Class<? extends Codec> codecType;
+            if (codecAnnot != null) {
+                codecType = codecAnnot.value();
+                if (!codecType.equals(Codec.class)) {
+                    // TODO cache here...
+                    Codec<String> codec = codecType.newInstance();
+                    adaptedValue = (T) codec.deserialize(configValue);
+                }
+            }
+            if (String.class.equals(targetType)) {
+                 return (T)configValue;
+            } else {
+                 Codec<?> adapter = Codec.getInstance(targetType);
+                 return (T)adapter.deserialize(configValue);
+            }
+        } catch (Exception e) {
+            throw new ConfigException("Failed to annotate configured member: " 
+ element, e);
+        }
+    }
+
+    /**
+     * This method evaluates the {@link Configuration} that currently is valid 
for the given target field/method.
+     * @param configurations Configuration instances that replace 
configuration served by services. This allows
+     *                       more easily testing and adaption.
+     * @return the {@link Configuration} instance to be used, never null.
+     */
+    public static Configuration getConfiguration(String name, Configuration... 
configurations) {
+        if(name!=null) {
+            for(Configuration conf: configurations){
+                if(name.equals(conf.getMetaInfo().getName())){
+                    return conf;
+                }
+            }
+            return Configuration.current(name);
+        }
+        else{
+            for(Configuration conf: configurations){
+                if("default".equals(conf.getMetaInfo().getName())){
+                    return conf;
+                }
+            }
+        }
+        return Configuration.current();
+    }
+}

Reply via email to