TAMAYA-252: Unified PropertyValue API and usage, also separating key, value, 
source and other meta-data and defining a clear builder policy.


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

Branch: refs/heads/master
Commit: ae4ebe1d34a03f7f6e3dd97859533eec879bc639
Parents: 855342a
Author: anatole <anat...@apache.org>
Authored: Sun Mar 5 21:27:29 2017 +0100
Committer: anatole <anat...@apache.org>
Committed: Mon Mar 6 00:29:34 2017 +0100

----------------------------------------------------------------------
 .../org/apache/tamaya/spi/FilterContext.java    |  20 ++-
 .../org/apache/tamaya/spi/PropertyFilter.java   |   4 +-
 .../org/apache/tamaya/spi/PropertySource.java   |  51 ++++++-
 .../org/apache/tamaya/spi/PropertyValue.java    |  77 +++++++++-
 .../apache/tamaya/spi/PropertyValueBuilder.java |  90 ++++++++----
 .../spi/PropertyValueCombinationPolicy.java     |   7 +-
 .../apache/tamaya/spi/FilterContextTest.java    |  29 ++--
 .../tamaya/spi/PropertyValueBuilderTest.java    | 129 +++++++++++++---
 .../apache/tamaya/spi/PropertyValueTest.java    | 146 ++++++++++++++++++-
 .../core/internal/DefaultConfiguration.java     |  86 +++++------
 .../tamaya/core/internal/PropertyFiltering.java |  33 ++---
 .../core/internal/PropertySourceComparator.java |  88 +++++------
 .../core/internal/WrappedPropertySource.java    |   2 +-
 .../core/propertysource/BasePropertySource.java |  14 +-
 .../core/propertysource/CLIPropertySource.java  |  16 +-
 .../EnvironmentPropertySource.java              |  29 ++--
 .../JavaConfigurationPropertySource.java        |   7 +-
 .../propertysource/SimplePropertySource.java    |  39 ++---
 .../propertysource/SystemPropertySource.java    |  19 +--
 .../core/ConfigurationContextBuilderTest.java   |  27 ++--
 .../apache/tamaya/core/TestPropertySource.java  |   7 +-
 .../DefaultConfigurationContextBuilderTest.java |  19 ++-
 .../DefaultConfigurationContextTest.java        |   2 +-
 .../ConverterTestsPropertySource.java           |   7 +-
 .../propertysource/BasePropertySourceTest.java  |  25 ++--
 .../propertysource/CLIPropertySourceTest.java   |  18 +--
 .../EnvironmentPropertySourceTest.java          |   9 +-
 .../PropertiesFilePropertySourceTest.java       |   6 +-
 .../SimplePropertySourceTest.java               |   5 +-
 .../SystemPropertySourceTest.java               |  28 ++--
 .../provider/JavaConfigurationProviderTest.java |   2 +-
 .../testdata/TestPropertyDefaultSource.java     |   9 +-
 .../core/testdata/TestPropertyFilter.java       |   7 +-
 .../testdata/TestPropertySourceProvider.java    |  13 +-
 .../testdata/TestRemovingPropertyFilter.java    |   7 +-
 .../SimplePropertySource.java                   |   9 +-
 36 files changed, 711 insertions(+), 375 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java 
b/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
index 3c675c8..d5c7850 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/FilterContext.java
@@ -32,7 +32,7 @@ public class FilterContext {
     /** The key. */
     private final String key;
     @Experimental
-    private Map<String, String> configEntries = new HashMap();
+    private Map<String, PropertyValue> configEntries = new HashMap();
     @Experimental
     private boolean singlePropertyScoped;
 
@@ -40,16 +40,24 @@ public class FilterContext {
     /**
      * Creates a new FilterContext.
      * @param key the key under evaluation, not null.
-     * @param singlePropertyScope true, if the filtering is done only for one 
single property accessed explcitily.
      * @param configEntries the raw configuration data available in the 
current evaluation context, not null.
      */
-    public FilterContext(String key, Map<String,String> configEntries, boolean 
singlePropertyScope) {
-        this.singlePropertyScoped = singlePropertyScope;
+    public FilterContext(String key, Map<String,PropertyValue> configEntries) {
+        this.singlePropertyScoped = false;
         this.key = Objects.requireNonNull(key);
         this.configEntries.putAll(configEntries);
         this.configEntries = Collections.unmodifiableMap(this.configEntries);
     }
 
+    public FilterContext(String key, PropertyValue value) {
+        this.singlePropertyScoped = true;
+        this.key = Objects.requireNonNull(key);
+        if(value!=null) {
+            this.configEntries.put(value.getKey(), value);
+        }
+        this.configEntries = Collections.unmodifiableMap(this.configEntries);
+    }
+
     /**
      * Get the key accessed. This information is very useful to evaluate 
additional metadata needed to determine/
      * control further aspects of the conversion.
@@ -92,13 +100,13 @@ public class FilterContext {
      * @return the configuration instance, or null.
      */
     @Experimental
-    public Map<String, String> getConfigEntries() {
+    public Map<String, PropertyValue> getConfigEntries() {
         return configEntries;
     }
 
     @Override
     public String toString() {
-        return "FilterContext{key='" + key + "', configEntries=" + 
configEntries + '}';
+        return "FilterContext{key='" + key + "', configEntries=" + 
configEntries.keySet() + '}';
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java 
b/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
index 1ecc88a..c14bd3c 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyFilter.java
@@ -42,7 +42,9 @@ public interface PropertyFilter {
      * @param value the value to be filtered, which also can be {@code null} 
if removed by another filter.
      * @param context the filter context, not null.
      * @return the filtered value, or {@code null} if the value should be 
removed alltogether.
+     * @see PropertyValue
+     * @see PropertyValueBuilder
      */
-    String filterProperty(String value, FilterContext context);
+    PropertyValue filterProperty(PropertyValue value, FilterContext context);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java 
b/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
index 83b2f7a..e0093af 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertySource.java
@@ -19,6 +19,8 @@
 package org.apache.tamaya.spi;
 
 
+import org.apache.tamaya.Configuration;
+
 import java.util.Collections;
 import java.util.Map;
 
@@ -55,6 +57,7 @@ public interface PropertySource {
      */
     PropertySource EMPTY = new PropertySource() {
 
+        @Override
         public int getOrdinal() {
             return Integer.MIN_VALUE;
         }
@@ -70,7 +73,7 @@ public interface PropertySource {
         }
 
         @Override
-        public Map<String, String> getProperties() {
+        public Map<String, PropertyValue> getProperties() {
             return Collections.emptyMap();
         }
 
@@ -87,6 +90,48 @@ public interface PropertySource {
 
 
     /**
+     * The ordinal value is the default ordering parameter which definines the 
default order of
+     * auto-discovered property sources. Ordering of property sources is 
important since values
+     * from property sources with higher ordinal values override values from 
less significant
+     * property sources.
+     *
+     * By default Tamaya includes the following property sources:
+     * <ol>
+     *     <li>Properties file values (/META-INF/javaconfiguration.properties) 
(ordinal 100)</li>
+     *     <li>JNDI values (ordinal 200, only when adding the {@code 
tamaya-jndi} extension module)</li>
+     *     <li>Environment properties (ordinal 300)</li>
+     *     <li>System properties (ordinal 1000)</li>
+     * </ol>
+     *
+     * <p><b>Important Hints for custom implementations</b>:</p>
+     * <p>
+     * If a custom implementation should be invoked <b>before</b> the default 
implementations, use a value &gt; 1000
+     * </p>
+     * <p>
+     * If a custom implementation should be invoked <b>after</b> the default 
implementations, use a value &lt; 100
+     * </p>
+     *
+     * <p>Reordering of the default order of the config-sources:</p>
+     * <p>Example: If the properties file/s should be used <b>before</b> the 
other implementations,
+     * you have to configure an ordinal &gt; 1000. That means, you have to add 
e.g. tamaya.ordinal=401 to
+     * /META-INF/javaconfiguration.properties . Hint: In case of property 
files every file is handled as independent
+     * config-source, but all of them have ordinal 400 by default (and can be 
reordered in a fine-grained manner.</p>
+     *
+     * In cases where it is not possible to change a config sources ordinal 
value, you may have several options:
+     * <ul>
+     *     <li>you can register an alternate implementation of {@link 
PropertyValueCombinationPolicy}.</li>
+     *     <li>you can use a {@link ConfigurationContextBuilder} to redefine 
the source order and finally use
+     *     {@link 
org.apache.tamaya.ConfigurationProvider#setConfiguration(Configuration)} to
+     *     change the current default {@link Configuration}.</li>
+     *     <li>finally, the imeplementor of this API may define alternate 
mechanism to reconfigure an ordinal
+     *     in a vendor specific way.</li>
+     * </ul>
+     * @return the 'importance' aka ordinal of the configured values. The 
higher, the more important.
+     */
+    int getOrdinal();
+
+
+    /**
      * Get the name of the property source. The name should be unique for the 
type of source, whereas the id is used
      * to ensure unique identity, either locally or remotely.
      * @return the configuration's name, never null.
@@ -103,12 +148,12 @@ public interface PropertySource {
     PropertyValue get(String key);
 
     /**
-     * Access the current properties as Map. The resulting Map may not return 
all items accessible, e.g.
+     * Access the current properties as Set. The resulting Map may not return 
all items accessible, e.g.
      * when the underlying storage does not support iteration of its entries.
      *
      * @return the corresponding map, never null.
      */
-    Map<String,String> getProperties();
+    Map<String, PropertyValue> getProperties();
 
     /**
      * Determines if this config source can be scanned for its list of 
properties.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
----------------------------------------------------------------------
diff --git a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java 
b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
index 0332b85..a622509 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValue.java
@@ -36,12 +36,15 @@ public final class PropertyValue implements Serializable{
     private String key;
     /** The value. */
     private String value;
+    /** The source of the value. */
+    private String source;
     /** Additional metadata provided by the provider. */
     private Map<String,String> metaEntries = new HashMap<>();
 
     PropertyValue(PropertyValueBuilder builder){
-        this.key = builder.key;
-        this.value = Objects.requireNonNull(builder.value);
+        this.key = Objects.requireNonNull(builder.key);
+        this.value = builder.value;
+        this.source = Objects.requireNonNull(builder.source);
         if(builder.metaEntries !=null) {
             this.metaEntries.putAll(builder.metaEntries);
         }
@@ -56,7 +59,7 @@ public final class PropertyValue implements Serializable{
     private PropertyValue(String key, String value, String source){
         this.key = Objects.requireNonNull(key, "key is required.");
         this.value = Objects.requireNonNull(value);
-        this.metaEntries.put("_"+key+".source", Objects.requireNonNull(source, 
"source is required."));
+        this.source = Objects.requireNonNull(source);
     }
 
     /**
@@ -68,6 +71,16 @@ public final class PropertyValue implements Serializable{
     }
 
     /**
+     * The source.
+     * @return the source, which provided the value, not null.
+     * @see PropertySource#getName().
+     */
+    public String getSource() {
+        return this.source;
+    }
+
+
+    /**
      * The value.
      * @return the value, in case a value is null it is valid to return {#code 
null} as result for
      * {@link PropertySource#get(String)}.
@@ -88,7 +101,16 @@ public final class PropertyValue implements Serializable{
     /**
      * Creates a new builder instance.
      * @param key the key, not null.
-     * @param value the value.
+     * @param source the source, typically the name of the {@link 
PropertySource} providing the value, not null.
+     * @return a new builder instance.
+     */
+    public static PropertyValueBuilder builder(String key, String source){
+        return new PropertyValueBuilder(key, source);
+    }
+
+    /**
+     * Creates a new builder instance.
+     * @param key the key, not null.
      * @param source the source, typically the name of the {@link 
PropertySource} providing the value, not null.
      * @return a new builder instance.
      */
@@ -96,6 +118,7 @@ public final class PropertyValue implements Serializable{
         return new PropertyValueBuilder(key, value, source);
     }
 
+
     /**
      * Creates a new PropertyValue without any metadata..
      * @param key the key, not null.
@@ -116,7 +139,7 @@ public final class PropertyValue implements Serializable{
      * @return the value found, or null.
      */
     public String getMetaEntry(String key) {
-        return this.metaEntries.get(key);
+        return this.metaEntries.get(Objects.requireNonNull(key));
     }
 
     /**
@@ -124,7 +147,9 @@ public final class PropertyValue implements Serializable{
      * @return a new builder, never null.
      */
     public PropertyValueBuilder toBuilder() {
-        return new PropertyValueBuilder(this.getKey(), this.getValue(), 
this.metaEntries);
+        return new PropertyValueBuilder(this.getKey(), this.getSource())
+                .setValue(this.getValue())
+        .setMetaEntries(this.metaEntries);
     }
 
     @Override
@@ -134,12 +159,14 @@ public final class PropertyValue implements Serializable{
         PropertyValue that = (PropertyValue) o;
         return Objects.equals(getKey(), that.getKey()) &&
                 Objects.equals(getValue(), that.getValue()) &&
+                Objects.equals(getSource(), that.getSource()) &&
                 Objects.equals(getMetaEntries(), that.getMetaEntries());
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(getKey(), getValue(), getMetaEntries());
+        return Objects.hash(getKey(), getValue(), getSource(),
+                getMetaEntries());
     }
 
     @Override
@@ -147,7 +174,41 @@ public final class PropertyValue implements Serializable{
         return "PropertyValue{" +
                 "key='" + key + '\'' +
                 ", value='" + value + '\'' +
-                ", metaEntries=" + metaEntries +
+                ", source='" + value + '\'' +
+                (metaEntries.isEmpty()?"":", metaEntries=" + metaEntries) +
                 '}';
     }
+
+    /**
+     * Maps a map of {@code Map<String,String>} to a {@code 
Map<String,PropertyValue>}.
+     * @param config the String based map, not null.
+     * @param source the source name, not null.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,PropertyValue> map(Map<String, String> config, 
String source) {
+        Map<String,PropertyValue> result = new HashMap<>(config.size());
+        for(Map.Entry<String,String> en:config.entrySet()){
+            result.put(en.getKey(), PropertyValue.of(en.getKey(), 
en.getValue(), source));
+        }
+        return result;
+    }
+
+    /**
+     * Maps a map of {@code Map<String,String>} to a {@code 
Map<String,PropertyValue>}.
+     * @param config the String based map, not null.
+     * @param source the source name, not null.
+     * @param metaData additional metadata, not null.
+     * @return the corresponding value based map.
+     */
+    public static Map<String,PropertyValue> map(Map<String, String> config, 
String source,
+                                                Map<String,String> metaData) {
+        Map<String,PropertyValue> result = new HashMap<>(config.size());
+        for(Map.Entry<String,String> en:config.entrySet()){
+            result.put(en.getKey(),
+                    new PropertyValueBuilder(en.getKey(), source)
+                            .setValue(en.getValue())
+            .addMetaEntries(metaData).build());
+        }
+        return result;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
----------------------------------------------------------------------
diff --git 
a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java 
b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
index 57a40be..6b4f9fd 100644
--- a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
+++ b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueBuilder.java
@@ -31,52 +31,46 @@ public class PropertyValueBuilder {
     String key;
     /** The property value. */
     String value;
+    /** The property vaoue source. */
+    String source;
     /** additional metadata entries (optional). */
     Map<String,String> metaEntries = new HashMap<>();
 
     /**
      * Create a new builder instance, for a given set of parameters.
+     * Before calling build at least a {@link #value} and its {@link #source}
+     * must be set.
+     */
+    PropertyValueBuilder(String key){
+        this.key = Objects.requireNonNull(key);
+    }
+
+    /**
+     * Create a new builder instance, for a given set of parameters.
      * @param key to access a property value.
-     * @param value the value, not null. If a value is null {@link 
PropertySource#get(String)} should return
-     * {@code null}.
      * @param source property source.
      */
-    public PropertyValueBuilder(String key, String value, String source) {
+    PropertyValueBuilder(String key, String source) {
         this.key = Objects.requireNonNull(key);
-        this.value = Objects.requireNonNull(value);
-        this.metaEntries.put("source", Objects.requireNonNull(source));
+        this.source = Objects.requireNonNull(source);
     }
 
     /**
-     * Creates a new builder from data from a {@link PropertyValue}.
+     * Create a new builder instance, for a given set of parameters.
      * @param key to access a property value.
      * @param value the value, not null. If a value is null {@link 
PropertySource#get(String)} should return
      * {@code null}.
-     * @param metaEntries the context data, not null.
+     * @param source property source.
      */
-    PropertyValueBuilder(String key, String value, Map<String,String> 
metaEntries) {
+    PropertyValueBuilder(String key, String value, String source) {
         this.key = Objects.requireNonNull(key);
-        this.value = Objects.requireNonNull(value);
-        this.metaEntries.putAll(metaEntries);
+        this.value = value;
+        this.source = Objects.requireNonNull(source);
     }
 
     /**
      * Replaces/sets the context data.
-     * @param metaEntries the context data to be applied, not null. Note that 
all keys should only identify the context
-     *                    data item. the builder does create a corresponding 
metadata entry, e.g.
-     *                    <pre>
-     *                    provider=myProviderName
-     *                    ttl=250
-     *                    creationIndex=1
-     *                    modificationIndex=23
-     *                    </pre>
-     *                    will be mapped, given a key {@code test.env.name} to
-     *                    <pre>
-     *                    _test.env.name.provider=myProviderName
-     *                    _test.env.name.ttl=250
-     *                    _test.env.name.creationIndex=1
-     *                    _test.env.name.modificationIndex=23
-     *                    </pre>
+     * @param metaEntries the context data to be applied, not null.
      * @return the builder for chaining.
      */
     public PropertyValueBuilder setMetaEntries(Map<String, String> 
metaEntries) {
@@ -91,14 +85,34 @@ public class PropertyValueBuilder {
      * @param value the context value, not null (will be converted to String).
      * @return the builder for chaining.
      */
-    public PropertyValueBuilder addContextData(String key, Object value) {
+    public PropertyValueBuilder addMetaEntry(String key, Object value) {
         this.metaEntries.put(key, String.valueOf(Objects.requireNonNull(value, 
"Meta value is null.")));
         return this;
     }
 
     /**
+     * Adds the context data given.
+     * @param metaEntries the context data to be applied, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder addMetaEntries(Map<String, String> 
metaEntries) {
+        this.metaEntries.putAll(metaEntries);
+        return this;
+    }
+
+    /**
+     * Removes a meta entry.
+     * @param key the entry's key, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder removeMetaEntry(String key) {
+        this.metaEntries.remove(key);
+        return this;
+    }
+
+    /**
      * Get the value's context data.
-     * @return the context data.
+     * @return the context data, not null.
      */
     public Map<String,String> getMetaEntries(){
         return Collections.unmodifiableMap(this.metaEntries);
@@ -124,8 +138,18 @@ public class PropertyValueBuilder {
     }
 
     /**
+     * Sets a new key.
+     * @param key the new key, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setKey(String key) {
+        this.key = Objects.requireNonNull(key);
+        return this;
+    }
+
+    /**
      * Sets a new value.
-     * @param value the new value.
+     * @param value the new value, not null.
      * @return the builder for chaining.
      */
     public PropertyValueBuilder setValue(String value) {
@@ -134,6 +158,16 @@ public class PropertyValueBuilder {
     }
 
     /**
+     * Sets a new source.
+     * @param source the new source, not null.
+     * @return the builder for chaining.
+     */
+    public PropertyValueBuilder setSource(String source) {
+        this.source = Objects.requireNonNull(source);
+        return this;
+    }
+
+    /**
      * Creates a new immutable {@link PropertyValue}.
      * @return a new immutable {@link PropertyValue}, never null.
      */

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
----------------------------------------------------------------------
diff --git 
a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
 
b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
index 096b2a1..81e4b60 100644
--- 
a/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
+++ 
b/code/api/src/main/java/org/apache/tamaya/spi/PropertyValueCombinationPolicy.java
@@ -18,7 +18,6 @@
  */
 package org.apache.tamaya.spi;
 
-import java.util.Map;
 
 /**
  * Policy that determines how the final value of a configuration entry is 
evaluated. An instances of this
@@ -36,9 +35,9 @@ public interface PropertyValueCombinationPolicy {
     PropertyValueCombinationPolicy DEFAULT_OVERRIDING_COLLECTOR = new 
PropertyValueCombinationPolicy(){
 
         @Override
-        public Map<String,String> collect(Map<String,String> currentValue, 
String key, PropertySource propertySource) {
+        public PropertyValue collect(PropertyValue currentValue, String key, 
PropertySource propertySource) {
             PropertyValue value = propertySource.get(key);
-            return value!=null?value.getConfigEntries():currentValue;
+            return value!=null?value:currentValue;
         }
 
     };
@@ -61,6 +60,6 @@ public interface PropertyValueCombinationPolicy {
      *                       {@code currentValue} should be returned in almost 
all cases.
      * @return the value to be used for future evaluation, including metadata 
entries.
      */
-    Map<String,String> collect(Map<String,String> currentValue, String key, 
PropertySource propertySource);
+    PropertyValue collect(PropertyValue currentValue, String key, 
PropertySource propertySource);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
----------------------------------------------------------------------
diff --git 
a/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java 
b/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
index 2dcf78a..d8d9380 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/FilterContextTest.java
@@ -32,45 +32,42 @@ public class FilterContextTest {
     @Test
     public void getKey() throws Exception {
         FilterContext ctx = new FilterContext("getKey",
-                new HashMap<String,String>(), true);
+                new HashMap<String,PropertyValue>());
         assertEquals("getKey", ctx.getKey());
     }
 
     @Test
     public void isSinglePropertyScoped() throws Exception {
         FilterContext ctx = new FilterContext("isSinglePropertyScoped",
-                new HashMap<String,String>(), true);
-        assertEquals(true, ctx.isSinglePropertyScoped());
-        ctx = new FilterContext("isSinglePropertyScoped",
-                new HashMap<String,String>(), false);
+                new HashMap<String,PropertyValue>());
         assertEquals(false, ctx.isSinglePropertyScoped());
+        ctx = new FilterContext("isSinglePropertyScoped", 
PropertyValue.of("isSinglePropertyScoped", "val", "test"));
+        assertEquals(true, ctx.isSinglePropertyScoped());
     }
 
     @Test
     public void getConfigEntries() throws Exception {
-        Map<String,String> config = new HashMap<>();
+        Map<String,PropertyValue> config = new HashMap<>();
         for(int i=0;i<10;i++) {
-            config.put("key-"+i, "value-"+i);
+            config.put("key-"+i, PropertyValue.of("key-"+i, "value-"+i, 
"test"));
         }
-        FilterContext ctx = new FilterContext("getConfigEntries",
-                config, true);
+        FilterContext ctx = new FilterContext("getMetaEntries", config);
         assertEquals(config, ctx.getConfigEntries());
         assertTrue(config != ctx.getConfigEntries());
     }
 
     @Test
     public void testToString() throws Exception {
-        Map<String,String> config = new HashMap<>();
+        Map<String,PropertyValue> config = new HashMap<>();
         for(int i=0;i<2;i++) {
-            config.put("key-"+i, "value-"+i);
+            config.put("key-"+i, PropertyValue.of("key-"+i, "value-"+i, 
"test"));
         }
-        FilterContext ctx = new FilterContext("testToString",
-                config, true);
+        FilterContext ctx = new FilterContext("testToString", config);
         String toString = ctx.toString();
         assertNotNull(toString);
-        assertTrue(toString.contains("FilterContext{key='testToString', 
configEntries={"));
-        assertTrue(toString.contains("key-0=value-0"));
-        assertTrue(toString.contains("key-1=value-1"));
+        assertTrue(toString.contains("FilterContext{key='testToString', 
configEntries=["));
+        assertTrue(toString.contains("key-0"));
+        assertTrue(toString.contains("key-1"));
         assertTrue(toString.endsWith("}"));
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java
----------------------------------------------------------------------
diff --git 
a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java 
b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java
index 5fdec2d..75597ea 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueBuilderTest.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.spi;
 
 import org.junit.Test;
+import org.mockito.internal.matchers.Null;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -31,54 +32,142 @@ import static org.junit.Assert.*;
 public class PropertyValueBuilderTest {
 
     @Test
+    public void testCreate1(){
+        new PropertyValueBuilder("k");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testCreate1_Null(){
+        new PropertyValueBuilder(null);
+    }
+
+    @Test
+    public void testCreate2(){
+        new PropertyValueBuilder("k", "source");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testCreate2_Null(){
+        new PropertyValueBuilder("k", null);
+    }
+
+    @Test
     public void testKey() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", "testKey");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", 
"testKey").setValue("v");
         PropertyValue val = b.build();
         assertEquals(val.getKey(),"k");
     }
 
     @Test
+    public void testSource() throws Exception {
+        PropertyValueBuilder b = new PropertyValueBuilder("k", 
"testSource").setValue("v");
+        PropertyValue val = b.build();
+        assertEquals(val.getSource(),"testSource");
+    }
+
+    @Test
     public void testValue() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", 
"testValue");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", 
"testValue").setValue("v");
         PropertyValue val = b.build();
         assertEquals(val.getValue(),"v");
-        assertEquals(val.getConfigEntries().get("k"),"v");
+        assertNull(val.getMetaEntries().get("k"));
     }
 
     @Test(expected=NullPointerException.class)
     public void testKeyNullValue() throws Exception {
-        new PropertyValueBuilder("k", null, "testKeyNullValue");
+        new PropertyValueBuilder(null, "testKeyNullValue");
+    }
+
+    @Test
+    public void testSetMetaEntries() throws Exception {
+        Map<String,String> meta = new HashMap<>();
+        meta.put("1","2");
+        meta.put("a", "b");
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey")
+                .setValue("v")
+                .addMetaEntry("k", "v2")
+                .setMetaEntries(meta).build();
+        assertEquals("v", pv.getValue());
+        assertEquals("k", pv.getKey());
+        assertNull("v2", pv.getMetaEntry("k"));
+        assertEquals("testGetKey", pv.getSource());
+        assertEquals("2", pv.getMetaEntry("1"));
+        assertEquals("b", pv.getMetaEntry("a"));
+    }
+
+    @Test
+    public void testGetKey() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", 
"testGetKey").setValue("v").build();
+        assertEquals("k", pv.getKey());
+    }
+
+    @Test
+    public void testGetValue1() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetValue");
+        assertEquals("v", pv.getValue());
+    }
+
+    @Test
+    public void testGetValue2() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", 
"testGetValue").setValue("v").build();
+        assertEquals("v", pv.getValue());
+    }
+
+    @Test
+    public void testRemoveMetaEntry() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey")
+                .setValue("v")
+                .addMetaEntry("k", "v2")
+                .addMetaEntry("k2", "v22")
+                .removeMetaEntry("k").build();
+        assertEquals("v22", pv.getMetaEntry("k2"));
+        assertNull(pv.getMetaEntry("k"));
+    }
+
+    @Test(expected=NullPointerException.class)
+    public void testSourceNullValue() throws Exception {
+        new PropertyValueBuilder("k", null);
+    }
+
+    @Test
+    public void testGetMetaEntries() throws Exception {
+        Map<String,String> meta = new HashMap<>();
+        meta.put("1","2");
+        meta.put("a", "b");
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey")
+                .setValue("v")
+                .setMetaEntries(meta).build();
+        assertEquals(meta, pv.getMetaEntries());
     }
 
     @Test
     public void testSetContextData() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", 
"testSetContextData");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", 
"testSetContextData").setValue("v");
         Map<String,String> context = new HashMap<>();
         context.put("source", "testSetContextData");
         context.put("ts", String.valueOf(System.currentTimeMillis()));
         context.put("y", "yValue");
-        b.setContextData(new HashMap<String, String>());
-        b.setContextData(context);
+        b.setMetaEntries(new HashMap<String, String>());
+        b.setMetaEntries(context);
         context.remove("y");
-        b.setContextData(context);
+        b.setMetaEntries(context);
         PropertyValue contextData = b.build();
-        assertEquals(contextData.getConfigEntries().size(), context.size()+1);
-        assertEquals(contextData.get("_k.source"), "testSetContextData");
-        assertNotNull(contextData.get("_k.ts"));
-        assertNull(contextData.get("_k.y"));
+        assertEquals(contextData.getMetaEntries().size(), context.size());
+        assertEquals(contextData.getMetaEntry("source"), "testSetContextData");
+        assertNotNull(contextData.getMetaEntry("ts"));
+        assertNull(contextData.getMetaEntry("y"));
     }
 
     @Test
     public void testAddContextData() throws Exception {
-        PropertyValueBuilder b = new PropertyValueBuilder("k", "v", 
"testAddContextData");
-        b.addContextData("ts", System.currentTimeMillis());
-        b.addContextData("y", "yValue");
-        b.addContextData("y", "y2");
+        PropertyValueBuilder b = new PropertyValueBuilder("k", 
"testAddContextData").setValue("v");
+        b.addMetaEntry("ts", System.currentTimeMillis());
+        b.addMetaEntry("y", "yValue");
+        b.addMetaEntry("y", "y2");
         PropertyValue contextData = b.build();
-        assertEquals(contextData.getConfigEntries().size(), 4);
-        assertEquals(contextData.get("_k.source"), "testAddContextData");
-        assertNotNull(contextData.get("_k.ts"));
-        assertEquals(contextData.get("_k.y"), "y2");
+        assertEquals(contextData.getMetaEntries().size(), 2);
+        assertNotNull(contextData.getMetaEntry("ts"));
+        assertEquals(contextData.getMetaEntry("y"), "y2");
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
----------------------------------------------------------------------
diff --git 
a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java 
b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
index c6909ab..533e978 100644
--- a/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
+++ b/code/api/src/test/java/org/apache/tamaya/spi/PropertyValueTest.java
@@ -20,6 +20,9 @@ package org.apache.tamaya.spi;
 
 import org.junit.Test;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import static org.junit.Assert.*;
 
 /**
@@ -28,25 +31,154 @@ import static org.junit.Assert.*;
 public class PropertyValueTest {
 
     @Test
+    public void testOf(){
+        assertNotNull(PropertyValue.of("k", "v", "testGetKey"));
+    }
+
+    @Test
+    public void testHashCode(){
+        assertEquals(PropertyValue.of("k", "v", "testGetKey").hashCode(),
+                PropertyValue.of("k", "v", "testGetKey").hashCode());
+        assertNotSame(PropertyValue.of("k", "v", "testGetKey").hashCode(),
+                PropertyValue.of("k1", "v", "testGetKey").hashCode());
+        assertNotSame(PropertyValue.of("k", "v", "testGetKey").hashCode(),
+                PropertyValue.of("k", "v1", "testGetKey").hashCode());
+        assertNotSame(PropertyValue.of("k", "v", "1").hashCode(),
+                PropertyValue.of("k", "v", "2").hashCode());
+    }
+
+    @Test
+    public void testEquals(){
+        assertEquals(PropertyValue.of("k", "v", "testEquals"),
+                PropertyValue.of("k", "v", "testEquals"));
+        assertNotSame(PropertyValue.of("k2", "v", "testEquals"),
+                PropertyValue.of("k", "v", "testEquals"));
+        assertNotSame(PropertyValue.of("k", "v", "testEquals"),
+                PropertyValue.of("k", "v2", "testEquals"));
+        assertNotSame(PropertyValue.of("k", "v", "testEquals"),
+                PropertyValue.of("k", "v", "testEquals2"));
+    }
+
+    @Test
+    public void testBuilder(){
+        assertNotNull(PropertyValue.builder("k", "testGetKey"));
+        assertEquals(PropertyValue.of("k", "v", "testEquals"),
+                PropertyValue.builder("k", 
"testEquals").setValue("v").build());
+    }
+
+    @Test
+    public void testToBuilder(){
+        assertNotNull(PropertyValue.of("k", "v", "testGetKey").toBuilder());
+        // round-trip
+        PropertyValue val = PropertyValue.of("k", "v", "testGetKey");
+        assertEquals(val,
+                val.toBuilder().build());
+    }
+
+
+    @Test
     public void testGetKey() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v", 
"testGetKey").build();
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetKey");
         assertEquals("k", pv.getKey());
     }
 
     @Test
     public void testGetValue() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v", 
"testGetKey").build();
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetValue");
         assertEquals("v", pv.getValue());
     }
 
     @Test
-    public void testGetContextData() throws Exception {
-        PropertyValue pv = PropertyValue.builder("k", "v", "testGetKey")
-                .addContextData("k", "v2").build();
+    public void testGetSource() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetSource");
+        assertEquals("testGetSource", pv.getSource());
+        pv = PropertyValue.of("k", "v", "testGetSource");
+        assertEquals("testGetSource", pv.getSource());
+    }
+
+    @Test
+    public void testGetMetaEntry() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", 
"testGetMetaEntry").setValue("v")
+                .addMetaEntry("k", "v2").build();
         assertEquals("v", pv.getValue());
         assertEquals("k", pv.getKey());
-        assertEquals("v2", pv.get("_k.k"));
-        assertEquals("testGetKey", pv.get("_k.source"));
+        assertEquals("v2", pv.getMetaEntry("k"));
+        assertEquals("testGetMetaEntry", pv.getSource());
     }
 
+    @Test
+    public void testGetMetaEntries() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", "v", "testGetMetaEntries");
+        assertNotNull(pv.getMetaEntries());
+        assertTrue(pv.getMetaEntries().isEmpty());
+    }
+
+    @Test
+    public void testMap() throws Exception {
+        Map<String,String> map = new HashMap<>();
+        map.put("a", "1");
+        map.put("b", "2");
+        Map<String,PropertyValue> result = PropertyValue.map(map, "source1");
+        assertNotNull(result);
+        assertEquals(map.size(), result.size());
+        for(Map.Entry<String,String>en:map.entrySet()){
+            PropertyValue val = result.get(en.getKey());
+            assertNotNull(val);
+            assertEquals(val.getKey(), en.getKey());
+            assertEquals(val.getValue(), en.getValue());
+            assertEquals(val.getSource(), "source1");
+            assertTrue(val.getMetaEntries().isEmpty());
+        }
+    }
+
+    @Test
+    public void testMapWithMetadata() throws Exception {
+        Map<String,String> map = new HashMap<>();
+        map.put("a", "1");
+        map.put("b", "2");
+        Map<String,String> meta = new HashMap<>();
+        map.put("m1", "n1");
+        map.put("m2", "n2");
+        Map<String,PropertyValue> result = PropertyValue.map(map, "source1", 
meta);
+        assertNotNull(result);
+        assertEquals(map.size(), result.size());
+        for(Map.Entry<String,String>en:map.entrySet()){
+            PropertyValue val = result.get(en.getKey());
+            assertNotNull(val);
+            assertEquals(val.getKey(), en.getKey());
+            assertEquals(val.getValue(), en.getValue());
+            assertEquals(val.getSource(), "source1");
+            assertEquals(val.getMetaEntries(), meta);
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testInstantiateNoKey1() throws Exception {
+        PropertyValue pv = PropertyValue.builder(null, 
"testGetKey").setValue("v").build();
+    }
+    @Test(expected = NullPointerException.class)
+    public void testInstantiateNoKey2() throws Exception {
+        PropertyValue pv = PropertyValue.of(null, "v", "testGetKey");
+    }
+
+    @Test
+    public void testInstantiateNoValue1() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", "testGetKey").build();
+    }
+    @Test
+    public void testInstantiateNoValue2() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", null, "testGetKey");
+    }
+    @Test(expected = NullPointerException.class)
+    public void testInstantiateNoSource1() throws Exception {
+        PropertyValue pv = PropertyValue.builder("k", 
null).setValue("v").build();
+    }
+    @Test(expected = NullPointerException.class)
+    public void testInstantiateNoSource2() throws Exception {
+        PropertyValue pv = PropertyValue.of("k", "v", null);
+    }
+    @Test(expected = NullPointerException.class)
+    public void testGetMetaEntry_Null() throws Exception {
+        PropertyValue.of("k", "v", "src").getMetaEntry(null);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
 
b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
index 268d825..8ad7489 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/internal/DefaultConfiguration.java
@@ -23,15 +23,8 @@ import org.apache.tamaya.ConfigOperator;
 import org.apache.tamaya.ConfigQuery;
 import org.apache.tamaya.Configuration;
 import org.apache.tamaya.TypeLiteral;
-import org.apache.tamaya.spi.ConfigurationContext;
-import org.apache.tamaya.spi.ConversionContext;
-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 java.util.ArrayList;
-import java.util.Collections;
+import org.apache.tamaya.spi.*;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -55,6 +48,25 @@ public class DefaultConfiguration implements Configuration {
      */
     private final ConfigurationContext configurationContext;
 
+    /**
+     * EvaluationStrategy
+     */
+    private ConfigValueEvaluator configEvaluator = loadConfigValueEvaluator();
+
+    private ConfigValueEvaluator loadConfigValueEvaluator() {
+        ConfigValueEvaluator eval = null;
+        try{
+            eval = ServiceContextManager.getServiceContext()
+                    .getService(ConfigValueEvaluator.class);
+        }catch(Exception e){
+            LOG.log(Level.WARNING, "Failed to load ConfigValueEvaluator from 
ServiceContext, using default.", e);
+        }
+        if(eval==null){
+            eval = new DefaultConfigValueEvaluator();
+        }
+        return eval;
+    }
+
 
     /**
      * Constructor.
@@ -64,24 +76,17 @@ public class DefaultConfiguration implements Configuration {
         this.configurationContext = 
Objects.requireNonNull(configurationContext);
     }
 
-
+    @Override
     public String get(String key) {
-        Map<String,String> value = evaluteRawValue(key);
-        if(value==null || value.get(key)==null){
+        PropertyValue value = configEvaluator.evaluteRawValue(key, 
configurationContext);
+        if(value==null || value.getValue()==null){
             return null;
         }
-        return PropertyFiltering.applyFilter(key, value, configurationContext);
-    }
-
-    protected Map<String,String> evaluteRawValue(String key) {
-        List<PropertySource> propertySources = 
configurationContext.getPropertySources();
-        Map<String,String> unfilteredValue = null;
-        PropertyValueCombinationPolicy combinationPolicy = 
this.configurationContext
-                .getPropertyValueCombinationPolicy();
-        for (PropertySource propertySource : propertySources) {
-            unfilteredValue = combinationPolicy.collect(unfilteredValue, key, 
propertySource);
+        value = PropertyFiltering.applyFilter(key, value, 
configurationContext);
+        if(value!=null){
+            return value.getValue();
         }
-        return unfilteredValue;
+        return null;
     }
 
 
@@ -111,28 +116,21 @@ public class DefaultConfiguration implements 
Configuration {
      */
     @Override
     public Map<String, String> getProperties() {
-        return PropertyFiltering.applyFilters(evaluateUnfilteredMap(), 
configurationContext);
-    }
-
-    protected Map<String, String> evaluateUnfilteredMap() {
-        List<PropertySource> propertySources = new 
ArrayList<>(configurationContext.getPropertySources());
-        Collections.reverse(propertySources);
-        Map<String, String> result = new HashMap<>();
-        for (PropertySource propertySource : propertySources) {
-            try {
-                int origSize = result.size();
-                Map<String, String> otherMap = propertySource.getProperties();
-                LOG.log(Level.FINEST, null, "Overriding with properties from " 
+ propertySource.getName());
-                result.putAll(otherMap);
-                LOG.log(Level.FINEST, null, "Handled properties from " + 
propertySource.getName() + "(new: " +
-                        (result.size() - origSize) + ", overrides: " + 
origSize + ", total: " + result.size());
-            } catch (Exception e) {
-                LOG.log(Level.SEVERE, "Error adding properties from 
PropertySource: " + propertySource + ", ignoring PropertySource.", e);
+        Map<String, PropertyValue> filtered = PropertyFiltering.applyFilters(
+                configEvaluator.evaluateRawValues(configurationContext),
+                configurationContext);
+        Map<String,String> result = new HashMap<>();
+        for(PropertyValue val:filtered.values()){
+            if(val.getValue()!=null) {
+                result.put(val.getKey(), val.getValue());
+                // TODO: Discuss metadata handling...
+                result.putAll(val.getMetaEntries());
             }
         }
         return result;
     }
 
+
     /**
      * Accesses the current String value for the given key and tries to 
convert it
      * using the {@link PropertyConverter} instances provided by the current
@@ -215,14 +213,6 @@ public class DefaultConfiguration implements Configuration 
{
         return this.configurationContext;
     }
 
-    /**
-     * Access the configuration's context.
-     * @return the configurastion context-
-     */
-    public ConfigurationContext getConfigurationContext() {
-        return configurationContext;
-    }
-
     @Override
     public String toString() {
         return "Configuration{\n " +

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
 
b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
index 1872be4..932d38c 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertyFiltering.java
@@ -22,6 +22,7 @@ import org.apache.tamaya.spi.ConfigurationContext;
 import org.apache.tamaya.spi.FilterContext;
 import org.apache.tamaya.spi.PropertyFilter;
 import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -51,27 +52,26 @@ public final class PropertyFiltering{
      */
     private PropertyFiltering(){}
 
-    public static String applyFilter(String key, Map<String,String> 
configData, ConfigurationContext configurationContext) {
+    public static PropertyValue applyFilter(String key, PropertyValue value, 
ConfigurationContext configurationContext) {
         // Apply filters to values, prevent values filtered to null!
-        String result = configData.get(key);
         for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
             boolean changed = false;
             // Apply filters to values, prevent values filtered to null!
-            FilterContext filterContext = new FilterContext(key, configData, 
true);
+            FilterContext filterContext = new FilterContext(key, value);
             for (PropertyFilter filter : 
configurationContext.getPropertyFilters()) {
-                String newValue = filter.filterProperty(result, filterContext);
-                if (newValue != null && !newValue.equals(result)) {
+                PropertyValue newValue = filter.filterProperty(value, 
filterContext);
+                if (newValue != null && !newValue.equals(value)) {
                     changed = true;
                     if (LOG.isLoggable(Level.FINEST)) {
-                        LOG.finest("Filter - " + key + ": " + result + " -> " 
+ newValue + " by " + filter);
+                        LOG.finest("Filter - " + value + " -> " + newValue + " 
by " + filter);
                     }
-                } else if (result != null && !result.equals(newValue)) {
+                } else if (value != null && !value.equals(newValue)) {
                     changed = true;
                     if (LOG.isLoggable(Level.FINEST)) {
-                        LOG.finest("Filter - " + key + ": " + result + " -> " 
+ newValue + " by " + filter);
+                        LOG.finest("Filter - " + value + " -> " + newValue + " 
by " + filter);
                     }
                 }
-                result = newValue;
+                value = newValue;
             }
             if (!changed) {
                 LOG.finest("Finishing filter loop, no changes detected.");
@@ -86,21 +86,20 @@ public final class PropertyFiltering{
                 }
             }
         }
-        return result;
+        return value;
     }
 
-    public static Map<String, String> applyFilters(Map<String, String> 
inputMap, ConfigurationContext configurationContext) {
-        Map<String, String> resultMap = new HashMap<>(inputMap);
+    public static Map<String, PropertyValue> applyFilters(Map<String, 
PropertyValue> inputMap, ConfigurationContext configurationContext) {
+        Map<String, PropertyValue> resultMap = new HashMap<>(inputMap);
         // Apply filters to values, prevent values filtered to null!
-        Map<String, String> metaData = filterMetadata(inputMap);
         for (int i = 0; i < MAX_FILTER_LOOPS; i++) {
             AtomicInteger changes = new AtomicInteger();
-            for (Map.Entry<String, String> entry : inputMap.entrySet()) {
-                FilterContext filterContext = new 
FilterContext(entry.getKey(), inputMap, false);
+            for (Map.Entry<String, PropertyValue> entry : inputMap.entrySet()) 
{
+                FilterContext filterContext = new 
FilterContext(entry.getKey(), inputMap);
                 for (PropertyFilter filter : 
configurationContext.getPropertyFilters()) {
                     final String k = entry.getKey();
-                    final String v = entry.getValue();
-                    String newValue = filter.filterProperty(v, filterContext);
+                    final PropertyValue v = entry.getValue();
+                    PropertyValue newValue = filter.filterProperty(v, 
filterContext);
                     if (newValue != null && !newValue.equals(v)) {
                         changes.incrementAndGet();
                         LOG.finest("Filter - " + k + ": " + v + " -> " + 
newValue + " by " + filter);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
 
b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
index 2793f1f..7e9c503 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/internal/PropertySourceComparator.java
@@ -85,50 +85,50 @@ public class PropertySourceComparator implements 
Comparator<PropertySource>, Ser
      * @return the ordinal value to compare the property source.
      */
     public static int getOrdinal(PropertySource propertySource) {
-        PropertyValue ordinalValue = 
propertySource.get(PropertySource.TAMAYA_ORDINAL);
-        if(ordinalValue!=null){
-            try{
-                return Integer.parseInt(ordinalValue.getValue().trim());
-            }catch(Exception e){
-                LOG.finest("Failed to parse ordinal from " + 
PropertySource.TAMAYA_ORDINAL +
-                        " in " + propertySource.getName()+": 
"+ordinalValue.getValue());
-            }
-        }
-        try {
-            Method method = propertySource.getClass().getMethod("getOrdinal");
-            if(int.class.equals(method.getReturnType())){
-                if(!method.isAccessible()){
-                    method.setAccessible(true);
-                }
-                try {
-                    return (int)method.invoke(propertySource);
-                } catch (Exception e) {
-                    LOG.log(Level.FINEST, "Error calling 'int getOrdinal()' on 
" + propertySource.getName(), e);
-                }
-            }
-        } catch (NoSuchMethodException e) {
-            LOG.finest("No 'int getOrdinal()' method found in " + 
propertySource.getName());
-        }
-        try {
-            Field field = propertySource.getClass().getField("ORDINAL");
-            if(int.class.equals(field.getType()) && 
Modifier.isStatic(field.getModifiers())){
-                if(!field.isAccessible()){
-                    field.setAccessible(true);
-                }
-                try {
-                    return (int)field.get(propertySource);
-                } catch (Exception e) {
-                    LOG.log(Level.FINEST, "Error evaluating 'int ORDINAL' on " 
+ propertySource.getName(), e);
-                }
-            }
-        } catch (NoSuchFieldException e) {
-            LOG.finest("No 'int ORDINAL' field found in " + 
propertySource.getName());
-        }
-        Priority prio = 
propertySource.getClass().getAnnotation(Priority.class);
-        if(prio!=null){
-            return prio.value();
-        }
-        return 0;
+//        PropertyValue ordinalValue = 
propertySource.get(PropertySource.TAMAYA_ORDINAL);
+//        if(ordinalValue!=null){
+//            try{
+//                return Integer.parseInt(ordinalValue.getValue().trim());
+//            }catch(Exception e){
+//                LOG.finest("Failed to parse ordinal from " + 
PropertySource.TAMAYA_ORDINAL +
+//                        " in " + propertySource.getName()+": 
"+ordinalValue.getValue());
+//            }
+//        }
+//        try {
+//            Method method = 
propertySource.getClass().getMethod("getOrdinal");
+//            if(int.class.equals(method.getReturnType())){
+//                if(!method.isAccessible()){
+//                    method.setAccessible(true);
+//                }
+//                try {
+//                    return (int)method.invoke(propertySource);
+//                } catch (Exception e) {
+//                    LOG.log(Level.FINEST, "Error calling 'int getOrdinal()' 
on " + propertySource.getName(), e);
+//                }
+//            }
+//        } catch (NoSuchMethodException e) {
+//            LOG.finest("No 'int getOrdinal()' method found in " + 
propertySource.getName());
+//        }
+//        try {
+//            Field field = propertySource.getClass().getField("ORDINAL");
+//            if(int.class.equals(field.getType()) && 
Modifier.isStatic(field.getModifiers())){
+//                if(!field.isAccessible()){
+//                    field.setAccessible(true);
+//                }
+//                try {
+//                    return (int)field.get(propertySource);
+//                } catch (Exception e) {
+//                    LOG.log(Level.FINEST, "Error evaluating 'int ORDINAL' on 
" + propertySource.getName(), e);
+//                }
+//            }
+//        } catch (NoSuchFieldException e) {
+//            LOG.finest("No 'int ORDINAL' field found in " + 
propertySource.getName());
+//        }
+//        Priority prio = 
propertySource.getClass().getAnnotation(Priority.class);
+//        if(prio!=null){
+//            return prio.value();
+//        }
+        return propertySource.getOrdinal();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
 
b/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
index db1a911..32bb12b 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/internal/WrappedPropertySource.java
@@ -84,7 +84,7 @@ class WrappedPropertySource implements PropertySource{
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return delegate.getProperties();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
index 5a41848..ebc681a 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/BasePropertySource.java
@@ -20,7 +20,6 @@ package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.spi.PropertyValueBuilder;
 
 import java.util.Map;
 import java.util.Objects;
@@ -135,19 +134,12 @@ public abstract class BasePropertySource implements 
PropertySource {
 
     @Override
     public PropertyValue get(String key) {
-        Map<String,String> properties = getProperties();
-        String val = properties.get(key);
+        Map<String,PropertyValue> properties = getProperties();
+        PropertyValue val = properties.get(key);
         if(val==null){
             return null;
         }
-        PropertyValueBuilder b = new PropertyValueBuilder(key, val, getName());
-        String metaKeyStart = "_" + key + ".";
-        for(Map.Entry<String,String> en:properties.entrySet()) {
-            if(en.getKey().startsWith(metaKeyStart) && en.getValue()!=null){
-                b.addContextData(en.getKey().substring(metaKeyStart.length()), 
en.getValue());
-            }
-        }
-        return b.build();
+        return val;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
index 12e4932..6f2489d 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/CLIPropertySource.java
@@ -18,6 +18,8 @@
  */
 package org.apache.tamaya.core.propertysource;
 
+import org.apache.tamaya.spi.PropertyValue;
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -33,7 +35,7 @@ public class CLIPropertySource extends BasePropertySource{
     private static String[] args = new String[0];
 
     /** The map of parsed main arguments. */
-    private static Map<String,String> mainArgs;
+    private static Map<String,PropertyValue> mainArgs;
 
     /* Initializes the initial state. */
     static {
@@ -83,7 +85,7 @@ public class CLIPropertySource extends BasePropertySource{
         if(argsProp!=null){
             CLIPropertySource.args = argsProp.split("\\s");
         }
-        Map<String,String> result = null;
+        Map<String,PropertyValue> result;
         if(CLIPropertySource.args==null){
             result = Collections.emptyMap();
         }else{
@@ -99,19 +101,19 @@ public class CLIPropertySource extends BasePropertySource{
                     int index = arg.indexOf("=");
                     if(index>0){
                         key = arg.substring(0,index).trim();
-                        result.put(prefix+key, arg.substring(index+1).trim());
+                        result.put(prefix+key, PropertyValue.of(key, 
arg.substring(index+1).trim(), "main-args"));
                         key = null;
                     }else{
-                        result.put(prefix+arg, arg);
+                        result.put(prefix+arg, PropertyValue.of(prefix+arg, 
arg, "main-args"));
                     }
                 }else if(arg.startsWith("-")){
                     key = arg.substring(1);
                 }else{
                     if(key!=null){
-                        result.put(prefix+key, arg);
+                        result.put(prefix+key, PropertyValue.of(prefix+key, 
arg, "main-args"));
                         key = null;
                     }else{
-                        result.put(prefix+arg, arg);
+                        result.put(prefix+arg, PropertyValue.of(prefix+arg, 
arg, "main-args"));
                     }
                 }
             }
@@ -120,7 +122,7 @@ public class CLIPropertySource extends BasePropertySource{
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return Collections.unmodifiableMap(mainArgs);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
index 3bab3b2..c204d26 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/EnvironmentPropertySource.java
@@ -20,10 +20,7 @@ package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.spi.PropertyValue;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
+import java.util.*;
 
 /**
  * This {@link org.apache.tamaya.spi.PropertySource} provides all properties 
which are set
@@ -34,8 +31,6 @@ import java.util.logging.Logger;
  */
 public class EnvironmentPropertySource extends BasePropertySource {
 
-    private static final Logger LOG = 
Logger.getLogger(EnvironmentPropertySource.class.getName());
-
     /**
      * Default ordinal for {@link 
org.apache.tamaya.core.propertysource.EnvironmentPropertySource}
      */
@@ -146,25 +141,21 @@ public class EnvironmentPropertySource extends 
BasePropertySource {
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         if(disabled){
             return Collections.emptyMap();
         }
         String prefix = this.prefix;
-        if(prefix==null) {
-            Map<String, String> entries = new HashMap<>(System.getenv());
-            for (Map.Entry<String, String> entry : System.getenv().entrySet()) 
{
-                entries.put("_" + entry.getKey() + ".source", getName());
-            }
-            return entries;
-        }else{
-            Map<String, String> entries = new HashMap<>();
-            for (Map.Entry<String, String> entry : System.getenv().entrySet()) 
{
-                entries.put(prefix + entry.getKey(), entry.getValue());
-                entries.put("_" + prefix + entry.getKey() + ".source", 
getName());
+        Map<String,String> envProps = System.getenv();
+        Map<String, PropertyValue> values = new HashMap<>();
+        for (Map.Entry<String,String> entry : envProps.entrySet()) {
+            if(prefix==null) {
+                values.put(entry.getKey(), PropertyValue.of(entry.getKey(), 
entry.getValue(), getName()));
+            }else {
+                values.put(prefix + entry.getKey(), PropertyValue.of(prefix + 
entry.getKey(), entry.getValue(), getName()));
             }
-            return entries;
         }
+        return values;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
index 90abb72..a6cd5e3 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/JavaConfigurationPropertySource.java
@@ -20,9 +20,8 @@ package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.core.internal.PropertySourceComparator;
-import org.apache.tamaya.core.propertysource.SimplePropertySource;
 import org.apache.tamaya.spi.PropertySource;
-import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValue;
 import org.apache.tamaya.spi.ServiceContextManager;
 
 import java.io.IOException;
@@ -115,11 +114,11 @@ public class JavaConfigurationPropertySource extends 
BasePropertySource {
 
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         if (!isEnabled()) {
             return Collections.emptyMap();
         }
-        Map<String,String> result = new HashMap<>();
+        Map<String,PropertyValue> result = new HashMap<>();
         for(PropertySource ps:getPropertySources()){
             result.putAll(ps.getProperties());
         }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
index 6a06b62..2c8ec0b 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SimplePropertySource.java
@@ -19,6 +19,7 @@
 package org.apache.tamaya.core.propertysource;
 
 import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertyValue;
 
 import java.io.File;
 import java.io.IOException;
@@ -39,14 +40,9 @@ public class SimplePropertySource extends BasePropertySource 
{
     private static final Logger LOG = 
Logger.getLogger(SimplePropertySource.class.getName());
 
     /**
-     * The property source name.
-     */
-    private String name;
-
-    /**
      * The current properties.
      */
-    private Map<String, String> properties;
+    private Map<String, PropertyValue> properties = new HashMap<>();
 
     /**
      * Creates a new Properties based PropertySource based on the given URL.
@@ -56,7 +52,7 @@ public class SimplePropertySource extends BasePropertySource {
     public SimplePropertySource(File propertiesLocation) {
         super(0);
         try {
-            this.name = propertiesLocation.toString();
+            setName(propertiesLocation.toString());
             this.properties = load(propertiesLocation.toURI().toURL());
         } catch (IOException e) {
             throw new ConfigException("Failed to load properties from " + 
propertiesLocation, e);
@@ -71,7 +67,7 @@ public class SimplePropertySource extends BasePropertySource {
     public SimplePropertySource(URL propertiesLocation) {
         super(0);
         this.properties = load(Objects.requireNonNull(propertiesLocation));
-        this.name = propertiesLocation.toString();
+        setName(propertiesLocation.toString());
     }
 
     /**
@@ -82,8 +78,10 @@ public class SimplePropertySource extends BasePropertySource 
{
      */
     public SimplePropertySource(String name, Map<String, String> properties) {
         super(0);
-        this.properties = new HashMap<>(properties);
-        this.name = Objects.requireNonNull(name);
+        setName(Objects.requireNonNull(name));
+        for(Map.Entry<String,String> en:properties.entrySet()){
+            this.properties.put(en.getKey(), PropertyValue.of(en.getKey(), 
en.getValue(), name));
+        }
     }
 
     /**
@@ -95,16 +93,11 @@ public class SimplePropertySource extends 
BasePropertySource {
     public SimplePropertySource(String name, URL propertiesLocation) {
         super(0);
         this.properties = load(propertiesLocation);
-        this.name = Objects.requireNonNull(name);
+        setName(name);
     }
 
     @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return this.properties;
     }
 
@@ -115,10 +108,11 @@ public class SimplePropertySource extends 
BasePropertySource {
      * @return loaded {@link java.util.Properties}
      * @throws IllegalStateException in case of an error while reading 
properties-file
      */
-    private Map<String, String> load(URL propertiesFile) {
+    private Map<String, PropertyValue> load(URL propertiesFile) {
+        setName(propertiesFile.toString());
         boolean isXML = isXMLPropertieFiles(propertiesFile);
 
-        Map<String, String> properties = new HashMap<>();
+        Map<String, PropertyValue> properties = new HashMap<>();
         try (InputStream stream = propertiesFile.openStream()) {
             Properties props = new Properties();
             if (stream != null) {
@@ -130,12 +124,7 @@ public class SimplePropertySource extends 
BasePropertySource {
             }
 
             for (String key : props.stringPropertyNames()) {
-                properties.put(key, props.getProperty(key));
-                if (getName() == null){
-                    LOG.finest("No property source name found for " + this +", 
ommitting source meta-entries.");
-                } else {
-                    properties.put("_" + key + ".source", getName());
-                }
+                properties.put(key, PropertyValue.of(key, 
props.getProperty(key), getName()));
             }
         } catch (IOException e) {
             throw new ConfigException("Error loading properties from " + 
propertiesFile, e);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
index 5c7604e..4dca29d 100644
--- 
a/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
+++ 
b/code/core/src/main/java/org/apache/tamaya/core/propertysource/SystemPropertySource.java
@@ -36,7 +36,7 @@ public class SystemPropertySource extends BasePropertySource {
      */
     public static final int DEFAULT_ORDINAL = 1000;
 
-    private volatile Map<String,String> cachedProperties;
+    private volatile Map<String, PropertyValue> cachedProperties;
 
     /**
      * previous System.getProperties().hashCode()
@@ -131,21 +131,19 @@ public class SystemPropertySource extends 
BasePropertySource {
     }
 
 
-    private Map<String, String> loadProperties() {
+    private Map<String,PropertyValue> loadProperties() {
         Properties sysProps = System.getProperties();
         previousHash = System.getProperties().hashCode();
         final String prefix = this.prefix;
-        Map<String, String> entries = new HashMap<>();
+        Map<String,PropertyValue> values = new HashMap<>();
         for (Map.Entry<Object,Object> entry : sysProps.entrySet()) {
             if(prefix==null) {
-                entries.put("_" + entry.getKey() + ".source", getName());
-                entries.put((String) entry.getKey(), (String) 
entry.getValue());
+                values.put((String) entry.getKey(), PropertyValue.of((String) 
entry.getKey(), (String)entry.getValue(), getName()));
             }else {
-                entries.put(prefix + entry.getKey(), (String)entry.getValue());
-                entries.put("_" + prefix + entry.getKey() + ".source", 
getName());
+                values.put(prefix + entry.getKey(), PropertyValue.of(prefix + 
entry.getKey(), (String)entry.getValue(), getName()));
             }
         }
-        return entries;
+        return values;
     }
 
     @Override
@@ -169,7 +167,7 @@ public class SystemPropertySource extends 
BasePropertySource {
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         if(disabled){
             return Collections.emptyMap();
         }
@@ -177,8 +175,7 @@ public class SystemPropertySource extends 
BasePropertySource {
         // synchronization was removed, Instance was marked as volatile. In 
the worst case it
         // is reloaded twice, but the values will be the same.
         if (previousHash != System.getProperties().hashCode()) {
-            Map<String, String> properties = loadProperties();
-            this.cachedProperties = Collections.unmodifiableMap(properties);
+            this.cachedProperties = 
Collections.unmodifiableMap(loadProperties());
         }
         return this.cachedProperties;
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
 
b/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
index 9a1dd6f..f1e8ea4 100644
--- 
a/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
+++ 
b/code/core/src/test/java/org/apache/tamaya/core/ConfigurationContextBuilderTest.java
@@ -130,13 +130,13 @@ public class ConfigurationContextBuilderTest {
     public void addPropertyFilters_Array() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
@@ -156,13 +156,13 @@ public class ConfigurationContextBuilderTest {
     public void addPropertyFilters_Collection() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
@@ -182,13 +182,13 @@ public class ConfigurationContextBuilderTest {
     public void removePropertyFilters_Array() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
@@ -211,13 +211,13 @@ public class ConfigurationContextBuilderTest {
     public void removePropertyFilters_Collection() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
@@ -326,9 +326,8 @@ public class ConfigurationContextBuilderTest {
     @Test
     public void setPropertyValueCombinationPolicy() throws Exception {
         PropertyValueCombinationPolicy combPol = new 
PropertyValueCombinationPolicy(){
-
             @Override
-            public Map<String, String> collect(Map<String, String> 
currentValue, String key, PropertySource propertySource) {
+            public PropertyValue collect(PropertyValue currentValue, String 
key, PropertySource propertySource) {
                 return currentValue;
             }
         };
@@ -457,8 +456,8 @@ public class ConfigurationContextBuilderTest {
         for(int i=0;i<propertyFilters.length;i++){
             propertyFilters[i] = new PropertyFilter(){
                 @Override
-                public String filterProperty(String value, FilterContext 
context) {
-                    return toString() + " - ";
+                public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
+                    return value.toBuilder().setValue(toString() + " - 
").build();
                 }
             };
         }
@@ -491,8 +490,8 @@ public class ConfigurationContextBuilderTest {
         ConfigurationContextBuilder b = 
ConfigurationProvider.getConfigurationContextBuilder();
         b.addPropertyFilters(new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
-                return toString() + " - ";
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
+                return value.toBuilder().setValue(toString() + " - ").build();
             }
         });
         assertFalse(b.getPropertyFilters().isEmpty());

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java 
b/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java
index 50e26e4..91d83d2 100644
--- a/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java
+++ b/code/core/src/test/java/org/apache/tamaya/core/TestPropertySource.java
@@ -21,6 +21,7 @@ package org.apache.tamaya.core;
 
 import org.apache.tamaya.spi.PropertySource;
 import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spi.PropertyValueBuilder;
 
 import java.util.Collections;
 import java.util.Date;
@@ -55,13 +56,13 @@ public class TestPropertySource implements PropertySource {
     @Override
     public PropertyValue get(String key) {
         return PropertyValue.builder(key, key + "Value", getName())
-                .addContextData("ordinal", String.valueOf(getOrdinal()))
-                .addContextData("createdAt", String.valueOf(new Date()))
+                .addMetaEntry("ordinal", String.valueOf(getOrdinal()))
+                .addMetaEntry("createdAt", String.valueOf(new Date()))
                 .build();
     }
 
     @Override
-    public Map<String, String> getProperties() {
+    public Map<String, PropertyValue> getProperties() {
         return Collections.emptyMap();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
 
b/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
index 9564bda..05dd922 100644
--- 
a/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
+++ 
b/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextBuilderTest.java
@@ -77,13 +77,13 @@ public class DefaultConfigurationContextBuilderTest {
     public void addPropertyFilters_Array() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
@@ -103,13 +103,13 @@ public class DefaultConfigurationContextBuilderTest {
     public void removePropertyFilters_Array() throws Exception {
         PropertyFilter filter1 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
         PropertyFilter filter2 = new PropertyFilter(){
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };
@@ -175,9 +175,10 @@ public class DefaultConfigurationContextBuilderTest {
         PropertyValueCombinationPolicy combPol = new 
PropertyValueCombinationPolicy(){
 
             @Override
-            public Map<String, String> collect(Map<String, String> 
currentValue, String key, PropertySource propertySource) {
+            public PropertyValue collect(PropertyValue currentValue, String 
key, PropertySource propertySource) {
                 return currentValue;
             }
+
         };
         ConfigurationContextBuilder b = new 
DefaultConfigurationContextBuilder()
                 .setPropertyValueCombinationPolicy(combPol);
@@ -192,7 +193,6 @@ public class DefaultConfigurationContextBuilderTest {
     }
 
 
-    @Priority(200)
     private static class TestPropertySource implements PropertySource{
 
         private String id;
@@ -206,6 +206,11 @@ public class DefaultConfigurationContextBuilderTest {
         }
 
         @Override
+        public int getOrdinal() {
+            return 200;
+        }
+
+        @Override
         public String getName() {
             return id!=null?id:"TestPropertySource";
         }
@@ -216,7 +221,7 @@ public class DefaultConfigurationContextBuilderTest {
         }
 
         @Override
-        public Map<String, String> getProperties() {
+        public Map<String, PropertyValue> getProperties() {
             return Collections.emptyMap();
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/ae4ebe1d/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
----------------------------------------------------------------------
diff --git 
a/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
 
b/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
index 6ab5976..9d98a5e 100644
--- 
a/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
+++ 
b/code/core/src/test/java/org/apache/tamaya/core/internal/DefaultConfigurationContextTest.java
@@ -145,7 +145,7 @@ public class DefaultConfigurationContextTest {
         PropertyFilter testFilter = new PropertyFilter() {
 
             @Override
-            public String filterProperty(String value, FilterContext context) {
+            public PropertyValue filterProperty(PropertyValue value, 
FilterContext context) {
                 return value;
             }
         };


Reply via email to