http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/src/main/asciidoc/design/2_CoreConcepts.adoc
----------------------------------------------------------------------
diff --git a/docs/src/main/asciidoc/design/2_CoreConcepts.adoc 
b/docs/src/main/asciidoc/design/2_CoreConcepts.adoc
new file mode 100644
index 0000000..831a71f
--- /dev/null
+++ b/docs/src/main/asciidoc/design/2_CoreConcepts.adoc
@@ -0,0 +1,849 @@
+// 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.
+<<<
+[[CoreConcepts]]
+== {name} Core Concepts
+Though {name} is a very powerful and flexible solution there are basically 
only a few simple core concepts required that build
+the base of all the other mechanisms:
+
+The API contains the following core concepts/artifacts:
+
+* Literal Key/Value Pairs
+* _PropertySource:_ is the the SPI for a source that provides configuration 
data. A +PropertySource+
+     hereby defines
+     ** a minimalistic SPI to be implemented by the config data source
+     ** provides data key/value pairs in raw format as String key/values only
+     ** providers should not have any dependencies other than to the datasource
+     ** providers may read context dependent data, but basically providers 
themselves are not contextual.
+        Context management should be done by the ConfigurationProvider 
implementation that also is responsible
+        for combining a set of property providers to a Configuration.
+  _Configuration_ is the API that users of Tamaya will see, when they access 
configuration in raw format. Hereby +Configuration+
+     ** adds type support for non String types
+     ** provides functional extension points (+with,query+)
+     ** allows registering/deregistering of change listeners
+     ** is the entry point for evaluating the current +Configuration+
+     ** each +PropertySource+ can be easily converted into a +Configuration+
+     ** allows configuration entries to be injected
+     ** to access configuration _templates_ (annotated interfaces).
+     ** Configuration may support mutability by allowing instances of 
+ConfigChangeSet+ to be passed.
+* _PropertySourceBuilder_ allows to aggregate different property sources. 
Hereby property sources are
+  seen as sets, which can be combined to new sources using set styled 
operations (aggregation, intersection, subtraction).
+  This allows to model and create composite sources, to build up more complex 
configuration models
+  step by step.
+* _MetaInfo_ is provided by each +Configuration, PropertySource+ and describes 
the configuration/provider and its entries.
+* _Environment_ is the base model for modelling the environment and the 
accessor for getting the current +Environment+ instance.
+* _Annotations_ a set of annotations allows to configure configuration 
injection on classes or interface (aka config templates).
+
+The SPI contains the following core concepts/artifacts:
+
+* _ServiceContext_ is the delegate singleton that is used by the framework to 
resolve components. The effective component
+  loading can be accessed by implementing and registering an instance of 
+ServiceContextProvider+ using +java.util.ServiceLoader+.
+* All the singleton used explicitly (+Environment,Configuration+ are backed up 
corresponding API interfaces.
+  To override a singleton's behaviour the corresponding SPI has to be 
implemented and registered, so it can be loaded
+  by the current +ServiceContext+ setup (by default ServiceLoader based).
+* Also the singleton used implicitly by +Configuration, Environment+ are 
backed up corresponding SPI interfaces.
+  To override a singleton's behaviour the corresponding SPI has to be 
implemented and registered, so it can be loaded
+  by the current +ServiceContext+ setup (by default ServiceLoader based).
+
+This is also reflected in the main parts of the API, which is quite small:
+
+* +org.apache.tamaya+ contains the main abstractions +Configuration, 
ConfigQuery, PropertyAdapter,
+  Environment, PropertySource, MetaInfo+
+* +org.apache.tamaya.spi+ contains the SPI interfaces to be implemented by 
implementations and the +ServiceContext+ mechanism.
++ +org.apache.tamaya.annot+ contains the annotations defined.
+
+In the implementation are there are additional projects:
+
+* +org.apache.tamaya.core+ contains the core implementation of the API. 
Deploying it together with the API results in a
+  flexible framework that can be easily used for configuration of different 
complexity. But out of the box this framework
+  will not do much more than exposing system and environment properties, its 
power comes when an additional meta-model
+  is defined and deployed. Hereby you can write your own, or use on e of the 
provided ones (see later).
+* the core part is extended by multiple additional modules
+  ** CDI integration
+  ** Default configuration meta-models and providers for the most common usage 
scenarios
+    *** standalone applications
+    *** Java EE
+    *** ...
+
+These parts are explained in the following sections. It is recommended that 
user's of the API read through this part.
+All subsequent parts are building upon this concepts and may be more difficult 
to understand without having read
+this section.
+
+
+[[APIKeyValues]]
+=== Key/Value Pairs
+
+Basically configuration is a very generic concept. Therefore it should be 
modelled in a generic way. The most simple
+and similarly most commonly used are simple literal key/value pairs. So the 
core building block of {name} are key/value pairs.
+You can think of a common +.properties+ file, e.g.
+
+[source,properties]
+.A simple properties file
+--------------------------------------------
+a.b.c=cVal
+a.b.c.1=cVal1
+a.b.c.2=cVal2
+a=aVal
+a.b=abVal
+a.b2=abVal
+--------------------------------------------
+
+Now you can use +java.util.Properties+ to read this file and access the 
corresponding properties, e.g.
+
+[source,properties]
+.Accessing some properties
+--------------------------------------------
+Properties props = new Properties();
+props.readProperties(...);
+String val = props.getProperty("a.b.c");
+val = props.getProperty("a.b.c.1");
+...
+--------------------------------------------
+
+This looks familiar to most of you. Nevertheless when looking closer to the 
above key/value pairs,
+there are more concepts in place: looking at the keys +a.b.c+, +a.b.c.1+, 
+a.b.c.2+, +a+, +a.b+ we
+see that the key names build up a flattened tree structure. So we can define 
the following:
+
+Given a key +p1.p2.p3.k=value+:
+
+* +p1.p2.p3.k+ is called the _qualified key_
+* +p1.p2.p3+ is the key's _area_
+* the child areas +p1.p2", "p1+ are called _areas_ as well
+* +k+ is the _(unqualified) key_
+
+Given that you can perform some very useful actions:
+
+* you can filter the keys with an area. E.g. in the example before you can 
query for all keys within the area +a.b.c+
+  and map them to new properties set as follows:
+
+[source,properties]
+.Accessing an area
+--------------------------------------------
+1=cVal1
+2=cVal2
+--------------------------------------------
+
+Similarly accessing the area +a+ results in the following properties:
+
+[source,properties]
+.Accessing the area +a+
+--------------------------------------------
+b=abVal
+b2=abVal
+--------------------------------------------
+
+Additionally you can access all values of an area recursively, so accessing 
+a+ recursively results in
+the following properties:
+
+[source,properties]
+.Accessing area +a+ recursively
+--------------------------------------------
+b.c=cVal
+b.c.1=cVal1
+b.c.2=cVal2
+b=abVal
+b2=abVal
+--------------------------------------------
+
+Why this is useful? Well there are different use cases:
+
+* you can segregate your configuration properties, e.g. a module can access 
its module configuration by
+  querying all properties under the area +config.modules.myModule+ (or 
whatever would be appropriate).
+* you can use this mechanism to configure maps (or more generally: 
collections).
+* you can easily filter parts of configuration
+* ...and more.
+
+==== Why Using Strings Only
+
+Using Strings as base representation of configuration comes with several huge 
advantages:
+
+* Strings are simple to understand
+* Strings are human readable and therefore easy to prove for correctness
+* Strings can easily be used within different language, different VMs, files 
or network communications.
+* Strings can easily be compared and manipulated
+* Strings can easily be searched, indexed and cached
+* It is very easy to provide Strings as configuration, which gives much 
flexibility for providing configuration in
+  production as well in testing.
+* and more
+
+On the other side there are also disadvantages:
+
+* Strings are inherently not type safe, they do not provide validation out of 
the box for special types, such as
+numbers,
+  dates etc.
+* Often you want not to work with Strings, but with according types.
+* Strings are not hierarchical, so mapping hierarchical structures requires 
some extra efforts.
+
+Nevertheless most of these advantages can be mitigated easily, hereby still 
keeping all the benefits from above:
+
+* Adding type safe converters on top of String allow to add any type easily, 
that can be directly mapped out of Strings.
+  This includes all common base types such as numbers, dates, time, but also 
timezones, formatting patterns and more.
+* Even more complex mappings can be easily realized, by using String not as a 
direct representation of configuration,
+  but a reference that defines where the more complex configuration artifact 
is available. This mechanism is similarly
+  easy to understand as parsing Strings to numbers, but is powerful enough to 
provide e.g. all kind of deployment
+  descriptors in Java EE.
+* Hierarchical and collection types can be mapped in different ways:
+** The keys of configuration can have additional syntax/semantics. E.g. when 
adding dor-separating path semantics
+*** trees/maps can also simply be mapped.
+
+[API PropertySource]
+=== PropertySource
+==== Basic Model
+
+We have seen that constrain configuration aspects to simple literal key/value 
pairs provides us with an easy to
+understand, generic, flexible, yet expendable mechanism. Looking at the Java 
language features a +java.util.Map<String,
+String>+ and +java.util.Properties+ basically model these quite well out of 
the box.
+So it would make sense to build configuration on top of the JDK's +Map+ 
interface. This creates immediately additional
+benefits:
+
+* we inherit full Lambda and collection support
+* Maps are widely known and well understood
+
+Nevertheless there are some severe drawbacks:
+
+* +Configuration+ also requires meta-data, such as
+** the origin of a certain configuration entry and how it was derived from 
other values
+** the sensitivity of some data
+** the provider that have read the data
+** the time, when the data was read
+** the timestamp, when some data may be outdated
+** ...
+
+Basically the same is also the not related to some single configuration key, 
but also to a whole map.
+The +PropertySource+ interface models exact these aspects and looks as 
illustrated below:
+
+[source,java]
+.Interface PropertySource
+--------------------------------------------
+public interface PropertySource{
+
+      Optional<String> get(String key);
+      boolean containsKey(String key);
+      Map<String, String> toMap();
+      MetaInfo getMetaInfo();
+
+      default Set<String> keySet();
+      default ConfigChangeSet load();
+      default boolean isMutable();
+      default void apply(ConfigChangeSet change);
+}
+--------------------------------------------
+
+Hereby
+
+* +getMetaInfo()+ return the meta information for the property provider, as 
well as for individual property key/value pairs.
+* +get+ look similar to the methods on +Map+, though +get+ uses the +Optional+ 
type introduced
+  with Java 8. This avoids returning +null+ or throwing exceptions in case no 
such entry is available and also
+  reduced the API's footprint, since default values can be easily implemented 
by calling +Optional.orElse+.
+* +containsKey, keySet+ are as well methods similar to +java.util.Map+ though 
implementations may only returns
+  limited data, especially when the underlying map storage does not support 
iteration.
+* +isMutable()+ allows to easy check, if a property provider is mutable, which 
is more elegant than catching
+  +NonSupportedOperation+ exception thrown on the according methods of +Map+.
+* +load()+ finally allows to (re)load a property map. It depends on the 
implementing source, if this operation
+  has any effect. If the map changes an according +ConfigChange+ must be 
returned, describing the
+  changes applied.
+* +toMap+ allows to extract thing to a +Map+. Similar to +containsKey, keySet+ 
implementations may only return
+  a limited data map, especially when the underlying map storage does not 
support iteration.
+
+This simple model will be used within the spi, where configuration can be 
injected/provided from external resources.
+But we have seen, that we have to consider additional aspects, such as 
extendability and type safety. Therefore we
+extend +PropertySource+ and hereby also apply the 'composite pattern', which 
results in the following key abstraction.
+
+==== Meta Information
+
+Each instance also provides an instance of +MetaInfo+, which provides meta 
information for the providers and its properties:
+
+[source,java]
+.Accessing Meta Information
+--------------------------------------------
+PropertySource prov = ...;
+MetaInfo metaInfo = prov.getMetaInfo();
+Set<String> keys = metaInfo.keySet();  // returns the attribute keys, for 
which meta-information is accessible.
+String metaData = metaInfo.get("a.b.c.value"); // access meta information
+String itemName = metaInfo.getName(); // access meta information for the 
provider
+--------------------------------------------
+
+As we have seen above there is as well a +MetaInfoBuilder+, which must be used 
to create instances of
++MetaInfo+.
+
+==== Mutability
+
+Property sources optionally may be mutable. This can be checked by calling 
+boolean isMutable()+. If a source
+is mutable a +ConfigChangeSet+ can be passed. This change set can then be 
applied by the source. On creation
+of the +ConfigChangeSetBuilder+ a source can pass version information, so 
_optimistic locking_ can be implemented
+easily:
+
+[source,java]
+.Creating and applying a +ConfigChangeSet+ to a PropertySource
+--------------------------------------------
+PropertySource source = ...;
+ConfigChangeSet changeSet = ConfigChangeSetBuilder.of(provider)  // creating a 
default version
+   .remove("key1ToBeRemoved", +key2ToBeRemoved")
+   .put("key2", "key2Value")
+   .put("key3", 12345)
+   .put("key4", 123.45)
+   .build();
+source.apply(changeSet);
+--------------------------------------------
+
+
+[[API Configuration]]
+=== Configuration
+==== Basic Model
+
+Configuration inherits all basic features from +PropertySource+, but 
additionally adds functionality for
+type safety and extension mechanisms:
+
+[source,java]
+.Interface Configuration
+--------------------------------------------
+public interface Configuration extends PropertySource{
+
+    default Optional<Boolean> getBoolean(String key);
+    default OptionalInt getInteger(String key);
+    default OptionalLong getLong(String key);
+    default OptionalDouble getDouble(String key);
+    default <T> Optional<T> getAdapted(String key, PropertyAdapter<T> adapter);
+    <T> Optional<T> get(String key, Class<T> type);
+
+    // accessing areas
+    default Set<String> getAreas();
+    default Set<String> getTransitiveAreas();
+    default Set<String> getAreas(final Predicate<String> predicate);
+    default Set<String> getTransitiveAreas(Predicate<String> predicate);
+    default boolean containsArea(String key);
+
+    // extension points
+    default Configuration with(UnaryOperator<Configuration> operator);
+    default <T> T query(ConfigQuery<T> query);
+
+    // versioning
+    default String getVersion(){return "N/A";}
+
+    // singleton accessors
+    public static boolean isDefined(String name);
+    public static <T> T current(String name, Class<T> template);
+    public static Configuration current(String name);
+    public static Configuration current();
+    public static <T> T current(Class<T> type){
+    public static void configure(Object instance);
+    public static String evaluateValue(String expression);
+    public static String evaluateValue(Configuration config, String 
expression);
+    public static void addChangeListener(ConfigChangeListener listener);
+    public static void removeChangeListener(ConfigChangeListener listener);
+}
+--------------------------------------------
+
+Hereby
+
+* +XXX getXXX(String)+ provide type safe accessors for all basic wrapper types 
of the JDK.
+* +getAdapted+ allow accessing any type, hereby also passing a 
+PropertyAdapter+ that converts
+  the configured literal value to the type required.
+* +getAreas()+, +getTransitiveAreas()+ allow to examine the hierarchical tree 
modeled by the configuration tree.
+  Optionally also predicates can be passed to select only part of the tree to 
be returned.
+* +containsArea+ allows to check, if an area is defined.
+* +with, query+ provide the extension points for adding additional 
functionality.
+
+* the static accessor methods define:
+  ** +current(), current(Class), current(String), current(String, Class)+ 
return the configuration valid for the current runtime environment.
+  ** +addChangeListener, removeChangeListener+ allow to register or unregister
+     global config change listener instances.
+  ** evaluateValue allows to evaluate a configuration expression based on a 
given configuration.
+  ** +configure+ performs injection of configured values.
+
+[[TypeConversion]]
+==== Type Conversion
+
+Configuration extend +PropertySource+ and add additional support for non 
String types. This is achieved
+with the help of +PropertyAdapter+ instances:
+
+[source,java]
+.PropertyAdapter
+--------------------------------------------
+@FunctionalInterface
+public interface PropertyAdapter<T>{
+    T adapt(String value);
+}
+--------------------------------------------
+
+PropertyAdapter instances can be implemented manually or registered and 
accessed from the
++PropertyAdapers+ singleton. Hereby the exact mechanism is determined by the 
API backing up the singleton.
+By default corresponding +PropertyAdapter+ instances can be registered using 
the Java +ServiceLoader+
+mechanism, or programmatically ba calling the +register(Class, 
PropertyAdapter)+ method.
+
+[source,java]
+--------------------------------------------
+public final class PropertyAdapters{
+    public static <T> PropertyAdapter<T> register(Class<T> targetType, 
PropertyAdapter<T> adapter);
+    public static boolean isTargetTypeSupported(Class<?> targetType);
+    public static  <T> PropertyAdapter<T> getAdapter(Class<T> targetType);
+    public static  <T> PropertyAdapter<T> getAdapter(Class<T> targetType, 
WithPropertyAdapter annotation);
+}
+--------------------------------------------
+
+Whereas this mechanism per se looks not very useful it's power shows up when 
combining it with the annotations
+API provided, e.g. look at the following annotated class:
+
+[source,java]
+.Annotated Example Class
+--------------------------------------------
+public class ConfiguredClass{
+
+    @ConfiguredProperty
+    private String testProperty;
+
+    @ConfiguredProperty("a.b.c.key1")
+    @DefaultValue("The current \\${JAVA_HOME} env property is 
${env:JAVA_HOME}.")
+    String value1;
+
+    @ConfiguredProperty("a.b.c.key2")
+    private int value2;
+
+    @ConfiguredProperty
+    @DefaultValue("http://127.0.0.1:8080/res/api/v1/info.json";)
+    private URL accessUrl;
+
+    @ConfiguredProperty
+    @DefaultValue("5")
+    private Integer int1;
+
+    @ConfiguredProperty("a.b.customType")
+    private MyCustomType myCustomType;
+
+    @ConfiguredProperty("BD")
+    private BigDecimal bigNumber;
+
+    ...
+}
+--------------------------------------------
+
+The class does not show all the possibilities that are provided, but it shows 
that arbitrary types can be supported easily.
+This applied similarly to collection types, whereas collections are more 
advanced and therefore described in a separate section
+later.
+
+Given the class above and the current configuration can provide the values 
required, configuring an instance of the
+class is simple:
+
+[source,java]
+.Configuring the Example Class
+--------------------------------------------
+ConfiguredClass classInstance = new ConfiguredClass();
+Configuration.configure(configuredClass);
+--------------------------------------------
+
+Additional types can transparently be supported by implementing and 
registering corresponding SPI instances. This is explained
+in the SPI documentation of {name}.
+
+==== Extension Points
+
+We are well aware of the fact that this library will not be able to cover all 
kinds of use cases. Therefore
+we have added similar functional extension mechanisms that were used in other 
areas of the Java eco-system as well:
+
+* +ConfigOperator+ define unary operations on +Configuration+. They can be 
used for filtering, implementing
+  configuration views, security interception etc.
+* +ConfigQuery+ defines a function returning any kind of result based on a 
configuration instance. Typical
+  use cases of queries could be the implementation of configuration SPI 
instances that are required
+  by other libraries or frameworks.
+
+Both interfaces hereby are defined as functional interfaces:
+
+[source,java]
+.ConfigQuery
+--------------------------------------------
+@FunctionalInterface
+public interface ConfigQuery<T>{
+    T query(Configuration config);
+}
+--------------------------------------------
+
+Instances of this interface can be applied on a +Configuration+ instance:
+
+[source,java]
+.Applying Config operators and queries
+--------------------------------------------
+ConfigSecurity securityContext = 
Configuration.current().query(ConfigSecurity::targetSecurityContext);
+--------------------------------------------
+
+NOTE: +ConfigSecurity+ is an arbitrary class.
+
+Similarly an instance of +UnaryOpertor<Configuration>+ can be applied as well 
to decorate an existing +Configuration+
+instance:
+
+[source,java]
+.Applying Config operators
+--------------------------------------------
+Configuration secured = Configuration.current().with(ConfigSecurity::secure);
+--------------------------------------------
+
+=== Configuration Injection
+
+The +Configuration+ interface provides static methods that allow to anykind of 
instances be configured
+ny just passing the instances calling +Configuration.configure(instance);+. 
The classes passed hereby must
+be annotated with +@ConfiguredProperty+ to define the configured properties. 
Hereby this annotation can be
+used in multiple ways and combined with other annotations such as 
+@DefaultValue+,
++@WithLoadPolicy+, +@WithConfig+, +@WithConfigOperator+, 
+@WithPropertyAdapter+.
+
+To illustrate the mechanism below the most simple variant of a configured 
class is given:
+
+[source,java]
+.Most simple configured class
+--------------------------------------------
+pubic class ConfiguredItem{
+  @ConfiguredProperty
+  private String aValue;
+}
+--------------------------------------------
+
+When this class is configured, e.g. by passing it to 
+Configuration.configure(Object)+,
+the following is happening:
+
+* The current valid +Configuration+ is evaluated by calling +Configuration cfg 
= Configuration.of();+
+* The current property value (String) is evaluated by calling 
+cfg.get("aValue");+
+* if not successful, an error is thrown (+ConfigException+)
+* On success, since no type conversion is involved, the value is injected.
+* The configured bean is registered as a weak change listener in the config 
system's underlying
+  configuration, so future config changes can be propagated (controllable by 
applying the
+  +@WithLoadPolicy+ annotation).
+
+In the next example we explicitly define the property value:
+[source,java]
+--------------------------------------------
+pubic class ConfiguredItem{
+
+  @ConfiguredProperty
+  @ConfiguredProperty("a.b.value")
+  @configuredProperty("a.b.deprecated.value")
+  @DefaultValue("${env:java.version}")
+  private String aValue;
+}
+--------------------------------------------
+
+Within this example we evaluate multiple possible keys. Evaluation is aborted 
if a key could be successfully
+resolved. Hereby the ordering of the annotations define the ordering of 
resolution, so in the example above
+resolution equals to +"aValue", "a.b.value", "a.b.deprecated.value"+. If no 
value could be read
+from the configuration, it uses the value from the +@DefaultValue+ annotation. 
Interesting here
+is that this value is not static, it is evaluated by calling 
+Configuration.evaluateValue(Configuration, String)+.
+
+[[API ConfigurationBuilder]]
+==== Building Simple Configuration
+
+Looking at the structures of configuration system used by large companies we 
typically encounter some kind of configuration
+hierarchies that are combined in arbitrary ways. Users of the systems are 
typically not aware of the complexities in this
+area, since they simply know the possible locations, formats and the 
overriding policies. Framework providers on the other
+side must face the complexities and it would be very useful if Tamaya can 
support here by providing prebuilt functionality
+that helps implementing these aspects. All this leads to the feature set of 
combining property sources. Hereby the following
+strategies are useful:
+
+* aggregating configurations, hereby later configurations added
+  ** override any existing entries from earlier configurations
+  ** combine conflicting entries from earlier configurations, e.g. into a 
comma-separated structure.
+  ** may throw a ConfigException ig entries are conflicting
+  ** may only add entries not yet defined by former providers, preventing 
entries that are already present to be overwrite
+  ** any custom aggregation strategy, which may be a mix of above
+* intersecting configurations
+* subtracting configurations
+* filtering configurations
+
+These common functionality is provided by +ConfigurationBuilder+ instances. 
Additionally to the base strategies above a
++MetaInfo+ instance can be passed optionally as well to define the meta 
information for the newly created configuration.
+Let's assume we have two configurations with the following data:
+
+[source,properties]
+.Configuration 1
+--------------------------------------------
+a=a
+b=b
+c=c
+g=g
+h=h
+i=i
+--------------------------------------------
+
+[source,properties]
+.Configuration 2
+--------------------------------------------
+a=A
+b=B
+c=C
+d=D
+e=E
+f=F
+--------------------------------------------
+
+Looking in detail you see that the entries +a,b,c+ are present in both 
configurations, whereas +d,e,f+ are only present in Configuration 1,
+and +g,h,i+ only in Configuration 2.
+
+[source,java]
+.Example Combining Configurations
+--------------------------------------------
+Configuration cfg1 = ...
+Configuration cfg2 = ...
+
+// aggregate, hereby values from Configuration 2 override values from 
Configuration 1
+Configuration unionOverriding = ConfigurationBuilder.of().aggregate(cfg1, 
cfg2).build();
+System.out.println("unionOverriding: " + unionOverriding);
+
+// ignore duplicates, values present in Configuration 1 are not overriden by 
Configuration 2
+Configuration unionIgnoringDuplicates = ConfigurationBuilder.of()
+                       
.withAggregationPolicy(AggregationPolicy.IGNORE_DUPLICATES).aggregate(cfg1, 
cfg2).build();
+System.out.println("unionIgnoringDuplicates: " + unionIgnoringDuplicates);
+
+// this variant combines/maps duplicate values into a new value
+Configuration unionCombined = 
ConfigurationBuilder.of().withAggregationPolicy(AggregationPolicy.COMBINE)
+                       .aggregate(cfg1, cfg2);
+System.out.println("unionCombined: " + unionCombined);
+
+// This variant throws an exception since there are key/value paris in both 
providers, but with different values
+try{
+    
ConfigurationBuilder.of().withAggregationPolicy(AggregationPolicy.EXCEPTION).aggregate(provider1,
 provider2)
+                       .build();
+}
+catch(ConfigException e){
+    // expected!
+}
+--------------------------------------------
+
+The example above produces the following outpout:
+
+[source,listing]
+.Example Combining Configurations
+--------------------------------------------
+AggregatedConfiguration{
+  (name = dynamicAggregationTests)
+  a = "[a][A]"
+  b = "[b][B]"
+  c = "[c][C]"
+  d = "[D]"
+  e = "[E]"
+  f = "[F]"
+  g = "[g]"
+  h = "[h]"
+  i = "[i]"
+}
+unionOverriding: AggregatedConfigurations{
+  (name = <noname>)
+  a = "A"
+  b = "B"
+  c = "C"
+  d = "D"
+  e = "E"
+  f = "F"
+  g = "g"
+  h = "h"
+  i = "i"
+}
+unionIgnoringDuplicates: AggregatedConfigurations{
+  (name = <noname>)
+  a = "a"
+  b = "b"
+  c = "c"
+  d = "D"
+  e = "E"
+  f = "F"
+  g = "g"
+  h = "h"
+  i = "i"
+}
+unionCombined: AggregatedConfigurations{
+  (name = <noname>)
+  a = "a,A"
+  b = "b,B"
+  c = "c,C"
+  d = "D"
+  e = "E"
+  f = "F"
+  g = "g"
+  h = "h"
+  i = "i"
+}
+--------------------------------------------
+
+No +AggregationPolicy+ is also a functional interface that can be implemented:
+
+[source,java]
+.AggregationPolicy Interface
+--------------------------------------------
+@FunctionalInterface
+public interface AggregationPolicy {
+    String aggregate(String key, String value1, String value2);
+}
+--------------------------------------------
+
+So we can also define our own aggregation strategy using a Lambda expression:
+
+[source,java]
+.Use a Custom AggregationPolicy
+--------------------------------------------
+Configuration cfg1 = ...;
+Configuration cfg2 = ...;
+Configuration config = ConfigurationBuilder.of("dynamicAggregationTests")
+      .withAggregationPolicy((k, v1, v2) -> (v1 != null ? v1 : "") + '[' + v2 
+ "]")
+      .aggregate(cfg1, cfg2).build();
+System.out.println(config);
+--------------------------------------------
+
+Additionally we also create here an instance of +MetaInfo+. The output of this 
code snippet is as follows:
+
+[source,listing]
+.Listing of dynamic aggregation policy
+--------------------------------------------
+AggregatedConfiguration{
+  (name = dynamicAggregationTests)
+  a = "[a][A]"
+  b = "[b][B]"
+  c = "[c][C]"
+  d = "[D]"
+  e = "[E]"
+  f = "[F]"
+  g = "[g]"
+  h = "[h]"
+  i = "[i]"
+}
+--------------------------------------------
+
+Summarizing the +ConfigurationBuilder+ allows to combine providers in various 
forms:
+
+[source,listing]
+.Methods provided on PropertySources
+--------------------------------------------
+public final class ConfigurationBuilder {
+
+    private ConfigurationBuilder() {}
+
+    public static ConfigurationBuilder of();
+    public static ConfigurationBuilder of(PropertySource config);
+    public static ConfigurationBuilder of(MetaInfo metaInfo);
+    public static ConfigurationBuilder of(String name);
+
+    public ConfigurationBuilder withMetaInfo(MetaInfo metaInfo);
+    public ConfigurationBuilder withAggregationPolicy(AggregationPolicy 
aggregationPolicy);
+
+    public ConfigurationBuilder addArgs(String... args);
+    public ConfigurationBuilder addPaths(List<String> paths);
+    public ConfigurationBuilder addUrls(URL... urls);
+    public ConfigurationBuilder addUrls(List<URL> urls);
+    public ConfigurationBuilder addMap(Map<String, String> map);
+
+    public ConfigurationBuilder empty();
+    public ConfigurationBuilder empty(MetaInfo metaInfo);
+    public ConfigurationBuilder emptyMutable(MetaInfo metaInfo);
+    public ConfigurationBuilder addEnvironmentProperties();
+    public ConfigurationBuilder addSystemProperties();
+    public ConfigurationBuilder aggregate(Configuration... configs){
+    public ConfigurationBuilder aggregate(List<Configuration> configs) {
+    public ConfigurationBuilder mutable(Configuration config) {
+    public ConfigurationBuilder intersected(Configuration... providers) {
+    public ConfigurationBuilder subtracted(Configuration target, 
Configuration... providers) {
+    public ConfigurationBuilder filtered(Predicate<String> filter, 
Configuration config) {
+    public ConfigurationBuilder contextual(Supplier<Configuration> mapSupplier,
+                                              Supplier<String> 
isolationKeySupplier) {
+    public ConfigurationBuilder delegating(Configuration mainMap, Map<String, 
String> parentMap) {
+    public ConfigurationBuilder replacing(Configuration mainMap, Map<String, 
String> replacementMap);
+
+    public Configuration build();
+    public Configuration buildFrozen();
+}
+--------------------------------------------
+
+
+
+=== Environment
+
+The environment basically is also a kind of property/value provider similar to 
+System
+.getenv()+ in the JDK. Nevertheless it provides additional functionality:
+
+[source,java]
+.Interface Environment
+--------------------------------------------
+public interface Environment {
+
+    Optional<String> get(String key);
+    boolean containsKey(String key);
+    Set<String> keySet();
+    Map<String,String> toMap();
+
+    public static Environment current();
+    public static Environment root();
+--------------------------------------------
+
+* Basically an environment can contain any properties. The root environment
+  hereby must contain at least
+  ** all JDK's environment properties.
+  ** additional root properties are allowed as well.
+* the root environment is always directly accessible by calling 
+Environment.root()+
+* the current environment can be accessed by calling +Environment.current()+.
+
+Summarizing the Environment can be seen as a runtime context. This also 
implies, that this context changes
+depending on the current runtime context. Developers implementing an 
environment mechanism should be aware that
+an environment can be accessed very frequently, so evaluation and access of an 
+Environment+ must be fast. For
+further details we recommend the SPI details section of the core 
implementation.
+
+
+== SPI
+
+[[API PropertySourceBuilder]]
+==== Building Property Sources
+
+In [[PropertSource]] we have outlines that the essence of a property key store 
for configuration can be modelled by
+the +PropertySource+ interface. Similarly to the +ConfigurationBuilder+ you 
can also combine several +PropertySource+
+instances to assemble more complex configuration scenarios. Typically 
assembling is done within a +ConfigProvider+,
+which is responsible for providing correct Configuration corresponding to the 
current environment.
+
+Summarizing you can
+* aggregate providers, hereby later providers added
+  ** override any existing entries from earlier providers
+  ** combine conflicting entries from earlier providers, e.g. into a 
comma-separated structure.
+  ** may throw a ConfigException ig entries are conflicting
+  ** may only add entries not yet defined by former providers, preventing 
entries that are already present to be overwritten
+  ** any custom aggregation strategy, which may be a mix of above
+* intersecting providers
+* subtracting providers
+* filtering providers
+
+The following code snippet gives a couple of examples:
+
+[source,java]
+.Example Combining PropertySources
+--------------------------------------------
+PropertySource provider1 = ...
+PropertySource provider2 = ...
+
+// aggregate, hereby values from provider 2 override values from provider 1
+PropertySource unionOverriding = PropertySourceBuilder.of()
+             .aggregate(provider1, provider2).build(); // OVERRIDE policy is 
default
+System.out.println("unionOverriding: " + unionOverriding);
+
+// ignore duplicates, values present in provider 1 are not overriden by 
provider 2
+PropertySource unionIgnoringDuplicates = PropertySources
+             .aggregate(AggregationPolicy.IGNORE_DUPLICATES(), provider1, 
provider2).build();
+System.out.println("unionIgnoringDuplicates: " + unionIgnoringDuplicates);
+
+// this variant combines/maps duplicate values into a new value
+PropertySource unionCombined = 
PropertySourceBuilder.of().withAggregationPolicy(AggregationPolicy.COMBINE))
+            .aggregate(provider1, provider2).build();
+System.out.println("unionCombined: " + unionCombined);
+
+// This variant throws an exception since there are key/value paris in both 
providers, but with different values
+try{
+    
PropertySourceBuilder.of().withAggregationPolicy(AggregationPolicy.EXCEPTION).aggregate(provider1,
 provider2);
+}
+catch(ConfigException e){
+    // expected!
+}
+--------------------------------------------
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/src/main/asciidoc/design/3_Extensions.adoc
----------------------------------------------------------------------
diff --git a/docs/src/main/asciidoc/design/3_Extensions.adoc 
b/docs/src/main/asciidoc/design/3_Extensions.adoc
new file mode 100644
index 0000000..db949ac
--- /dev/null
+++ b/docs/src/main/asciidoc/design/3_Extensions.adoc
@@ -0,0 +1,841 @@
+// 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.
+<<<
+[[CoreConcepts]]
+== {name} Core Concepts
+Though {name} is a very powerful and flexible solution there are basically 
only a few simple core concepts required that build
+the base of all the other mechanisms:
+
+The API contains the following core concepts/artifacts:
+
+* Literal Key/Value Pairs
+* _PropertyProvider:_ is the the SPI for a source that provides configuration 
data. A +PropertyProvider+
+     hereby defines
+     ** a minimalistic SPI to be implemented by the config data source
+     ** provides data key/value pairs in raw format as String key/values only
+     ** providers should not have any dependencies other than to the datasource
+     ** providers may read context dependent data, but basically providers 
themselves are not contextual.
+        Context management should be done by the ConfigurationProvider 
implementation that also is responsible
+        for combining a set of property providers to a Configuration.
+  _Configuration_ is the API that users of Tamaya will see, when they access 
configuration in raw format. Hereby +Configuration+
+     ** adds type support for non String types
+     ** provides functional extension points (+with,query+)
+     ** allows registering/deregistering of change listeners
+     ** is the entry point for evaluating the current +Configuration+
+     ** each +PropertyProvider+ can be easily converted into a +Configuration+
+     ** allows configuration entries to be injected
+     ** to access configuration _templates_ (annotated interfaces).
+     ** Configuration may support mutability by allowing instances of 
+ConfigChangeSet+ to be passed.
+* _PropertyProviders_ allows to aggregate different property providers. Hereby 
property providers are
+  seen as sets, which can be combined to new providers using set styled 
operations (aggregate, intersect, subtract).
+  This allows to model and create composite container providers, to build up 
more complex configuration models
+  step by step.
+* _MetaInfo_ is provided by each +Configuration, PropertyProvider+ and 
describes the configuration/provider and its entries.
+* _Environment_ is the base model for modelling the environment and the 
accessor for getting the current +Environment+ instance.
+* _Annotations_ a set of annotations allows to configure configuration 
injection on classes or interface (aka config templates).
+
+The SPI contains the following core concepts/artifacts:
+
+* _Bootstrap_ is the delegate singleton that is used by the framework to 
resolve components. The effective component
+  loading can be accessed by implementing and registering an instance of 
+ServiceProvider+ using +java.util.ServiceLoader+.
+* All the singleton used explicitly (+PropertyAdapters,PropertyProviders+ are 
backed up corresponding API interfaces.
+  To override a singleton's behaviour the corresponding SPI has to be 
implemented and registered, so it can be loaded
+  by the current +Bootstrap+ setup (by default ServiceLoader based).
+* Also the singleton used implicitly by +Configuration, Environment, Stage+ 
are backed up corresponding SPI interfaces.
+  To override a singleton's behaviour the corresponding SPI has to be 
implemented and registered, so it can be loaded
+  by the current +Bootstrap+ setup (by default ServiceLoader based).
+
+This is also reflected in the main parts of the API, which is quite small:
+
+* +org.apache.tamaya+ contains the main abstractions +Configuration, 
ConfigOperator, ConfigQuery, PropertyAdapter, Stage,
+  Environment, PropertyProvider, MetaInfo+
+* +org.apache.tamaya.spi+ contains the SPI interfaces to be implemented by 
implementations and the +Bootstrap+ mechanism.
++ +org.apache.tamaya.annot+ contains the annotations defined.
+
+In the implementation are there are additional projects:
+
+* +org.apache.tamaya.core+ contains the core implementation of the API. 
Deploying it together with the API results in a
+  flexible framework that can be easily used for configuration of different 
complexity. But out of the box this framework
+  will not do much more than exposing system and environment properties, its 
power comes when an additional meta-model
+  is defined and deployed. Hereby you can write your own, or use on e of the 
provided ones (see later).
+* the core part is extended by multiple additional modules
+  ** CDI integration
+  ** Default configuration meta-models and providers for the most common usage 
scenarios
+    *** standalone applications
+    *** Java EE
+    *** ...
+
+These parts are explained in the following sections. It is recommended that 
user's of the API read through this part.
+All subsequent parts are building upon this concepts and may be more difficult 
to understand without having read
+this section.
+
+
+[[APIKeyValues]]
+=== Key/Value Pairs
+
+Basically configuration is a very generic concept. Therefore it should be 
modelled in a generic way. The most simple
+and similarly most commonly used are simple literal key/value pairs. So the 
core building block of {name} are key/value pairs.
+You can think of a common +.properties+ file, e.g.
+
+[source,properties]
+.A simple properties file
+--------------------------------------------
+a.b.c=cVal
+a.b.c.1=cVal1
+a.b.c.2=cVal2
+a=aVal
+a.b=abVal
+a.b2=abVal
+--------------------------------------------
+
+Now you can use +java.util.Properties+ to read this file and access the 
corresponding properties, e.g.
+
+[source,properties]
+.Accessing some properties
+--------------------------------------------
+Properties props = new Properties();
+props.readProperties(...);
+String val = props.getProperty("a.b.c");
+val = props.getProperty("a.b.c.1");
+...
+--------------------------------------------
+
+This looks familiar to most of you. Nevertheless when looking closer to the 
above key/value pairs,
+there are more concepts in place: looking at the keys +a.b.c+, +a.b.c.1+, 
+a.b.c.2+, +a+, +a.b+ we
+see that the key names build up a flattened tree structure. So we can define 
the following:
+
+Given a key +p1.p2.p3.k=value+:
+
+* +p1.p2.p3.k+ is called the _qualified key_
+* +p1.p2.p3+ is the key's _area_
+* the child areas +p1.p2", "p1+ are called _areas_ as well
+* +k+ is the _(unqualified) key_
+
+Given that you can perform some very useful actions:
+
+* you can filter the keys with an area. E.g. in the example before you can 
query for all keys within the area +a.b.c+
+  and map them to new properties set as follows:
+
+[source,properties]
+.Accessing an area
+--------------------------------------------
+1=cVal1
+2=cVal2
+--------------------------------------------
+
+Similarly accessing the area +a+ results in the following properties:
+
+[source,properties]
+.Accessing the area +a+
+--------------------------------------------
+b=abVal
+b2=abVal
+--------------------------------------------
+
+Additionally you can access all values of an area recursively, so accessing 
+a+ recursively results in
+the following properties:
+
+[source,properties]
+.Accessing area +a+ recursively
+--------------------------------------------
+b.c=cVal
+b.c.1=cVal1
+b.c.2=cVal2
+b=abVal
+b2=abVal
+--------------------------------------------
+
+Why this is useful? Well there are different use cases:
+
+* you can segregate your configuration properties, e.g. a module can access 
its module configuration by
+  querying all properties under the area +config.modules.myModule+ (or 
whatever would be appropriate).
+* you can use this mechanism to configure maps (or more generally: 
collections).
+* you can easily filter parts of configuration
+* ...and more.
+
+==== Why Using Strings Only
+
+Using Strings as base representation of configuration comes with several huge 
advantages:
+
+* Strings are simple to understand
+* Strings are human readable and therefore easy to prove for correctness
+* Strings can easily be used within different language, different VMs, files 
or network communications.
+* Strings can easily be compared and manipulated
+* Strings can easily be searched, indexed and cached
+* It is very easy to provide Strings as configuration, which gives much 
flexibility for providing configuration in
+  production as well in testing.
+* and more
+
+On the other side there are also disadvantages:
+
+* Strings are inherently not type safe, they do not provide validation out of 
the box for special types, such as
+numbers,
+  dates etc.
+* Often you want not to work with Strings, but with according types.
+* Strings are not hierarchical, so mapping hierarchical structures requires 
some extra efforts.
+
+Nevertheless most of these advantages can be mitigated easily, hereby still 
keeping all the benefits from above:
+
+* Adding type safe converters on top of String allow to add any type easily, 
that can be directly mapped out of Strings.
+  This includes all common base types such as numbers, dates, time, but also 
timezones, formatting patterns and more.
+* Even more complex mappings can be easily realized, by using String not as a 
direct representation of configuration,
+  but a reference that defines where the more complex configuration artifact 
is available. This mechanism is similarly
+  easy to understand as parsing Strings to numbers, but is powerful enough to 
provide e.g. all kind of deployment
+  descriptors in Java EE.
+* Hierarchical and collection types can be mapped in different ways:
+** The keys of configuration can have additional syntax/semantics. E.g. when 
adding dor-separating path semantics
+*** trees/maps can also simply be mapped.
+
+[APIPropertyProviders]
+=== Property Providers
+==== Basic Model
+
+We have seen that constrain configuration aspects to simple literal key/value 
pairs provides us with an easy to
+understand, generic, flexible, yet expendable mechanism. Looking at the Java 
language features a +vava.util.Map<String,
+String>+ and +java.util.Properties+ basically model these quite well out of 
the box.
+So it makes sense to build configuration on top of the JDK's +Map+ interface. 
This creates immediately additional
+benefits:
+
+* we inherit full Lambda and collection support
+* Maps are widely known and well understood
+
+Nevertheless there are some things to be considered:
+
+* Configuration also requires meta-data, such as
+** the origin of a certain configuration entry and how it was derived from 
other values
+** the sensitivity of some data
+** the provider that have read the data
+** the time, when the data was read
+** the timestamp, when some data may be outdated
+** ...
+
+Basically the same is also the not related to some single configuration key, 
but also to a whole map.
+The +PropertyProvider+ interface models exact these aspects and looks as 
illustrated below:
+
+[source,java]
+.Interface PropertyProvider
+--------------------------------------------
+public interface PropertyProvider{
+
+      Optional<String> get(String key);
+      boolean containsKey(String key);
+      Map<String, String> toMap();
+      MetaInfo getMetaInfo();
+
+      default Set<String> keySet();
+      default ConfigChangeSet load();
+      default boolean isMutable();
+      default void apply(ConfigChangeSet change);
+}
+--------------------------------------------
+
+Hereby
+
+* +getMetaInfo()+ return the meta information for the property provider, as 
well as for individual property key/value pairs.
+* +get, containsKey, keySet+ look similar to the methods on +Map+, though 
+get+ uses the +Optional+ type introduced
+  with Java 8. This avoids returning +null+ or throwing exceptions in case no 
such entry is available and also
+  reduced the API's footprint, since default values can be easily implemented 
by calling +Optional.orElse+.
+* +isMutable()+ allows to easy check, if a property provider is mutable, which 
is more elegant than catching
+  +NonSupportedOperation+ exception thrown on the according methods of +Map+.
+* +load()+ finally allows to (re)load a property map. It depends on the 
implementing source, if this operation
+  has any effect. If the map changes an according +ConfigChange+ must be 
returned, describing the
+  changes applied.
+* +hasSameProperties+ allows to perform a comparison with another provider.
+* +toMap+ allows to extract thing to a +Map+.
+
+This simple model will be used within the spi, where configuration can be 
injected/provided from external resources.
+But we have seen, that we have to consider additional aspects, such as 
extendability and type safety. Therefore we
+extend +PropertyMap+ and hereby also apply the 'composite pattern', which 
results in the following key abstraction.
+
+==== Meta Information
+
+Each instance also provides an instance of +MetaInfo+, which provides meta 
information for the providers and its properties:
+
+[source,java]
+.Accessing Meta Information
+--------------------------------------------
+PropertyProvider prov = ...;
+MetaInfo metaInfo = prov.getMetaInfo();
+Set<String> keys = metaInfo.keySet();  // returns the attribute keys, for 
which meta-information is accessible.
+String metaData = metaInfo.get("a.b.c.value"); // access meta information
+String itemName = metaInfo.getName(); // access meta information for the 
provider
+--------------------------------------------
+
+As we have seen above there is as well a +MetaInfoBuilder+, which must be used 
to create instances of
++MetaInfo+.
+
+==== Mutability
+
+Property providers optionally may be mutable. This can be checked by calling 
+boolean isMutable()+. If a provider
+is mutable a +ConfigChangeSet+ can be passed. This change set can then be 
applied by the provider. On creation
+of the +ConfigChangeSetBuilder+ a provider can pass version information, so 
_optimistic locking_ can be implemented
+easily:
+
+[source,java]
+.Creating and applying a +ConfigChangeSet+ to a provider
+--------------------------------------------
+PropertyProvider prov = ...;
+ConfigChangeSet changeSet = ConfigChangeSetBuilder.of(provider)  // creating a 
default version
+   .remove("key1ToBeRemoved", +key2ToBeRemoved")
+   .put("key2", "key2Value")
+   .put("key3", 12345)
+   .put("key4", 123.45)
+   .build();
+provider.apply(changeSet);
+--------------------------------------------
+
+[[API CombineProviders]]
+==== Combining Property Providers
+
+Looking at the structures of configuration system used by large companies we 
typically encounter some kind of configuration
+hierarchies that are combined in arbitrary ways. Users of the systems are 
typically not aware of the complexities in this
+area, since they simply know the possible locations, formats and the 
overriding policies. Framework providers on the other
+side must face the complexities and it would be very useful if Tamaya can 
support here by providing prebuilt functionality
+that helps implementing these aspects. All this leads to the feature set of 
combining property providers. Hereby the following
+strategies are useful:
+
+* aggregating providers, hereby later providers added
+  ** override any existing entries from earlier providers
+  ** combine conflicting entries from earlier providers, e.g. into a 
comma-separated structure.
+  ** may throw a ConfigExcepotion ig entries are conflicting
+  ** may only add entries not yet defined by former providers, preventing 
entries that are already present to be overwritte
+  ** any custom aggregation strategy, which may be a mix of above
+* intersecting providers
+* subtracting providers
+* filtering providers
+
+These common functionality is provided by the +PropertyProviders+ singleton. 
Additionally to the base strategies above a +MetaInfo+
+instance can be passed optionally as well to define the meta information for 
the newly created provider instances.
+Let's assume we have two property providers with the following data:
+
+[source,properties]
+.Provider 1
+--------------------------------------------
+a=a
+b=b
+c=c
+g=g
+h=h
+i=i
+--------------------------------------------
+
+[source,properties]
+.Provider 2
+--------------------------------------------
+a=A
+b=B
+c=C
+d=D
+e=E
+f=F
+--------------------------------------------
+
+Looking in detail you see that the entries +a,b,c+ are present in both 
providers, whereas +d,e,f+ are only present in provider 1,
+and +g,h,i+ only in provider 2.
+
+[source,java]
+.Example Combining PropertyProviders
+--------------------------------------------
+PropertyProvider provider1 = ...
+PropertyProvider provider2 = ...
+
+// aggregate, hereby values from provider 2 override values from provider 1
+PropertyProvider unionOverriding = 
PropertyProviders.aggregate(AggregationPolicy.OVERRIDE(), provider1, provider2);
+System.out.println("unionOverriding: " + unionOverriding);
+
+// ignore duplicates, values present in provider 1 are not overriden by 
provider 2
+PropertyProvider unionIgnoringDuplicates = 
PropertyProviders.aggregate(AggregationPolicy.IGNORE_DUPLICATES(), provider1, 
provider2);
+System.out.println("unionIgnoringDuplicates: " + unionIgnoringDuplicates);
+
+// this variant combines/maps duplicate values into a new value
+PropertyProvider unionCombined = 
PropertyProviders.aggregate(AggregationPolicy.COMBINE(), provider1, provider2);
+System.out.println("unionCombined: " + unionCombined);
+
+// This variant throws an exception since there are key/value paris in both 
providers, but with different values
+try{
+    PropertyProviders.aggregate(AggregationPolicy.EXCEPTION(), provider1, 
provider2);
+}
+catch(ConfigException e){
+    // expected!
+}
+--------------------------------------------
+
+The example above produces the following outpout:
+
+[source,listing]
+.Example Combining PropertyProviders
+--------------------------------------------
+AggregatedPropertyProvider{
+  (name = dynamicAggregationTests)
+  a = "[a][A]"
+  b = "[b][B]"
+  c = "[c][C]"
+  d = "[D]"
+  e = "[E]"
+  f = "[F]"
+  g = "[g]"
+  h = "[h]"
+  i = "[i]"
+}
+unionOverriding: AggregatedPropertyProvider{
+  (name = <noname>)
+  a = "A"
+  b = "B"
+  c = "C"
+  d = "D"
+  e = "E"
+  f = "F"
+  g = "g"
+  h = "h"
+  i = "i"
+}
+unionIgnoringDuplicates: AggregatedPropertyProvider{
+  (name = <noname>)
+  a = "a"
+  b = "b"
+  c = "c"
+  d = "D"
+  e = "E"
+  f = "F"
+  g = "g"
+  h = "h"
+  i = "i"
+}
+unionCombined: AggregatedPropertyProvider{
+  (name = <noname>)
+  a = "a,A"
+  b = "b,B"
+  c = "c,C"
+  d = "D"
+  e = "E"
+  f = "F"
+  g = "g"
+  h = "h"
+  i = "i"
+}
+--------------------------------------------
+
+No +AggregationPolicy+ is also an interface that can be implemented:
+
+[source,java]
+.AggregationPolicy Interface
+--------------------------------------------
+@FunctionalInterface
+public interface AggregationPolicy {
+    String aggregate(String key, String value1, String value2);
+}
+--------------------------------------------
+
+So we can also define our own aggregation strategy using a Lambda expression:
+
+[source,java]
+.Use a Custom AggregationPolicy
+--------------------------------------------
+PropertyProvider provider1 = ...;
+PropertyProvider provider2 = ...;
+PropertyProvider props = PropertyProviders.aggregate(
+      (k, v1, v2) -> (v1 != null ? v1 : "") + '[' + v2 + "]",
+      MetaInfo.of("dynamicAggregationTests"),
+      props1, props2);
+System.out.println(props);
+--------------------------------------------
+
+Additionally we also pass here an instance of +MetaInfo+. The output of this 
code snippet is as follows:
+
+[source,listing]
+.Listing of dynamic aggregation policy
+--------------------------------------------
+AggregatedPropertyProvider{
+  (name = dynamicAggregationTests)
+  a = "[a][A]"
+  b = "[b][B]"
+  c = "[c][C]"
+  d = "[D]"
+  e = "[E]"
+  f = "[F]"
+  g = "[g]"
+  h = "[h]"
+  i = "[i]"
+}
+--------------------------------------------
+
+Summarizing the +PropertyProviders+ singleton allows to combine providers in 
various forms:
+
+[source,listing]
+.Methods provided on PropertyProviders
+--------------------------------------------
+public final class PropertyProviders {
+
+    private PropertyProviders() {}
+
+    public static PropertyProvider fromArgs(String... args) {
+    public static PropertyProvider fromArgs(MetaInfo metaInfo, String... args) 
{
+    public static PropertyProvider fromPaths(AggregationPolicy 
aggregationPolicy, String... paths) {
+    public static PropertyProvider fromPaths(String... paths) {
+    public static PropertyProvider fromPaths(List<String> paths) {
+    public static PropertyProvider fromPaths(AggregationPolicy 
aggregationPolicy, List<String> paths) {
+    public static PropertyProvider fromPaths(MetaInfo metaInfo, List<String> 
paths) {
+    public static PropertyProvider fromPaths(AggregationPolicy 
aggregationPolicy, MetaInfo metaInfo, List<String> paths) {
+    public static PropertyProvider fromUris(URI... uris) {
+    public static PropertyProvider fromUris(AggregationPolicy 
aggregationPolicy, URI... uris) {
+    public static PropertyProvider fromUris(List<URI> uris) {
+    public static PropertyProvider fromUris(AggregationPolicy 
aggregationPolicy, List<URI> uris) {
+    public static PropertyProvider fromUris(MetaInfo metaInfo, URI... uris) {
+    public static PropertyProvider fromUris(AggregationPolicy 
aggregationPolicy, MetaInfo metaInfo, URI... uris) {
+    public static PropertyProvider fromUris(MetaInfo metaInfo, List<URI> uris) 
{
+    public static PropertyProvider fromUris(AggregationPolicy 
aggregationPolicy, MetaInfo metaInfo, List<URI> uris) {
+    public static PropertyProvider fromMap(Map<String, String> map) {
+    public static PropertyProvider fromMap(MetaInfo metaInfo, Map<String, 
String> map) {
+    public static PropertyProvider empty() {
+    public static PropertyProvider emptyMutable() {
+    public static PropertyProvider empty(MetaInfo metaInfo) {
+    public static PropertyProvider emptyMutable(MetaInfo metaInfo) {
+    public static PropertyProvider fromEnvironmentProperties() {
+    public static PropertyProvider fromSystemProperties() {
+    public static PropertyProvider freezed(PropertyProvider provider) {
+    public static PropertyProvider aggregate(AggregationPolicy mapping, 
MetaInfo metaInfo, PropertyProvider... providers){
+    public static PropertyProvider aggregate(PropertyProvider... providers) {
+    public static PropertyProvider aggregate(List<PropertyProvider> providers) 
{
+    public static PropertyProvider aggregate(AggregationPolicy mapping, 
PropertyProvider... propertyMaps) {
+    public static PropertyProvider aggregate(AggregationPolicy mapping, 
List<PropertyProvider> providers) {
+    public static PropertyProvider mutable(PropertyProvider provider) {
+    public static PropertyProvider intersected(AggregationPolicy 
aggregationPolicy, PropertyProvider... providers) {
+    public static PropertyProvider intersected(PropertyProvider... providers) {
+    public static PropertyProvider subtracted(PropertyProvider target, 
PropertyProvider... providers) {
+    public static PropertyProvider filtered(Predicate<String> filter, 
PropertyProvider provider) {
+    public static PropertyProvider contextual(Supplier<PropertyProvider> 
mapSupplier,
+                                              Supplier<String> 
isolationKeySupplier) {
+    public static PropertyProvider delegating(PropertyProvider mainMap, 
Map<String, String> parentMap) {
+    public static PropertyProvider replacing(PropertyProvider mainMap, 
Map<String, String> replacementMap) {
+}
+--------------------------------------------
+
+
+[[API Configuration]]
+=== Configuration
+==== Basic Model
+
+Configuration inherits all basic features from +PropertyProvider+, but 
additionally adds functionality for
+type safety and extension mechanisms:
+
+[source,java]
+.Interface Configuration
+--------------------------------------------
+public interface Configuration extends PropertyProvider{
+
+    default OptionalBoolean getBoolean(String key);
+    default OptionalInt getInteger(String key);
+    default OptionalLong getLong(String key);
+    default OptionalDouble getDouble(String key);
+    default <T> Optional<T> getAdapted(String key, PropertyAdapter<T> adapter);
+    <T> Optional<T> get(String key, Class<T> type);
+
+    // accessing areas
+    default Set<String> getAreas();
+    default Set<String> getTransitiveAreas();
+    default Set<String> getAreas(final Predicate<String> predicate);
+    default Set<String> getTransitiveAreas(Predicate<String> predicate);
+    default boolean containsArea(String key);
+
+    // extension points
+    default Configuration with(ConfigOperator operator);
+    default <T> T query(ConfigQuery<T> query);
+
+    // versioning
+    default String getVersion(){return "N/A";}
+    void addPropertyChangeListener(PropertyChangeListener l);
+    void removePropertyChangeListener(PropertyChangeListener l);
+
+    // singleton accessors
+    public static boolean isDefined(String name);
+    public static <T> T current(String name, Class<T> template);
+    public static Configuration current(String name);
+    public static Configuration current();
+    public static <T> T current(Class<T> type){
+    public static void configure(Object instance);
+    public static String evaluateValue(String expression);
+    public static String evaluateValue(Configuration config, String 
expression);
+    public static void addGlobalPropertyChangeListener(PropertyChangeListener 
listener);
+    public static void 
removeGlobalPropertyChangeListener(PropertyChangeListener listener);
+}
+--------------------------------------------
+
+Hereby
+
+* +XXX getXXX(String)+ provide type safe accessors for all basic wrapper types 
of the JDK.
+* +getAdapted+ allow accessing any type, hereby also passing a 
+PropertyAdapter+ that converts
+  the configured literal value to the type required.
+* +getAreas()+, +getTransitiveAreas()+ allow to examine the hierarchical tree 
modeled by the configuration tree.
+  Optionally also predicates can be passed to select only part of the tree to 
be returned.
+* +containsArea+ allows to check, if an area is defined.
+* +with, query+ provide the extension points for adding additional 
functionality.
+
+* the static accessor methods define:
+  ** +current(), current(Class), current(String), current(String, Class)+ 
return the configuration valid for the current runtime environment.
+  ** +addPropertyChangeListener, removePropertyChangeListener+ allow to 
register or unregister
+     global config change listener instances.
+  ** evaluateValue allows to evaluate a configuration expression based on a 
given configuration.
+  ** +configure+ performs injection of configured values.
+
+[[TypeConversion]]
+==== Type Conversion
+
+Configuration extend +PropertyProvider+ and add additional support for non 
String types. This is achieved
+with the help of +PropertyAdapter+ instances:
+
+[source,java]
+.PropertyAdapter
+--------------------------------------------
+@FunctionalInterface
+public interface PropertyAdapter<T>{
+    T adapt(String value);
+}
+--------------------------------------------
+
+PropertyAdapter instances can be implemented manually or registered and 
accessed from the
++PropertyAdapers+ singleton. Hereby the exact mechanism is determined by the 
API backing up the singleton.
+By default corresponding +PropertyAdapter+ instances can be registered using 
the Java +ServiceLoader+
+mechanism, or programmatically ba calling the +register(Class, 
PropertyAdapter)+ method.
+
+[source,java]
+--------------------------------------------
+public final class PropertyAdapters{
+    public static <T> PropertyAdapter<T> register(Class<T> targetType, 
PropertyAdapter<T> adapter);
+    public static boolean isTargetTypeSupported(Class<?> targetType);
+    public static  <T> PropertyAdapter<T> getAdapter(Class<T> targetType);
+    public static  <T> PropertyAdapter<T> getAdapter(Class<T> targetType, 
WithPropertyAdapter annotation);
+}
+--------------------------------------------
+
+Whereas this mechanism per se looks not very useful it's power shows up when 
combining it with the annotations
+API provided, e.g. look at the following annotated class:
+
+[source,java]
+.Annotated Example Class
+--------------------------------------------
+public class ConfiguredClass{
+
+    @ConfiguredProperty
+    private String testProperty;
+
+    @ConfiguredProperty("a.b.c.key1")
+    @DefaultValue("The current \\${JAVA_HOME} env property is 
${env:JAVA_HOME}.")
+    String value1;
+
+    @ConfiguredProperty("a.b.c.key2")
+    private int value2;
+
+    @ConfiguredProperty
+    @DefaultValue("http://127.0.0.1:8080/res/api/v1/info.json";)
+    private URL accessUrl;
+
+    @ConfiguredProperty
+    @DefaultValue("5")
+    private Integer int1;
+
+    @ConfiguredProperty("a.b.customType")
+    private MyCustomType myCustomType;
+
+    @ConfiguredProperty("BD")
+    private BigDecimal bigNumber;
+
+    ...
+}
+--------------------------------------------
+
+The class does not show all the possibilities that are provided, but it shows 
that arbitrary types can be supported easily.
+This applied similarly to collection types, whereas collections are more 
advanced and therefore described in a separate section
+later.
+
+Given the class above and the current configuration can provide the values 
required, configuring an instance of the
+class is simple:
+
+[source,java]
+.Configuring the Example Class
+--------------------------------------------
+ConfiguredClass classInstance = new ConfiguredClass();
+Configuration.configure(configuredClass);
+--------------------------------------------
+
+Additional types can transparently be supported by implementing and 
registering corresponding SPI instances. This is explained
+in the SPI documentation of {name}.
+
+==== Extension Points
+
+We are well aware of the fact that this library will not be able to cover all 
kinds of use cases. Therefore
+we have added similar functional extension mechanisms that were used in other 
areas of the Java eco-system as well:
+
+* +ConfigOperator+ define unary operations on +Configuration+. They can be 
used for filtering, implementing
+  configuration views, security interception etc.
+* +ConfigQuery+ defines a function returning any kind of result based on a 
configuration instance. Typical
+  use cases of queries could be the implementation of configuration SPI 
instances that are required
+  by other libraries or frameworks.
+
+Both interfaces hereby are defined as functional interfaces:
+
+[source,java]
+.ConfigOperator and ConfigQuery
+--------------------------------------------
+@FunctionalInterface
+public interface ConfigOperator{
+    Configuration operate(Configuration config);
+}
+
+@FunctionalInterface
+public interface ConfigQuery<T>{
+    T query(Configuration config);
+}
+--------------------------------------------
+
+Both interfaces can be applied on a +Configuration+ instance:
+
+[source,java]
+.Applying Config operators and queries
+--------------------------------------------
+Configuration secured = Configuration.of().apply(ConfigSecurity::secure);
+ConfigSecurity securityContext = 
Configuration.of().query(ConfigSecurity::targetSecurityContext);
+--------------------------------------------
+
+NOTE: +ConfigSecurity+ is an arbitrary class.
+
+=== Configuration Injection
+
+The +Configuration+ interface provides static methods that allow to anykind of 
instances be configured
+ny just passing the instances calling +Configuration.configure(instance);+. 
The classes passed hereby must
+be annotated with +@ConfiguredProperty+ to define the configured properties. 
Hereby this annotation can be
+used in multiple ways and combined with other annotations such as 
+@DefaultValue+,
++@WithLoadPolicy+, +@WithConfig+, +@WithConfigOperator+, 
+@WithPropertyAdapter+.
+
+To illustrate the mechanism below the most simple variant of a configured 
class is given:
+
+[source,java]
+.Most simple configured class
+--------------------------------------------
+pubic class ConfiguredItem{
+  @ConfiguredProperty
+  private String aValue;
+}
+--------------------------------------------
+
+When this class is configured, e.g. by passing it to 
+Configuration.configure(Object)+,
+the following is happening:
+
+* The current valid +Configuration+ is evaluated by calling +Configuration cfg 
= Configuration.of();+
+* The current property value (String) is evaluated by calling 
+cfg.get("aValue");+
+* if not successful, an error is thrown (+ConfigException+)
+* On success, since no type conversion is involved, the value is injected.
+* The configured bean is registered as a weak change listener in the config 
system's underlying
+  configuration, so future config changes can be propagated (controllable by 
applying the
+  +@WithLoadPolicy+ annotation).
+
+In the next example we explicitly define the property value:
+[source,java]
+--------------------------------------------
+pubic class ConfiguredItem{
+
+  @ConfiguredProperty
+  @ConfiguredProperty("a.b.value")
+  @configuredProperty("a.b.deprecated.value")
+  @DefaultValue("${env:java.version}")
+  private String aValue;
+}
+--------------------------------------------
+
+Within this example we evaluate multiple possible keys. Evaluation is aborted 
if a key could be successfully
+resolved. Hereby the ordering of the annotations define the ordering of 
resolution, so in the example above
+resolution equals to +"aValue", "a.b.value", "a.b.deprecated.value"+. If no 
value could be read
+from the configuration, it uses the value from the +@DefaultValue+ annotation. 
Interesting here
+is that this value is not static, it is evaluated by calling 
+Configuration.evaluateValue(Configuration, String)+.
+
+=== Environment
+
+The environment basically is also a kind of property/value provider similar to 
+System.getProperties()+ and +System
+.getenv()+ in the JDK. Nevertheless it provides additional functionality:
+
+[source,java]
+.Interface Environment
+--------------------------------------------
+public interface Environments {
+
+    String getEnvironmentType();
+    String getEnvironmentId();
+    Environment getParentEnvironment();
+
+    Optional<String> get(String key);
+    boolean containsKey(String key);
+    Set<String> keySet();
+    Map<String,String> toMap();
+
+    public static Environment current(){
+    public static Environment getRootEnvironment(){
+    public static List<String> getEnvironmentTypeOrder(){
+    public static List<String> getEnvironmentHierarchy(){
+    public static Optional<Environment> getInstance(String environmentType, 
String contextId){
+    public static Set<String> getEnvironmentContexts(String environmentType){
+    public static boolean isEnvironmentActive(String environmentType){
+--------------------------------------------
+
+* environments are hierarchical. Hereby all environments inherit from the root 
environment. The root environment
+  hereby must contain
+  ** all JDK's system properties, with same keys, values
+  ** all JDK's environment properties, prefixed with +env:+.
+  ** additional root properties are allowed as well.
+* the root environment is always directly accessible by calling 
+Environment.getRootEnvironment()+
+* the current environment can be accessed by calling +Environment.of()+.
+* each environment also defines a +Stage+ (implementing +StageSupplier+). 
Hereby, if not set explicitly the +Stage+ is inherited from the root
+  environment. Consequently the root environment must provide a +Stage+, which 
by default is +Stage.development()+.
+
+Additionally each environment instance is uniquely identified by the 
environment type (accessible from
++getEnvironmentType()+ and the environment id (accessible from 
+getEnvironmentId()+). So it is possible to access
+an +Environment+ by calling +of(String environmentType, String 
environmentId)+. Implementations may restrict access
+to environments depending on the current runtime environment (runtime context) 
active. The API does
+not require further aspects.
+
+The call to +getEnvironmentIds(String)+ returns all context ids of the known 
+Environment+ instances
+of a given type. E.g. assuming there is an environment type +war+ calling 
+Environment.getEnvironmentIds("war")+
+may return +"/web/app1", "/web/app2"+ (assuming the war context ids equal the 
web applications root contexts).
+
+All environments are basically ordered. The ordering can be accessed by 
calling +getEnvironmentTypeOrder()+. Hereby
+not every environment type in a hierarchy must necessarily present. This is 
reflected by +getEnvironmentHierarchy()+
+which returns the environment type ids in order, but only containing the types 
of the environments
+currently present and accessible in the hierarchy. As an example an 
environment type order in an advanced
+use case could be something like +"root","ear","war","saas","user"+, whereas 
the concrete environment type hierarchy
+may be +"root","war","saas"+, because the application was not included
+in an additional ear archive and no user is currently active (anonymous). The 
call to +isEnvironmentActive(String)+
+allows to determine if an environment of the given type is currently active.
+Finally the environment hierarchy is of course similarly reflected by the 
relationship (+getParentEnvironment()+).
+The following code should illustrate some of these concepts:
+
+[source,java]
+.Interface Environment
+--------------------------------------------
+List<String> envHierarchy = Environment.getEnvironmentHierarchy();
+  // -> "root","war","saas"
+Environment env = Environment.of();
+System.out.println(env.getEnvironmentContext()); // saas
+System.out.println(env.getEnvironmentId());      // mysolution_pro
+env = env.getParentEnvironment();
+System.out.println(env.getEnvironmentContext()); // war
+System.out.println(env.getEnvironmentId());      // pro
+env = env.getParentEnvironment();
+System.out.println(env.getEnvironmentContext()); // root
+System.out.println(env.getEnvironmentId());      // system
+env = env.getParentEnvironment();
+// env is null now!
+--------------------------------------------
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/src/main/asciidoc/design/4_ImplementationCore.adoc
----------------------------------------------------------------------
diff --git a/docs/src/main/asciidoc/design/4_ImplementationCore.adoc 
b/docs/src/main/asciidoc/design/4_ImplementationCore.adoc
new file mode 100644
index 0000000..2233002
--- /dev/null
+++ b/docs/src/main/asciidoc/design/4_ImplementationCore.adoc
@@ -0,0 +1,47 @@
+// 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.
+<<<
+[[CoreConcepts]]
+== {name} Core Implementation Concepts
+Tamaya comes with an implementation module that implements the Tamaya API. The 
API itself does only provide the API for configuration usage.
+Especially it does not define how the current runtime +Environment+ is mapped 
to a +Configuration+. This the gaop that should be solved
+by the core library.
+
+The high level packages give you a good overview of the functionality provided:
+
+* +org.apache.tamaya.core+ is the root package of the Tamaya core 
implementation.
+* +org.apache.tamaya.core.config+ provides
+
+
+
+The SPI contains the following core concepts/artifacts:
+
+* _Bootstrap_ is the delegate singleton that is used by the framework to 
resolve components. The effective component
+  loading can be accessed by implementing and registering an instance of 
+ServiceProvider+ using +java.util.ServiceLoader+.
+* All the singleton used explicitly (+PropertyAdapters,PropertyProviders+ are 
backed up corresponding API interfaces.
+  To override a singleton's behaviour the corresponding SPI has to be 
implemented and registered, so it can be loaded
+  by the current +Bootstrap+ setup (by default ServiceLoader based).
+* Also the singleton used implicitly by +Configuration, Environment, Stage+ 
are backed up corresponding SPI interfaces.
+  To override a singleton's behaviour the corresponding SPI has to be 
implemented and registered, so it can be loaded
+  by the current +Bootstrap+ setup (by default ServiceLoader based).
+
+This is also reflected in the main parts of the API, which is quite small:
+
+* +org.apache.tamaya+ contains the main abstractions +Configuration, 
ConfigOperator, ConfigQuery, PropertyAdapter, Stage,
+  Environment, PropertyProvider, MetaInfo+
+* +org.apache.tamaya.spi+ contains the SPI interfaces to be implemented by 
implementations and the +Bootstrap+ mechanism.
++ +org.apache.tamaya.annot+ contains the annotations defined.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/src/main/asciidoc/design/Design.adoc
----------------------------------------------------------------------
diff --git a/docs/src/main/asciidoc/design/Design.adoc 
b/docs/src/main/asciidoc/design/Design.adoc
new file mode 100644
index 0000000..4865ca1
--- /dev/null
+++ b/docs/src/main/asciidoc/design/Design.adoc
@@ -0,0 +1,117 @@
+Apache Tamaya -- Design Documentation
+=====================================
+:name: Tamaya
+:rootpackage: org.apache.tamaya
+:title: Apache Tamaya
+:revnumber: 0.1-SNAPSHOT
+:revremark: Incubator
+:revdate: November 2014
+:longversion: {revnumber} ({revremark}) {revdate}
+:authorinitials: ATR
+:author: Anatole Tresch, Anatole Tresch
+:email: <atsti...@gmail.com>
+:source-highlighter: coderay
+:website: http://tamaya.incubator.apache.org/
+:iconsdir: {imagesdir}/icons
+:toc:
+:toc-placement: manual
+:icons:
+:encoding: UTF-8
+:numbered:
+
+'''
+
+<<<
+
+-> add image : : 
https://raw.githubusercontent.com/JavaConfig/config-api/master/src/main/asciidoc/images/javaconfig.jpg[]
+
+toc::[]
+
+<<<
+:numbered!:
+-----------------------------------------------------------
+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.
+-----------------------------------------------------------
+
+:numbered:
+
+<<<
+
+== Introduction
+This document describes the {name} API for Configuration. The technical 
objective is to provide a
+unified configuration model in Java, targeting Java ME, SE as well as the EE 
platform.
+The API will provide support for key/value based application configuration. It 
will provide
+as well higher level APIs that are based on the low level ke</value pairs. 
Finally it will
+provide extension points for adding additional features and additional modules 
for extension
+or adaption.
+
+=== Working Group
+This work is being conducted as part of a community lead joint effort under 
the Apache Software Foundation. This
+specification is the result of the collaborative work of the members of the 
{name} Users Group and the community at
+large. Currently the project is lead by Anatole Tresch (atsticks at gmail.dot 
com).
+
+=== Goals
+Configuration is a key feature in all kind of programming languages. Basically 
configuration is the parametrization of
+well defined aspects of a software product without having to recompile/rebuild 
the code.
+
+==== Targets
+{name} targets to support all general configuration aspects, e.g.
+
+* spplication configuration
+** plugins
+** modules
+** components
+* Configuration of Java EE related aspects for Java enterprise application 
portability and dynamic provisioning, such as
+** Configuration of CDI (interceptors, decorators and alternatives)
+** Configuration of Bean Validation, JSF, web applications etc.
+* Configuration of instances within Java SE, e.g. by passing instances to a 
method that injects configured values, or by providing
+  accessors to evaluate current configuration vlues. This can be used 
explicitly or transparently by client code.
+
+Additionally the solution should support
+
+* multiple configuration locations, including remote locations
+* multiple configuration formats, including custom formats
+* multiple configuration loading mechanisms, including custom mechanisms. By 
default reading the classpath, files und URIs are supported by default.
+* type conversion
+* configuration of collections
+
+
+=== Required Java version
+The API is based on Java SE 8.0 language features.
+
+=== How this document is organized
+There are five main section in this document:
+
+* Use cases.
+* Requirements.
+* Specification.
+* Implementation Recommendations.
+* An appendix.
+
+<<<
+include::src/main/asciidoc/design/0_UseCases.adoc[]
+
+<<<
+include::src/main/asciidoc/design/1_Requirements.adoc[]
+
+<<<
+include::src/main/asciidoc/design/2_CoreConcepts.adoc[]
+
+:numbered!:
+== APPENDIX
+

Reply via email to