You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2014/12/17 00:26:30 UTC

[1/4] incubator-tamaya git commit: TAMAYA-29: Removed stage. TAMAYA-19: Simplified environment model. -> Updated docs.

Repository: incubator-tamaya
Updated Branches:
  refs/heads/master 0b3b96393 -> cd513bf36


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/tasks.adoc
----------------------------------------------------------------------
diff --git a/docs/tasks.adoc b/docs/tasks.adoc
deleted file mode 100644
index a0040d6..0000000
--- a/docs/tasks.adoc
+++ /dev/null
@@ -1,388 +0,0 @@
-Apache Tamaya - Possible Tasks
-==============================
-:name: Tamaya
-:rootpackage: org.apache.tamaya
-:title: Apache Tamaya
-:revnumber: 0.1-SNAPSHOT
-:revremark: Draft
-:revdate: October 2014
-:longversion: {revnumber} ({revremark}) {revdate}
-:authorinitials: ATR
-:author: Anatole Tresch
-:email: <at...@gmail.com>
-:source-highlighter: coderay
-:website: http://tamaya.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
-
-== What is Tamaya
-
-{name} is the Apache standard for flexible and powerful configuration. Objective is to provide flavors for
-Java SE, ME as well as to ship with powerful features for Java EE and Cloud Solutions. All functions provided
-is build on top of a small but very powerful, flexible and extendible API. This API is implemented by a core implementation,
-which then can be extended or adapted for use in different runtime scenarios, such as SE, ME, EE, Spring, OSGI
-and more. Similarly additional modules may be provided that help also existing solution to be plugged into
-{name}, so you can start right away using {name} without having to rebuild/change your existing application.
-
-== Main Features of {name}
-
-The main features of {name} currently are
-
-* *A simple key/value store*, named +PropertyProvider+ (simply called "provider").
-* Simple *built-in meta-data model*, that allows to easily attach metadata to a provider or single property keys.
-* Support for *different configuration formats*.
-* Support for *different configuration locations*, including remote locations.
-* Powerful and flexible *options to combine providers to new composite providers* using different combination policies.
-* The *Configuration model* adds additional features:
-** *Type Adapters* allow to convert configuration into any required target type.
-** *Built-in support* for all basic Java types.
-* *Contextual, hierarchical and multi-layered environment model*. The model is rather simple, but nevertheless
-  powerful enough to map complex layered runtime environments such as Java EE or multi-tenant SaaS solutions.
-* *Configurable System Properties* allow to tweak system properties to behave contextually.
-* *Templates* provide a type safe configuration mechanism where an annotated interface is implemented by the
-  configuration system, providing data from an underlying configuration.
-* *Configuration Injection* allows configured values to be directly injected into the bean's configured.
-* *Loading Policies* allow to control how configuration changes are reflected on the configured beans.
-* *Configuration Operators and Queries* can be used to easily implement advanced features such as *Views,
-  Security Constraints and Filters*.
-* Provider and configuration changes can be observed by registering *PropertyChangeListeners*.
-* Configurations are *versioned*, so remote pull scenarios can be implemented very efficiently.
-* The system supports *multiple configurations* identified by name.
-* The configuration system provides a powerful management console for reading and updating of configuration.
-* The system also supports distributed configuration scenarios by leveraging existing solutions, such as Memcached,
-  Hazelcast or Zookeper.
-* The system is built on "Java 8 features*.
-* A *Java 7 Backport* is provided.
-
-=== Purpose of this Document
-
-The document should help to organize people and ideas around the Apache Tamaya Library. It list possible features,
-ideas and tasks that need to be done. Everybody can have a look at and see, where hos contribution and capabilities
-would fit best.
-
-== Basics
-
-=== Styles, Logo
-
-The project requires
-
-* a good Apache styled logo and
-* CSS styles as needed,
-* an initial web page,
-* a twitter account
-* ...
-
-=== Infrastructure
-
-We should setup all needed infrastructure
-* code repos
-* project modules (including module sites)
-* coding and documentation guidelines
-* automatic builds (CI), included automatic coverage and sonar quality checks.
-* a docker image or appliance, with everything setup, so contributors can easily
-  start contributing...
-* ...
-
-== Main Features
-
-=== Metadata Model
-
-Currently +MetaInfo+ models metadata as a separate constuct. It has been shown that this leads to more complex
-handling when creating composites and makes the API overall more complex. The idea is to model metadata as simple
-key/value pairs, that are part of the provider/configuration data as well, but handled separately. Metadata hereby
-is identified by a starting '_' character in its key. For example refer to the following configuration properties:
-
-[source,listing]
-.Basic Properties
-----------------------------------------------------------------
-a.b.Foo=foo
-a.b.Bar=bar
-a.AnyOther=whatelse
-Something=none
-----------------------------------------------------------------
-
-Now we can model meta-data as follows:
-
-[source,listing]
-.Metadata Properties
-----------------------------------------------------------------
-[a.b].info=An area info
-[a.b.Foo].auth=role1,role2
-[a.b.Foo].encrypt=PGP
-[a.b.Foo].sensitive=true
-[].info=This is a test configuration example.
-----------------------------------------------------------------
-
-The above would model the following:
-
-* The area +a.b+ has the meta property +info+.
-* The entry +a.b.Foo+ has three meta properties +auth,encrypt+ and +sensitive+. These could be interpreted by a security
-  view and used to encrypt the values returned by the configuration instance, if not the current user has one of the
-  specified roles.
-* The last meta data defines an attribute +info+ for the whole provider/configuration (the root area).
-
-Given that the overall entries would be as follows:
-
-[source,listing]
-.Full Properties with Meta Properties
-----------------------------------------------------------------
-[a.b].info=An area info
-a.b.Foo=foo
-[a.b.Foo].auth=role1,role2
-[a.b.Foo].encrypt=PGP
-[a.b.Foo].sensitive=true
-a.b.Bar=bar
-[].info=This is a test configuration example.
-a.AnyOther=whatelse
-Something=none
-----------------------------------------------------------------
-
-The current +MetaInfo+ class could be adapted, so it is reading data from the underlying configuration/provider,
-instead of its own datastructure. This would make a later mapping of configuration and its metadata into DB table, JSON
-etc, much more easier.
-The providers on the other side may suppress any metadata from ordinary output, such
-as +toString()+, Similarly accessing metadata using the official config API (+get, getOrDefault, getAreas+ etc)
-should be disabled. The +MetaInfoBuilder+ must probably as well adapted or redesigned.
-
-=== Collection Support
-
-Add a key/value based model for mapping collections such as sets, maps, list. Implement according adapters.
-In combination with the metadata model above this could be something like:
-
-[source,listing]
-.Collection Support
-----------------------------------------------------------------
-mySet=[a,b,c,d,e\,e,f]
-[mySet].type=set
-#optional define the implementation class
-[mySet].class=java.util.TreeSet
-
-myList=[a,b,c,d,e\,e,f]
-[myList].type=list
-#optional define the implementation class
-[myList].class=java.util.ArrayList
-
-myMap=[a:aa,b:bb,c:cc,d:dd,e:e\,e,f:ff]
-[myMap].type=map
-#optional define the implementation class
-[myMap].class=java.util.TreeMap
-
-#Finally we could also add support for non String based types
-myTypedSet=[1,2,3,4.5,6,7.10.123]
-[myTypedSet].contentClass=java.lang.Double
-myTypedList=[CHF 10.20, EUR 12.20, BTC 0.002]
-[myTypedList].contentType=org.javamoney.moneta.FastMoney
-myTypedMap=[CHF:CHF 10.20, EUR:EUR 12.20, BTC:BTC 0.002]
-[myTypedMap].contentTypes=javax.money.CurrencyUnit,javax.money.MonetaryAmount
-----------------------------------------------------------------
-
-
-=== Management Service
-
-A JMX/Restful API should be designed and built that exposes configuration information. Access should be secured, e.g.
-using OAuth or other security mechasnisms.
-
-=== Management Client
-
-A nice web-based client to manage configuration data would be nice as well. This also includes a UI for creating new
-configurations.
-
-=== Mapping Configuration to a Database
-
-A flexible mechanism should be implemented that allows the use of databases (SQL/JPA as well as non-SQL) for
-storing/retreiving/managing configuration:
-
-* JPA, Hibernate
-* MongoDB
-* ...
-
-=== Integration with OSGI
-
-Examples are to be created and tested, where OSGI is used as the basic runtime platform, e.g. Apache Felix, but as well
-others.
-
-=== Integration with Jigsaw
-
-Once Jigsaw is mature and in a usable (still early) stage, examples are to be created and tested, where OSGI is used as
-the basic runtime platform, e.g. Apache Felix, but as well others.
-
-== Distributed/Remote Configuration Support
-
-=== Configuration Server
-
-A configuration server should be implemented that provides access to configurations and triggers updates to registered
-clients (push). Similarly a poull model should be supported, where clients can asl for the current version id of a certain
-configuration and reload it if necessary.
-
-=== Configuration Distribution Policies
-
-Different configuration distribution policies should be defined any implemented, e.g. distributed cache, restful services,
-web services, EJB/RMI calls, asynchronous queues, publish/subsribe models, ...
-
-=== Dynamic Service Lookup
-
-Configuration Servers and Clients should bea ble to locate each other in different ways:
-
-* with fixed configured IPs, or IP ranges
-* using a dynamic service location protocol like
-** SLP
-** Distributed Maps/Datagrids
-** Apache Zookeeper
-
-=== Configuration Client
-
-A subset of the API would be created that exposes only a well defined subset, of exactly one configuration targeted
-to a certain instance, VM or whatever. The client should be connectable to a server in different ways (see configuration
-distributiont policies).
-
-=== Preferences Support
-
-Write a +PreferencesFactory+ for +java.util.preferences+.
-
-== Third Party Integration
-
-=== Integration with Deltaspike Config
-
-Integration with Deltaspike Config should be implemented and discussed with Deltaspike guys.
-
-=== Integration with Spring
-
-A {name} module should be created that allows Spring to be used either as client or configuration provider.
-
-=== Integration with Jetty
-
-A {name} module should be created that allows a Jetty instance to be deployed and started that is (completely)
-configured based on configuration server.
-
-=== Integration with Tomcat
-
-A {name} module should be created that allows a Tomcat instance to be deployed and started that is (completely)
-configured based on configuration server.
-
-=== Configuration of Java EE
-
-In the Java EE area there would be several options:
-
-=== Configuration of Application Servers (administrative resources)
-
-It should be possible to start a application server instance remotely and configure all administrative resources and the
-deployments based on the configuration service, server to be considered maybe
-
-* Wildfly
-* IBM
-* Weblogic
-* Glassfish
-* Apache Geronimo
-
-==== Configuration of CDI
-
-Implement a CDI extension that controls CDI based on configuration:
-* Add beans
-* Remove (veto) beans
-* Add/remove interceptors
-* Add/remove decorators
-* Activate alternatives
-* ...
-
-==== Configuration of Bean Validation
-
-* Add configurable validators.
-* Configure bean validation based on configuration
-* ...
-
-=== JNDI Support
-
-Write a +JCA+ adapter to provide configuration data through JNDI.
-
-==== Configure JSF
-
-Use the JSF +XML Document+ event to completely configure JSF.
-
-==== Configure Web Services
-
-Provide a WebServiceProviderFactory that may be configured.
-
-==== Configure JPA
-
-Provide an implementation that allows configuration of persistence units. Talk with JPA EG people to see if we can
-get an SPI to hook in a stadardized way.
-
-==== Configure EJBs
-
-Provide an implementation that allows configuration of EJBs and MDBs:
-
-* Register beans
-* Unregister/disable beans
-* Intercept beans
-* Support Configuration Injection (in the worst case using a standard Interceptor, provide supporting artifacts to
-  help developers to achive this easily).
-* Talk with EE8 Umbrella EG (Bill Shanon, Linda DeMichels) on a feasible SPI for EE8, if possible join the EG.
-
-==== Configure ...
-
-Just think of any Java EE aspects that might be worth to be configured. If it can be done, e.g. by managing CDI managed
-resources, it might be easy. For others it is a good idea to discuss things with our matter of experts...
-
-== Special Goodies
-
-=== Maintenance Mode Servlet Filter
-
-Provide a servlet filter that is capable of switching to maintenance mode, based on configuration. Similarly also a forwarding
-servlet could be useful, wehere only request based on configuration are forwarded, other might be rejected or dropped
-as configured.
-
-=== Dynamic Camel Routes
-
-Provides dynamic (configurable) Camel routes, e.g. usable within ServiceMix or standalone.
-
-=== Dynamic CXF
-
-Provides dynamic (configurable) CXF adapters, e.g. usable within ServiceMix or standalone.
-
-=== Configurable Apache MQ
-
-Provides an implementation for configuring Apache MQ.
-
-=== Dynamic ...
-
-Interested to see what other ideas are around. Let us know!
-


[2/4] incubator-tamaya git commit: TAMAYA-29: Removed stage. TAMAYA-19: Simplified environment model. -> Updated docs.

Posted by an...@apache.org.
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: <at...@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
+


[3/4] incubator-tamaya git commit: TAMAYA-29: Removed stage. TAMAYA-19: Simplified environment model. -> Updated docs.

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/design/3_Extensions.adoc
----------------------------------------------------------------------
diff --git a/docs/design/3_Extensions.adoc b/docs/design/3_Extensions.adoc
deleted file mode 100644
index db949ac..0000000
--- a/docs/design/3_Extensions.adoc
+++ /dev/null
@@ -1,841 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-<<<
-[[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/design/4_ImplementationCore.adoc
----------------------------------------------------------------------
diff --git a/docs/design/4_ImplementationCore.adoc b/docs/design/4_ImplementationCore.adoc
deleted file mode 100644
index 2233002..0000000
--- a/docs/design/4_ImplementationCore.adoc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-<<<
-[[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/pom.xml
----------------------------------------------------------------------
diff --git a/docs/pom.xml b/docs/pom.xml
index 965ff76..5e02db1 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -62,7 +62,7 @@ under the License.
                             <embedAssets>true</embedAssets>
                             <imagesDir>${project.build.sourceDirectory}/images/</imagesDir>
                             <sourceDirectory>.</sourceDirectory>
-                            <sourceDocumentName>Design.adoc</sourceDocumentName>
+                            <sourceDocumentName>src/main/asciidoc/design/Design.adoc</sourceDocumentName>
                         </configuration>
                     </execution>
                     <execution>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/src/main/asciidoc/PossibleContributions.adoc
----------------------------------------------------------------------
diff --git a/docs/src/main/asciidoc/PossibleContributions.adoc b/docs/src/main/asciidoc/PossibleContributions.adoc
new file mode 100644
index 0000000..a0040d6
--- /dev/null
+++ b/docs/src/main/asciidoc/PossibleContributions.adoc
@@ -0,0 +1,388 @@
+Apache Tamaya - Possible Tasks
+==============================
+:name: Tamaya
+:rootpackage: org.apache.tamaya
+:title: Apache Tamaya
+:revnumber: 0.1-SNAPSHOT
+:revremark: Draft
+:revdate: October 2014
+:longversion: {revnumber} ({revremark}) {revdate}
+:authorinitials: ATR
+:author: Anatole Tresch
+:email: <at...@gmail.com>
+:source-highlighter: coderay
+:website: http://tamaya.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
+
+== What is Tamaya
+
+{name} is the Apache standard for flexible and powerful configuration. Objective is to provide flavors for
+Java SE, ME as well as to ship with powerful features for Java EE and Cloud Solutions. All functions provided
+is build on top of a small but very powerful, flexible and extendible API. This API is implemented by a core implementation,
+which then can be extended or adapted for use in different runtime scenarios, such as SE, ME, EE, Spring, OSGI
+and more. Similarly additional modules may be provided that help also existing solution to be plugged into
+{name}, so you can start right away using {name} without having to rebuild/change your existing application.
+
+== Main Features of {name}
+
+The main features of {name} currently are
+
+* *A simple key/value store*, named +PropertyProvider+ (simply called "provider").
+* Simple *built-in meta-data model*, that allows to easily attach metadata to a provider or single property keys.
+* Support for *different configuration formats*.
+* Support for *different configuration locations*, including remote locations.
+* Powerful and flexible *options to combine providers to new composite providers* using different combination policies.
+* The *Configuration model* adds additional features:
+** *Type Adapters* allow to convert configuration into any required target type.
+** *Built-in support* for all basic Java types.
+* *Contextual, hierarchical and multi-layered environment model*. The model is rather simple, but nevertheless
+  powerful enough to map complex layered runtime environments such as Java EE or multi-tenant SaaS solutions.
+* *Configurable System Properties* allow to tweak system properties to behave contextually.
+* *Templates* provide a type safe configuration mechanism where an annotated interface is implemented by the
+  configuration system, providing data from an underlying configuration.
+* *Configuration Injection* allows configured values to be directly injected into the bean's configured.
+* *Loading Policies* allow to control how configuration changes are reflected on the configured beans.
+* *Configuration Operators and Queries* can be used to easily implement advanced features such as *Views,
+  Security Constraints and Filters*.
+* Provider and configuration changes can be observed by registering *PropertyChangeListeners*.
+* Configurations are *versioned*, so remote pull scenarios can be implemented very efficiently.
+* The system supports *multiple configurations* identified by name.
+* The configuration system provides a powerful management console for reading and updating of configuration.
+* The system also supports distributed configuration scenarios by leveraging existing solutions, such as Memcached,
+  Hazelcast or Zookeper.
+* The system is built on "Java 8 features*.
+* A *Java 7 Backport* is provided.
+
+=== Purpose of this Document
+
+The document should help to organize people and ideas around the Apache Tamaya Library. It list possible features,
+ideas and tasks that need to be done. Everybody can have a look at and see, where hos contribution and capabilities
+would fit best.
+
+== Basics
+
+=== Styles, Logo
+
+The project requires
+
+* a good Apache styled logo and
+* CSS styles as needed,
+* an initial web page,
+* a twitter account
+* ...
+
+=== Infrastructure
+
+We should setup all needed infrastructure
+* code repos
+* project modules (including module sites)
+* coding and documentation guidelines
+* automatic builds (CI), included automatic coverage and sonar quality checks.
+* a docker image or appliance, with everything setup, so contributors can easily
+  start contributing...
+* ...
+
+== Main Features
+
+=== Metadata Model
+
+Currently +MetaInfo+ models metadata as a separate constuct. It has been shown that this leads to more complex
+handling when creating composites and makes the API overall more complex. The idea is to model metadata as simple
+key/value pairs, that are part of the provider/configuration data as well, but handled separately. Metadata hereby
+is identified by a starting '_' character in its key. For example refer to the following configuration properties:
+
+[source,listing]
+.Basic Properties
+----------------------------------------------------------------
+a.b.Foo=foo
+a.b.Bar=bar
+a.AnyOther=whatelse
+Something=none
+----------------------------------------------------------------
+
+Now we can model meta-data as follows:
+
+[source,listing]
+.Metadata Properties
+----------------------------------------------------------------
+[a.b].info=An area info
+[a.b.Foo].auth=role1,role2
+[a.b.Foo].encrypt=PGP
+[a.b.Foo].sensitive=true
+[].info=This is a test configuration example.
+----------------------------------------------------------------
+
+The above would model the following:
+
+* The area +a.b+ has the meta property +info+.
+* The entry +a.b.Foo+ has three meta properties +auth,encrypt+ and +sensitive+. These could be interpreted by a security
+  view and used to encrypt the values returned by the configuration instance, if not the current user has one of the
+  specified roles.
+* The last meta data defines an attribute +info+ for the whole provider/configuration (the root area).
+
+Given that the overall entries would be as follows:
+
+[source,listing]
+.Full Properties with Meta Properties
+----------------------------------------------------------------
+[a.b].info=An area info
+a.b.Foo=foo
+[a.b.Foo].auth=role1,role2
+[a.b.Foo].encrypt=PGP
+[a.b.Foo].sensitive=true
+a.b.Bar=bar
+[].info=This is a test configuration example.
+a.AnyOther=whatelse
+Something=none
+----------------------------------------------------------------
+
+The current +MetaInfo+ class could be adapted, so it is reading data from the underlying configuration/provider,
+instead of its own datastructure. This would make a later mapping of configuration and its metadata into DB table, JSON
+etc, much more easier.
+The providers on the other side may suppress any metadata from ordinary output, such
+as +toString()+, Similarly accessing metadata using the official config API (+get, getOrDefault, getAreas+ etc)
+should be disabled. The +MetaInfoBuilder+ must probably as well adapted or redesigned.
+
+=== Collection Support
+
+Add a key/value based model for mapping collections such as sets, maps, list. Implement according adapters.
+In combination with the metadata model above this could be something like:
+
+[source,listing]
+.Collection Support
+----------------------------------------------------------------
+mySet=[a,b,c,d,e\,e,f]
+[mySet].type=set
+#optional define the implementation class
+[mySet].class=java.util.TreeSet
+
+myList=[a,b,c,d,e\,e,f]
+[myList].type=list
+#optional define the implementation class
+[myList].class=java.util.ArrayList
+
+myMap=[a:aa,b:bb,c:cc,d:dd,e:e\,e,f:ff]
+[myMap].type=map
+#optional define the implementation class
+[myMap].class=java.util.TreeMap
+
+#Finally we could also add support for non String based types
+myTypedSet=[1,2,3,4.5,6,7.10.123]
+[myTypedSet].contentClass=java.lang.Double
+myTypedList=[CHF 10.20, EUR 12.20, BTC 0.002]
+[myTypedList].contentType=org.javamoney.moneta.FastMoney
+myTypedMap=[CHF:CHF 10.20, EUR:EUR 12.20, BTC:BTC 0.002]
+[myTypedMap].contentTypes=javax.money.CurrencyUnit,javax.money.MonetaryAmount
+----------------------------------------------------------------
+
+
+=== Management Service
+
+A JMX/Restful API should be designed and built that exposes configuration information. Access should be secured, e.g.
+using OAuth or other security mechasnisms.
+
+=== Management Client
+
+A nice web-based client to manage configuration data would be nice as well. This also includes a UI for creating new
+configurations.
+
+=== Mapping Configuration to a Database
+
+A flexible mechanism should be implemented that allows the use of databases (SQL/JPA as well as non-SQL) for
+storing/retreiving/managing configuration:
+
+* JPA, Hibernate
+* MongoDB
+* ...
+
+=== Integration with OSGI
+
+Examples are to be created and tested, where OSGI is used as the basic runtime platform, e.g. Apache Felix, but as well
+others.
+
+=== Integration with Jigsaw
+
+Once Jigsaw is mature and in a usable (still early) stage, examples are to be created and tested, where OSGI is used as
+the basic runtime platform, e.g. Apache Felix, but as well others.
+
+== Distributed/Remote Configuration Support
+
+=== Configuration Server
+
+A configuration server should be implemented that provides access to configurations and triggers updates to registered
+clients (push). Similarly a poull model should be supported, where clients can asl for the current version id of a certain
+configuration and reload it if necessary.
+
+=== Configuration Distribution Policies
+
+Different configuration distribution policies should be defined any implemented, e.g. distributed cache, restful services,
+web services, EJB/RMI calls, asynchronous queues, publish/subsribe models, ...
+
+=== Dynamic Service Lookup
+
+Configuration Servers and Clients should bea ble to locate each other in different ways:
+
+* with fixed configured IPs, or IP ranges
+* using a dynamic service location protocol like
+** SLP
+** Distributed Maps/Datagrids
+** Apache Zookeeper
+
+=== Configuration Client
+
+A subset of the API would be created that exposes only a well defined subset, of exactly one configuration targeted
+to a certain instance, VM or whatever. The client should be connectable to a server in different ways (see configuration
+distributiont policies).
+
+=== Preferences Support
+
+Write a +PreferencesFactory+ for +java.util.preferences+.
+
+== Third Party Integration
+
+=== Integration with Deltaspike Config
+
+Integration with Deltaspike Config should be implemented and discussed with Deltaspike guys.
+
+=== Integration with Spring
+
+A {name} module should be created that allows Spring to be used either as client or configuration provider.
+
+=== Integration with Jetty
+
+A {name} module should be created that allows a Jetty instance to be deployed and started that is (completely)
+configured based on configuration server.
+
+=== Integration with Tomcat
+
+A {name} module should be created that allows a Tomcat instance to be deployed and started that is (completely)
+configured based on configuration server.
+
+=== Configuration of Java EE
+
+In the Java EE area there would be several options:
+
+=== Configuration of Application Servers (administrative resources)
+
+It should be possible to start a application server instance remotely and configure all administrative resources and the
+deployments based on the configuration service, server to be considered maybe
+
+* Wildfly
+* IBM
+* Weblogic
+* Glassfish
+* Apache Geronimo
+
+==== Configuration of CDI
+
+Implement a CDI extension that controls CDI based on configuration:
+* Add beans
+* Remove (veto) beans
+* Add/remove interceptors
+* Add/remove decorators
+* Activate alternatives
+* ...
+
+==== Configuration of Bean Validation
+
+* Add configurable validators.
+* Configure bean validation based on configuration
+* ...
+
+=== JNDI Support
+
+Write a +JCA+ adapter to provide configuration data through JNDI.
+
+==== Configure JSF
+
+Use the JSF +XML Document+ event to completely configure JSF.
+
+==== Configure Web Services
+
+Provide a WebServiceProviderFactory that may be configured.
+
+==== Configure JPA
+
+Provide an implementation that allows configuration of persistence units. Talk with JPA EG people to see if we can
+get an SPI to hook in a stadardized way.
+
+==== Configure EJBs
+
+Provide an implementation that allows configuration of EJBs and MDBs:
+
+* Register beans
+* Unregister/disable beans
+* Intercept beans
+* Support Configuration Injection (in the worst case using a standard Interceptor, provide supporting artifacts to
+  help developers to achive this easily).
+* Talk with EE8 Umbrella EG (Bill Shanon, Linda DeMichels) on a feasible SPI for EE8, if possible join the EG.
+
+==== Configure ...
+
+Just think of any Java EE aspects that might be worth to be configured. If it can be done, e.g. by managing CDI managed
+resources, it might be easy. For others it is a good idea to discuss things with our matter of experts...
+
+== Special Goodies
+
+=== Maintenance Mode Servlet Filter
+
+Provide a servlet filter that is capable of switching to maintenance mode, based on configuration. Similarly also a forwarding
+servlet could be useful, wehere only request based on configuration are forwarded, other might be rejected or dropped
+as configured.
+
+=== Dynamic Camel Routes
+
+Provides dynamic (configurable) Camel routes, e.g. usable within ServiceMix or standalone.
+
+=== Dynamic CXF
+
+Provides dynamic (configurable) CXF adapters, e.g. usable within ServiceMix or standalone.
+
+=== Configurable Apache MQ
+
+Provides an implementation for configuring Apache MQ.
+
+=== Dynamic ...
+
+Interested to see what other ideas are around. Let us know!
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/src/main/asciidoc/design/0_UseCases.adoc
----------------------------------------------------------------------
diff --git a/docs/src/main/asciidoc/design/0_UseCases.adoc b/docs/src/main/asciidoc/design/0_UseCases.adoc
new file mode 100644
index 0000000..8ec833e
--- /dev/null
+++ b/docs/src/main/asciidoc/design/0_UseCases.adoc
@@ -0,0 +1,319 @@
+// 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.
+
+<<<
+[[UseCases]]
+== Use Cases
+
+This section describes some, but not all, of the use cases that should be covered by Tamaya.
+
+
+[[UCSimpleAccess]]
+=== Simple Property Access (UC 1)
+
+Tamaya should provide a simple Java API for accessing configuration. Hereby
+
+* Configuration is organized as key/value pairs. This basically can be modeled as +Map<String,String>+
+* Configuration should be as simple as possible. A +Map<String,String>+ instance has methods that may not
+  be used in many use cases and/or are not easy to implement. Currently the following functionality
+  must be supported:
+  ** access a value by key (+get+)
+  ** check if a value is present (+containsKey+)
+  ** get a set of all defined keys (+keySet+)
+  ** a property provider must be convertable to a +Map+, by calling +toMap()+
+  ** a property provider must get access to its meta information.
+* The API must never return null.
+* The API should support undefined values.
+* The API must support passing default values, to be returned if a value is undefined.
+* The API must allow to throw exceptions, when a value is undefined.
+  Customized exceptions hereby should be supported.
+* Properties can be stored in the classpath, on a file.
+* Properties can be stored in properties, xml-properties or ini-format.
+* Properties can also be provided as properties, or as a Map<String,String>
+
+
+[[UCAutoConfig]]
+=== Automatic Configuration
+
+* Tamaya should provide a feature for automatic configuration, where properties can be annotated.
+* Hereby the lifecycle of the instances configured should not be managed by Tamaya.
+* String as well as other types should be supported.
+* It should be possible to define default values to be used, if no valid value is present.
+* It should be possible to define dynamic expressions, at least for default values.
+* The values configured should be reinjected, if the underlying configuration changes.
+* Reinjection should be controllable by an injection policy.
+* It should be possible to evaluate multiple keys, e.g. current keys, and as a backup deprecated keys
+  from former application releases.
+* The type conversion of the properties injected should be configurable.
+* The value evaluated for a property (before type conversion) may be adaptable as well.
+* It should be possible to observe configuration changes.
+
+The most simplest way is using injection, e.g. a POJO can be written as follows:
+
+[source, java]
+.Configured POJO Example
+----------------------------------------------------
+public class MyPojo {
+  @ConfigProperty("myCurrency")
+  @DefaultValue("CHF")
+  private String currency;
+
+  @ConfigProperty("myCurrencyRate")
+  private Long currencyRate;
+}
+----------------------------------------------------
+
+The instance then can be passed for being configured:
+
+[source, java]
+.Configuring a POJO
+----------------------------------------------------
+MyPojo instance = new MyPojo();
+Configuration.configure(instance);
+----------------------------------------------------
+
+[[UCTemplates]]
+=== Configuration Templates
+
+For type safe configuration clients should be able to define an interface that is implemented by the
+configuration system:
+
+* clients define an interface and annotate it as required
+* the interface methods must not take any arguments
+* the configuration system can be called to return such an interface implementation.
+* the configuration system returns a proxy hereby providing the values required.
+* similar to configured types also templates support multiple values and custom adapters.
+* It is possible to listen on configuration changes for templates, so users of the templates
+  may react on configuration changes.
+
+A template hereby is modelled by annotating an interface with the same annotations as for
+configured classes:
+
+[source, java]
+.Type Safe Configuration Template Example
+----------------------------------------------------
+public interface MyConfig {
+  @ConfiguredProperty("myCurrency")
+  @DefaultValue("CHF")
+  String getCurrency();
+
+  @ConfiguredProperty("myCurrencyRate")
+  Long getCurrencyRate();
+
+}
+----------------------------------------------------
+
+The configuration system will then provide the interface as follows:
+
+[source, java]
+.Accessing a type safe Configuration Template
+----------------------------------------------------
+MyConfig config = Configuration.of(MyConfig.class);
+----------------------------------------------------
+
+Finally a +Configuration+ itself can be accessed as template as well, which
+provides full access to all features:
+
+[source, java]
+.Accessing a Configuration
+----------------------------------------------------
+Configuration config = Configuration.of(Configuration.class);
+----------------------------------------------------
+
+
+[[UCSimpleConfiguration]]
+=== Simple Property Based Configuration
+
+In this most simple usage scenario an application is configured by some property files contained in the
+Java archive.
+
+* It provides default property files in the formats defined by the JDK within its application archive.
+* It allows to override settings by system properties.
+* It is able to consider command line arguments as well.
+
+
+[[UCAdvancedPropertyBasedConfiguration]]
+=== Advanced Property Based Configuration
+
+Enhancing the previous scenario, we might as well consider the current environment. Saying that our overriding mechanisms
+must be improved, since
+
+* some environment settings should not be overridable
+* some defaults should be overridden by environment or system properties, whereas others may not
+* Additionally the user may have an option, where he is allowed to define an external configuration file that should be used to configure
+  the application. This is especially useful for applications with lots of command line options (under windows even command
+  execution may fail die to exceeding command length).
+* Finally application developers may have their own formats in place, so the system should be able to support these formats.
+
+
+[[UCModularizedConfiguration]]
+=== Modularized Configuration
+
+When systems grow they must be modularized to keep control. Whereas that sounds not really fancy, it leads to additional aspects
+to be considered by a configuration system.
+
+* Different code modules want to have their own "module configuration".
+* Some modules require a certain subset of keys to be read at once into a Map.
+* Products contain multiple modules, which per product are configured separately.
+
+
+[[UCTypeSupport]]
+=== Extended Type Support
+
+Application configuration must also support non String types such as primitives, wrapper types, math types
+and date/time values. Basically each type that can be created from a String in more standardized way should
+supported. This should be even possible for types not known at build time of possible. Type conversion hereby
+should be flexible.
+
+[[UCDynamicProvisioning]]
+=== Dynamic Provisioning
+
+In Cloud Computing, especially the PaaS and SaaS areas a typical use case would be that an application (or server)
+is deployed, configured and started dynamically. Typically things are controlled by some "active controller components",
+which are capable of
+* creating new nodes (using IaaS services)
+* deploying and starting the required runtime platform , e.g. as part of a PaaS solution.
+* deploying and starting the application modules.
+
+All these steps require some kind of configuration. As of today required files are often created on the target node
+before the systems are started, using proprietary formats and mechanism. Similarly accessing the configuration in place
+may require examining the file system or using again proprietary management functions. Of course, a configuration
+solution should not try to solve that, but it can provide a significant bunch of functionality useful in such scenarios:
+
+* provide remote capabilities for configuration
+* allow configuration to be updated remotely.
+* allow client code to listen for configuration changes and react as needed.
+
+Consequently:
+
+-> Ensure Configuration can be transferred over the network easily.
+
+-> Whereas many people will no think serializability is the solution, it would be much more useful to define
+   a text based format for serialization, e.g. in +XML+ or +JSON+.
+
+-> Similarly a management API should be defined, which allows to inspect the configuration in place, e.g. using
+   JMX or REST services.
+
+[[UCJavaEE]]
+=== Java EE
+
+Considering Java EE different aspects should be considered:
+
+* Java EE is a complex multi-layered architecture with different levels of runtime contexts:
+** application server boot level (system classloader),
+** (optional) deployment/undeployment of ears (ear classloader),
+** (optional) deployment/undeployment of web applications (war classloader),
+** different runtime setups, e.g. EJB calls, MDB execution, Servlet Requests, scheduled and timed executions.
+* Configuring administrative resources (e.g. datasources, users, security etc) is typically vendor specific.
+* The environment is inherently multi-threaded.
+
+Given that a couple of additional requirements araise:
+
+-> Configuration must be contextual, depending on the current runtime context (e.g. boot level, ear, war, ...).
+
+-> Hereby contextual aspects can even exceed the levels described above, e.g. for SaaS scenarios.
+
+-> Resources can be unloaded, e.g. wars, ears can be restarted.
+
+-> The different contextual levels can also be used for overriding, e.g. application specific configuration
+may override ear or system configuration.
+
+-> Configuration may be read from different sources (different classloaders, files, databases, remote locations).
+
+-> Configuration may be read in different formats (deployment descriptors, +ServiceLoader+ configuration, alt-DD feature, ...)
+
+-> JSF also knows the concept of stages.
+
+-> Many SPI's of Java EE require the implementation of some well defined Java interface, so it would be useful if the
+   configuration solution supports easy implementation of such instances.
+
+-> In general it would be useful to model the +Environment+ explicitly.
+
+-> Configuration used as preferences is writable as well. This requires mutability to be modelled in way, without the
+   need of synchronization.
+
+-> JNDI can be used for configuration as well.
+
+[[UCMultiTenancy]]
+=== Scenario MultiTenancy
+In multi tenancy setups a hierarchical/graph model of contexts for configurations is required. For example there might
+be some kind of layering as follows:
+
+* Layer 0: Low level system configuration
+* Layer 1: Domain configuration
+* Layer 2: Default App configuration
+* Layer 3: Tenant specific configuration
+* Layer 4: User specific configuration
+
+Configurations made in the tenant or user layer override the default app configuration etc.
+
+-> It must be possible to structure Configuration in layers that can override/extend each other.
+
+-> The current environment must be capable of mapping tenant, user and other aspects, so a corresponding configuration
+   (or layer) can be derived.
+
+[[UCJavaAPI]]
+=== Accessing Configuration
+
+So far we described much how configuration must be organized and managed, but we got not concrete, how it is accessed.
+Basically there are two basic scenarios to be distinguished, which mainly depend on the way how the lifecycle of a component
+to be configured is managed:
+
+* If the lifecycle is managed manually by the developer, the configuration system
+** can inject configuration values, when explicitly called to to so
+** can provide an accessor for configuration.
+* If the lifecycle is managed by some container such as a DI container, the configuration
+  system should leverage the functionality of the container, where possible.
+
+
+
+
+[[UCTesting]]
+=== Testing
+When testing a Java solution, it must be possible to easily control the configuration provided, so isolated
+component tests can be written effectively. Also it should be possible to control/isolate the configuration level for
+each test case.
+
+-> isolation of configuration services is required
+
+-> API for controlling the configuration provided, required for according implementations in the testing frameworks.
+
+[[UCStaging]]
+=== Staging
+Different companies go through different staging levels during the development of software components. Currently only
+rarely the EE frameworks support staging aspects, nevertheless no broader, well modelled staging concept is defined.
+Different companies also have different staging or sub-staging levels in place, which also must be reflected.
+Especially with sub-stages inheritance of stage related configuration is common sense and should be supported.
+
+-> Main stages available and to be supported must be defined.
+
+-> Enable additional stages to be added, so also custom stages can be supported.
+
+
+[[UCCotsIntegration]]
+=== Custom of the Shelf (COTS) Integration
+When buying software from an external software company it is often very cumbersome to integrate, adapt and customize
+third party software to the internal operational requirements. Especially, when software is delivered as ear modules
+portability is often very difficult and time consuming. Configuration should enable COTS providers to define a
+customization contract, which also can be part of the COTS software interface and integration specifications. This
+would allow operations to better control and configure third party solutions as possible, whereas in the evaluation
+phase the integration and configuration options can explicitly be defined.
+
+-> It must be possible to document configuration aspects supported.
+
+-> Configuration must be overridable from external sources (the operations which must operate the COTS solution).
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/src/main/asciidoc/design/1_Requirements.adoc
----------------------------------------------------------------------
diff --git a/docs/src/main/asciidoc/design/1_Requirements.adoc b/docs/src/main/asciidoc/design/1_Requirements.adoc
new file mode 100644
index 0000000..6367ed3
--- /dev/null
+++ b/docs/src/main/asciidoc/design/1_Requirements.adoc
@@ -0,0 +1,50 @@
+// 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.
+
+<<<
+[[Requirements]]
+== Requirements
+=== Core Configuration Requirements
+Based on the scope and use cases described above the following core requirements can be identified:
+
+* Configuration is modelled as String based key/value pairs.
+* Configuration can be combined using the GoF composite pattern. Hereby different composition policies can be applied, such as
+  ** override: subsequent entries override existing ones.
+  ** substraction: keys present in the second configuration will be removed.
+  ** union-resolve: key/values were added, in case of conflicts a +ConfigException+ must be thrown.
+  ** union-ignore: similar to union, whereas duplicates are ignored (leaving the initial value loaded).
+  ** intersection:
+
+[[RequirementsServer]]
+=== Server Configuration Requirements
+shskjdhskhds sdkj ksjdks skjdskjd:
+
+. Req1
+. Req2
+
+[[RequirementsExtensions]]
+=== Extensions Requirements
+shskjdhskhds sdkj ksjdks skjdskjd:
+
+. Req1
+. Req2
+
+[[RequirementsNonFunctional]]
+=== Non Functional Requirements
+. Req1
+. Req2
+


[4/4] incubator-tamaya git commit: TAMAYA-29: Removed stage. TAMAYA-19: Simplified environment model. -> Updated docs.

Posted by an...@apache.org.
TAMAYA-29: Removed stage.
TAMAYA-19: Simplified environment model.
-> Updated docs.


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

Branch: refs/heads/master
Commit: cd513bf36b7da240fef80b5660ff3399693b8954
Parents: 0b3b963
Author: anatole <an...@apache.org>
Authored: Wed Dec 17 00:26:20 2014 +0100
Committer: anatole <an...@apache.org>
Committed: Wed Dec 17 00:26:20 2014 +0100

----------------------------------------------------------------------
 docs/Design.adoc                                | 117 ---
 docs/design/0_UseCases.adoc                     | 319 -------
 docs/design/1_Requirements.adoc                 |  50 --
 docs/design/2_CoreConcepts.adoc                 | 843 ------------------
 docs/design/3_Extensions.adoc                   | 841 ------------------
 docs/design/4_ImplementationCore.adoc           |  47 -
 docs/pom.xml                                    |   2 +-
 .../main/asciidoc/PossibleContributions.adoc    | 388 +++++++++
 docs/src/main/asciidoc/design/0_UseCases.adoc   | 319 +++++++
 .../main/asciidoc/design/1_Requirements.adoc    |  50 ++
 .../main/asciidoc/design/2_CoreConcepts.adoc    | 849 +++++++++++++++++++
 docs/src/main/asciidoc/design/3_Extensions.adoc | 841 ++++++++++++++++++
 .../asciidoc/design/4_ImplementationCore.adoc   |  47 +
 docs/src/main/asciidoc/design/Design.adoc       | 117 +++
 docs/tasks.adoc                                 | 388 ---------
 15 files changed, 2612 insertions(+), 2606 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/Design.adoc
----------------------------------------------------------------------
diff --git a/docs/Design.adoc b/docs/Design.adoc
deleted file mode 100644
index 403b4ff..0000000
--- a/docs/Design.adoc
+++ /dev/null
@@ -1,117 +0,0 @@
-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: <at...@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::design/0_UseCases.adoc[]
-
-<<<
-include::design/1_Requirements.adoc[]
-
-<<<
-include::design/2_CoreConcepts.adoc[]
-
-:numbered!:
-== APPENDIX
-

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/design/0_UseCases.adoc
----------------------------------------------------------------------
diff --git a/docs/design/0_UseCases.adoc b/docs/design/0_UseCases.adoc
deleted file mode 100644
index 8ec833e..0000000
--- a/docs/design/0_UseCases.adoc
+++ /dev/null
@@ -1,319 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-<<<
-[[UseCases]]
-== Use Cases
-
-This section describes some, but not all, of the use cases that should be covered by Tamaya.
-
-
-[[UCSimpleAccess]]
-=== Simple Property Access (UC 1)
-
-Tamaya should provide a simple Java API for accessing configuration. Hereby
-
-* Configuration is organized as key/value pairs. This basically can be modeled as +Map<String,String>+
-* Configuration should be as simple as possible. A +Map<String,String>+ instance has methods that may not
-  be used in many use cases and/or are not easy to implement. Currently the following functionality
-  must be supported:
-  ** access a value by key (+get+)
-  ** check if a value is present (+containsKey+)
-  ** get a set of all defined keys (+keySet+)
-  ** a property provider must be convertable to a +Map+, by calling +toMap()+
-  ** a property provider must get access to its meta information.
-* The API must never return null.
-* The API should support undefined values.
-* The API must support passing default values, to be returned if a value is undefined.
-* The API must allow to throw exceptions, when a value is undefined.
-  Customized exceptions hereby should be supported.
-* Properties can be stored in the classpath, on a file.
-* Properties can be stored in properties, xml-properties or ini-format.
-* Properties can also be provided as properties, or as a Map<String,String>
-
-
-[[UCAutoConfig]]
-=== Automatic Configuration
-
-* Tamaya should provide a feature for automatic configuration, where properties can be annotated.
-* Hereby the lifecycle of the instances configured should not be managed by Tamaya.
-* String as well as other types should be supported.
-* It should be possible to define default values to be used, if no valid value is present.
-* It should be possible to define dynamic expressions, at least for default values.
-* The values configured should be reinjected, if the underlying configuration changes.
-* Reinjection should be controllable by an injection policy.
-* It should be possible to evaluate multiple keys, e.g. current keys, and as a backup deprecated keys
-  from former application releases.
-* The type conversion of the properties injected should be configurable.
-* The value evaluated for a property (before type conversion) may be adaptable as well.
-* It should be possible to observe configuration changes.
-
-The most simplest way is using injection, e.g. a POJO can be written as follows:
-
-[source, java]
-.Configured POJO Example
-----------------------------------------------------
-public class MyPojo {
-  @ConfigProperty("myCurrency")
-  @DefaultValue("CHF")
-  private String currency;
-
-  @ConfigProperty("myCurrencyRate")
-  private Long currencyRate;
-}
-----------------------------------------------------
-
-The instance then can be passed for being configured:
-
-[source, java]
-.Configuring a POJO
-----------------------------------------------------
-MyPojo instance = new MyPojo();
-Configuration.configure(instance);
-----------------------------------------------------
-
-[[UCTemplates]]
-=== Configuration Templates
-
-For type safe configuration clients should be able to define an interface that is implemented by the
-configuration system:
-
-* clients define an interface and annotate it as required
-* the interface methods must not take any arguments
-* the configuration system can be called to return such an interface implementation.
-* the configuration system returns a proxy hereby providing the values required.
-* similar to configured types also templates support multiple values and custom adapters.
-* It is possible to listen on configuration changes for templates, so users of the templates
-  may react on configuration changes.
-
-A template hereby is modelled by annotating an interface with the same annotations as for
-configured classes:
-
-[source, java]
-.Type Safe Configuration Template Example
-----------------------------------------------------
-public interface MyConfig {
-  @ConfiguredProperty("myCurrency")
-  @DefaultValue("CHF")
-  String getCurrency();
-
-  @ConfiguredProperty("myCurrencyRate")
-  Long getCurrencyRate();
-
-}
-----------------------------------------------------
-
-The configuration system will then provide the interface as follows:
-
-[source, java]
-.Accessing a type safe Configuration Template
-----------------------------------------------------
-MyConfig config = Configuration.of(MyConfig.class);
-----------------------------------------------------
-
-Finally a +Configuration+ itself can be accessed as template as well, which
-provides full access to all features:
-
-[source, java]
-.Accessing a Configuration
-----------------------------------------------------
-Configuration config = Configuration.of(Configuration.class);
-----------------------------------------------------
-
-
-[[UCSimpleConfiguration]]
-=== Simple Property Based Configuration
-
-In this most simple usage scenario an application is configured by some property files contained in the
-Java archive.
-
-* It provides default property files in the formats defined by the JDK within its application archive.
-* It allows to override settings by system properties.
-* It is able to consider command line arguments as well.
-
-
-[[UCAdvancedPropertyBasedConfiguration]]
-=== Advanced Property Based Configuration
-
-Enhancing the previous scenario, we might as well consider the current environment. Saying that our overriding mechanisms
-must be improved, since
-
-* some environment settings should not be overridable
-* some defaults should be overridden by environment or system properties, whereas others may not
-* Additionally the user may have an option, where he is allowed to define an external configuration file that should be used to configure
-  the application. This is especially useful for applications with lots of command line options (under windows even command
-  execution may fail die to exceeding command length).
-* Finally application developers may have their own formats in place, so the system should be able to support these formats.
-
-
-[[UCModularizedConfiguration]]
-=== Modularized Configuration
-
-When systems grow they must be modularized to keep control. Whereas that sounds not really fancy, it leads to additional aspects
-to be considered by a configuration system.
-
-* Different code modules want to have their own "module configuration".
-* Some modules require a certain subset of keys to be read at once into a Map.
-* Products contain multiple modules, which per product are configured separately.
-
-
-[[UCTypeSupport]]
-=== Extended Type Support
-
-Application configuration must also support non String types such as primitives, wrapper types, math types
-and date/time values. Basically each type that can be created from a String in more standardized way should
-supported. This should be even possible for types not known at build time of possible. Type conversion hereby
-should be flexible.
-
-[[UCDynamicProvisioning]]
-=== Dynamic Provisioning
-
-In Cloud Computing, especially the PaaS and SaaS areas a typical use case would be that an application (or server)
-is deployed, configured and started dynamically. Typically things are controlled by some "active controller components",
-which are capable of
-* creating new nodes (using IaaS services)
-* deploying and starting the required runtime platform , e.g. as part of a PaaS solution.
-* deploying and starting the application modules.
-
-All these steps require some kind of configuration. As of today required files are often created on the target node
-before the systems are started, using proprietary formats and mechanism. Similarly accessing the configuration in place
-may require examining the file system or using again proprietary management functions. Of course, a configuration
-solution should not try to solve that, but it can provide a significant bunch of functionality useful in such scenarios:
-
-* provide remote capabilities for configuration
-* allow configuration to be updated remotely.
-* allow client code to listen for configuration changes and react as needed.
-
-Consequently:
-
--> Ensure Configuration can be transferred over the network easily.
-
--> Whereas many people will no think serializability is the solution, it would be much more useful to define
-   a text based format for serialization, e.g. in +XML+ or +JSON+.
-
--> Similarly a management API should be defined, which allows to inspect the configuration in place, e.g. using
-   JMX or REST services.
-
-[[UCJavaEE]]
-=== Java EE
-
-Considering Java EE different aspects should be considered:
-
-* Java EE is a complex multi-layered architecture with different levels of runtime contexts:
-** application server boot level (system classloader),
-** (optional) deployment/undeployment of ears (ear classloader),
-** (optional) deployment/undeployment of web applications (war classloader),
-** different runtime setups, e.g. EJB calls, MDB execution, Servlet Requests, scheduled and timed executions.
-* Configuring administrative resources (e.g. datasources, users, security etc) is typically vendor specific.
-* The environment is inherently multi-threaded.
-
-Given that a couple of additional requirements araise:
-
--> Configuration must be contextual, depending on the current runtime context (e.g. boot level, ear, war, ...).
-
--> Hereby contextual aspects can even exceed the levels described above, e.g. for SaaS scenarios.
-
--> Resources can be unloaded, e.g. wars, ears can be restarted.
-
--> The different contextual levels can also be used for overriding, e.g. application specific configuration
-may override ear or system configuration.
-
--> Configuration may be read from different sources (different classloaders, files, databases, remote locations).
-
--> Configuration may be read in different formats (deployment descriptors, +ServiceLoader+ configuration, alt-DD feature, ...)
-
--> JSF also knows the concept of stages.
-
--> Many SPI's of Java EE require the implementation of some well defined Java interface, so it would be useful if the
-   configuration solution supports easy implementation of such instances.
-
--> In general it would be useful to model the +Environment+ explicitly.
-
--> Configuration used as preferences is writable as well. This requires mutability to be modelled in way, without the
-   need of synchronization.
-
--> JNDI can be used for configuration as well.
-
-[[UCMultiTenancy]]
-=== Scenario MultiTenancy
-In multi tenancy setups a hierarchical/graph model of contexts for configurations is required. For example there might
-be some kind of layering as follows:
-
-* Layer 0: Low level system configuration
-* Layer 1: Domain configuration
-* Layer 2: Default App configuration
-* Layer 3: Tenant specific configuration
-* Layer 4: User specific configuration
-
-Configurations made in the tenant or user layer override the default app configuration etc.
-
--> It must be possible to structure Configuration in layers that can override/extend each other.
-
--> The current environment must be capable of mapping tenant, user and other aspects, so a corresponding configuration
-   (or layer) can be derived.
-
-[[UCJavaAPI]]
-=== Accessing Configuration
-
-So far we described much how configuration must be organized and managed, but we got not concrete, how it is accessed.
-Basically there are two basic scenarios to be distinguished, which mainly depend on the way how the lifecycle of a component
-to be configured is managed:
-
-* If the lifecycle is managed manually by the developer, the configuration system
-** can inject configuration values, when explicitly called to to so
-** can provide an accessor for configuration.
-* If the lifecycle is managed by some container such as a DI container, the configuration
-  system should leverage the functionality of the container, where possible.
-
-
-
-
-[[UCTesting]]
-=== Testing
-When testing a Java solution, it must be possible to easily control the configuration provided, so isolated
-component tests can be written effectively. Also it should be possible to control/isolate the configuration level for
-each test case.
-
--> isolation of configuration services is required
-
--> API for controlling the configuration provided, required for according implementations in the testing frameworks.
-
-[[UCStaging]]
-=== Staging
-Different companies go through different staging levels during the development of software components. Currently only
-rarely the EE frameworks support staging aspects, nevertheless no broader, well modelled staging concept is defined.
-Different companies also have different staging or sub-staging levels in place, which also must be reflected.
-Especially with sub-stages inheritance of stage related configuration is common sense and should be supported.
-
--> Main stages available and to be supported must be defined.
-
--> Enable additional stages to be added, so also custom stages can be supported.
-
-
-[[UCCotsIntegration]]
-=== Custom of the Shelf (COTS) Integration
-When buying software from an external software company it is often very cumbersome to integrate, adapt and customize
-third party software to the internal operational requirements. Especially, when software is delivered as ear modules
-portability is often very difficult and time consuming. Configuration should enable COTS providers to define a
-customization contract, which also can be part of the COTS software interface and integration specifications. This
-would allow operations to better control and configure third party solutions as possible, whereas in the evaluation
-phase the integration and configuration options can explicitly be defined.
-
--> It must be possible to document configuration aspects supported.
-
--> Configuration must be overridable from external sources (the operations which must operate the COTS solution).
-

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/design/1_Requirements.adoc
----------------------------------------------------------------------
diff --git a/docs/design/1_Requirements.adoc b/docs/design/1_Requirements.adoc
deleted file mode 100644
index 6367ed3..0000000
--- a/docs/design/1_Requirements.adoc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-<<<
-[[Requirements]]
-== Requirements
-=== Core Configuration Requirements
-Based on the scope and use cases described above the following core requirements can be identified:
-
-* Configuration is modelled as String based key/value pairs.
-* Configuration can be combined using the GoF composite pattern. Hereby different composition policies can be applied, such as
-  ** override: subsequent entries override existing ones.
-  ** substraction: keys present in the second configuration will be removed.
-  ** union-resolve: key/values were added, in case of conflicts a +ConfigException+ must be thrown.
-  ** union-ignore: similar to union, whereas duplicates are ignored (leaving the initial value loaded).
-  ** intersection:
-
-[[RequirementsServer]]
-=== Server Configuration Requirements
-shskjdhskhds sdkj ksjdks skjdskjd:
-
-. Req1
-. Req2
-
-[[RequirementsExtensions]]
-=== Extensions Requirements
-shskjdhskhds sdkj ksjdks skjdskjd:
-
-. Req1
-. Req2
-
-[[RequirementsNonFunctional]]
-=== Non Functional Requirements
-. Req1
-. Req2
-

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/cd513bf3/docs/design/2_CoreConcepts.adoc
----------------------------------------------------------------------
diff --git a/docs/design/2_CoreConcepts.adoc b/docs/design/2_CoreConcepts.adoc
deleted file mode 100644
index 41c2311..0000000
--- a/docs/design/2_CoreConcepts.adoc
+++ /dev/null
@@ -1,843 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-<<<
-[[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 (+PropertyAdapters,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, Stage,
-  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.
-
-[APIPropertySources]
-=== 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 PropertySourceBuilder]]
-==== Building Property Sources
-
-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 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 +PropertySources+ 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 PropertySources
---------------------------------------------
-PropertySource provider1 = ...
-PropertySource provider2 = ...
-
-// aggregate, hereby values from provider 2 override values from provider 1
-PropertySource unionOverriding = PropertySources.aggregate(AggregationPolicy.OVERRIDE(), provider1, provider2);
-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);
-System.out.println("unionIgnoringDuplicates: " + unionIgnoringDuplicates);
-
-// this variant combines/maps duplicate values into a new value
-PropertySource unionCombined = PropertySources.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{
-    PropertySources.aggregate(AggregationPolicy.EXCEPTION(), provider1, provider2);
-}
-catch(ConfigException e){
-    // expected!
-}
---------------------------------------------
-
-The example above produces the following outpout:
-
-[source,listing]
-.Example Combining PropertySources
---------------------------------------------
-AggregatedPropertySource{
-  (name = dynamicAggregationTests)
-  a = "[a][A]"
-  b = "[b][B]"
-  c = "[c][C]"
-  d = "[D]"
-  e = "[E]"
-  f = "[F]"
-  g = "[g]"
-  h = "[h]"
-  i = "[i]"
-}
-unionOverriding: AggregatedPropertySource{
-  (name = <noname>)
-  a = "A"
-  b = "B"
-  c = "C"
-  d = "D"
-  e = "E"
-  f = "F"
-  g = "g"
-  h = "h"
-  i = "i"
-}
-unionIgnoringDuplicates: AggregatedPropertySource{
-  (name = <noname>)
-  a = "a"
-  b = "b"
-  c = "c"
-  d = "D"
-  e = "E"
-  f = "F"
-  g = "g"
-  h = "h"
-  i = "i"
-}
-unionCombined: AggregatedPropertySource{
-  (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
---------------------------------------------
-PropertySource provider1 = ...;
-PropertySource provider2 = ...;
-PropertySource props = PropertySources.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
---------------------------------------------
-AggregatedPropertySource{
-  (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 +PropertySources+ singleton allows to combine providers in various forms:
-
-[source,listing]
-.Methods provided on PropertySources
---------------------------------------------
-public final class PropertySources {
-
-    private PropertySources() {}
-
-    public static PropertySource fromArgs(String... args) {
-    public static PropertySource fromArgs(MetaInfo metaInfo, String... args) {
-    public static PropertySource fromPaths(AggregationPolicy aggregationPolicy, String... paths) {
-    public static PropertySource fromPaths(String... paths) {
-    public static PropertySource fromPaths(List<String> paths) {
-    public static PropertySource fromPaths(AggregationPolicy aggregationPolicy, List<String> paths) {
-    public static PropertySource fromPaths(MetaInfo metaInfo, List<String> paths) {
-    public static PropertySource fromPaths(AggregationPolicy aggregationPolicy, MetaInfo metaInfo, List<String> paths) {
-    public static PropertySource fromUris(URI... uris) {
-    public static PropertySource fromUris(AggregationPolicy aggregationPolicy, URI... uris) {
-    public static PropertySource fromUris(List<URI> uris) {
-    public static PropertySource fromUris(AggregationPolicy aggregationPolicy, List<URI> uris) {
-    public static PropertySource fromUris(MetaInfo metaInfo, URI... uris) {
-    public static PropertySource fromUris(AggregationPolicy aggregationPolicy, MetaInfo metaInfo, URI... uris) {
-    public static PropertySource fromUris(MetaInfo metaInfo, List<URI> uris) {
-    public static PropertySource fromUris(AggregationPolicy aggregationPolicy, MetaInfo metaInfo, List<URI> uris) {
-    public static PropertySource fromMap(Map<String, String> map) {
-    public static PropertySource fromMap(MetaInfo metaInfo, Map<String, String> map) {
-    public static PropertySource empty() {
-    public static PropertySource emptyMutable() {
-    public static PropertySource empty(MetaInfo metaInfo) {
-    public static PropertySource emptyMutable(MetaInfo metaInfo) {
-    public static PropertySource fromEnvironmentProperties() {
-    public static PropertySource fromSystemProperties() {
-    public static PropertySource freezed(PropertySource provider) {
-    public static PropertySource aggregate(AggregationPolicy mapping, MetaInfo metaInfo, PropertySource... providers){
-    public static PropertySource aggregate(PropertySource... providers) {
-    public static PropertySource aggregate(List<PropertySource> providers) {
-    public static PropertySource aggregate(AggregationPolicy mapping, PropertySource... propertyMaps) {
-    public static PropertySource aggregate(AggregationPolicy mapping, List<PropertySource> providers) {
-    public static PropertySource mutable(PropertySource provider) {
-    public static PropertySource intersected(AggregationPolicy aggregationPolicy, PropertySource... providers) {
-    public static PropertySource intersected(PropertySource... providers) {
-    public static PropertySource subtracted(PropertySource target, PropertySource... providers) {
-    public static PropertySource filtered(Predicate<String> filter, PropertySource provider) {
-    public static PropertySource contextual(Supplier<PropertySource> mapSupplier,
-                                              Supplier<String> isolationKeySupplier) {
-    public static PropertySource delegating(PropertySource mainMap, Map<String, String> parentMap) {
-    public static PropertySource replacing(PropertySource mainMap, Map<String, String> replacementMap) {
-}
---------------------------------------------
-
-
-[[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 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 +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]
-.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!
---------------------------------------------
-
-