Merge branch 'master' of https://github.com/apache/incubator-tamaya-sandbox
diff --git a/apache-commons/src/main/java/org/apache/tamaya/commons/IniConfigurationFormat.java b/apache-commons/src/main/java/org/apache/tamaya/commons/IniConfigurationFormat.java
index 7c86d65..bf03fcf 100644
--- a/apache-commons/src/main/java/org/apache/tamaya/commons/IniConfigurationFormat.java
+++ b/apache-commons/src/main/java/org/apache/tamaya/commons/IniConfigurationFormat.java
@@ -64,7 +64,7 @@
             }
             for (String section : commonIniConfiguration.getSections()) {
                 SubnodeConfiguration sectionConfig = commonIniConfiguration.getSection(section);
-                PropertyValue sectionNode = ((ObjectValue) data).getOrSetField(section,
+                PropertyValue sectionNode = ((ObjectValue) data).getOrSetValue(section,
                         () -> PropertyValue.createObject(section));
                 Map<String, String> properties = new HashMap<>();
                 Iterator<String> keyIter = sectionConfig.getKeys();
diff --git a/camel/src/main/java/org/apache/tamaya/camel/TamayaPropertiesComponent.java b/camel/src/main/java/org/apache/tamaya/camel/TamayaPropertiesComponent.java
index aec571b..516fb7f 100644
--- a/camel/src/main/java/org/apache/tamaya/camel/TamayaPropertiesComponent.java
+++ b/camel/src/main/java/org/apache/tamaya/camel/TamayaPropertiesComponent.java
@@ -36,7 +36,7 @@
     private List<TamayaPropertyResolver> resolvers = new ArrayList<>();
 
     /**
-     * Constructor similar to getParent.
+     * Constructor similar to parent.
      */
     public TamayaPropertiesComponent(){
         super();
@@ -50,7 +50,7 @@
     }
 
     /**
-     * Constructor similar to getParent with additional locations.
+     * Constructor similar to parent with additional locations.
      * @param locations additional locations for Camel.  
      */
     public TamayaPropertiesComponent(String ... locations){
@@ -65,7 +65,7 @@
     }
 
     /**
-     * Constructor similar to getParent with only one location.
+     * Constructor similar to parent with only one location.
      * @param location addition location for Camel.
      */
     public TamayaPropertiesComponent(String location){
diff --git a/documentation/bnd.bnd b/documentation/bnd.bnd
new file mode 100644
index 0000000..ef18c20
--- /dev/null
+++ b/documentation/bnd.bnd
@@ -0,0 +1,32 @@
+-buildpath: \
+	osgi.annotation; version=6.0.0,\
+	osgi.core; version=6.0,\
+	osgi.cmpn; version=6.0
+
+-testpath: \
+	${junit}
+
+javac.source: 1.8
+javac.target: 1.8
+
+Automatic-Module-Name: org.apache.tamaya.doc
+Bundle-Version: ${version}.${tstamp}
+Bundle-Name: Apache Tamaya - Documentation Generator
+Bundle-SymbolicName: org.apache.tamaya.doc
+Bundle-Description: Apacha Tamaya Configuration - Documentation Generator
+Bundle-Category: Implementation
+Bundle-Copyright: (C) Apache Foundation
+Bundle-License: Apache Licence version 2
+Bundle-Vendor: Apache Software Foundation
+Bundle-ContactAddress: dev-tamaya@incubator.apache.org
+Bundle-DocURL: http://tamaya.apache.org
+Export-Package: \
+	org.apache.tamaya.doc,\
+    org.apache.tamaya.doc.spi
+Import-Package: \
+    org.apache.tamaya,\
+    org.apache.tamaya.spi
+Export-Service: \
+    org.apache.tamaya.doc.spi.ConfigDocumentationMBean,\
+    org.apache.tamaya.doc.spi.ModelProviderSpi
+
diff --git a/documentation/pom.xml b/documentation/pom.xml
new file mode 100644
index 0000000..8ac628f
--- /dev/null
+++ b/documentation/pom.xml
@@ -0,0 +1,72 @@
+<!--
+  ~ 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 createObject the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied.  See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.tamaya.ext</groupId>
+        <artifactId>tamaya-sandbox</artifactId>
+        <version>0.4-incubating-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <artifactId>tamaya-doc_alpha</artifactId>
+    <name>Apache Tamaya Modules - Documentation</name>
+    <description>This extension module provides functionality to document your configuration options easily.
+    </description>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.reflections</groupId>
+            <artifactId>reflections</artifactId>
+            <version>0.9.9-RC1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.j2html</groupId>
+            <artifactId>j2html</artifactId>
+            <version>1.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-core</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-injection-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/ConfigDocumenter.java b/documentation/src/main/java/org/apache/tamaya/doc/ConfigDocumenter.java
new file mode 100644
index 0000000..c726101
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/ConfigDocumenter.java
@@ -0,0 +1,186 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc;
+
+import org.apache.tamaya.doc.annot.*;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.reflections.Reflections;
+import org.reflections.scanners.FieldAnnotationsScanner;
+import org.reflections.scanners.MethodAnnotationsScanner;
+import org.reflections.scanners.TypeAnnotationsScanner;
+import org.reflections.util.ClasspathHelper;
+import org.reflections.util.ConfigurationBuilder;
+import org.reflections.util.FilterBuilder;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Class to read and store the current configuration documentation.
+ */
+public class ConfigDocumenter {
+
+    private DocumentedConfiguration docs = new DocumentedConfiguration();
+
+
+    public static ConfigDocumenter getInstance(){
+        return ServiceContextManager.getServiceContext()
+                .getService(ConfigDocumenter.class, ConfigDocumenter::new);
+    }
+
+    public static ConfigDocumenter getInstance(ClassLoader classLoader){
+        return ServiceContextManager.getServiceContext(classLoader)
+                .getService(ConfigDocumenter.class, ConfigDocumenter::new);
+    }
+
+    /**
+     * Read documentation from the given classes.
+     * @param clazzes the classes to read, not null.
+     */
+    public void readClasses(Class... clazzes){
+        FilterBuilder filterBuilder = new FilterBuilder();
+        List<URL> urls = new ArrayList<>(clazzes.length);
+        for(Class clazz:clazzes){
+//            filterBuilder.exclude(".*");
+            filterBuilder.include(clazz.getName()+".*");
+            urls.add(ClasspathHelper.forClass(clazz));
+        }
+        ConfigurationBuilder configBuilder = new ConfigurationBuilder()
+                .setScanners(new TypeAnnotationsScanner(), new MethodAnnotationsScanner(), new FieldAnnotationsScanner())
+                .setUrls(urls)
+                .filterInputsBy(filterBuilder);
+        Reflections reflections = new Reflections(configBuilder);
+        readSpecs(reflections);
+    }
+
+    /**
+     * Read documentation from the classes managed by the given classloader.
+     * @param classLoader the classloader, not null.
+     */
+    public void readClasses(ClassLoader classLoader){
+        ConfigurationBuilder configBuilder = new ConfigurationBuilder()
+                .setScanners(new TypeAnnotationsScanner(), new MethodAnnotationsScanner(), new FieldAnnotationsScanner())
+                .setUrls(ClasspathHelper.forClassLoader(classLoader));
+        Reflections reflections = new Reflections(configBuilder);
+        readSpecs(reflections);
+    }
+
+    /**
+     * Read documentation from the given packages.
+     * @param packages the package names, not null.
+     */
+    public void readPackages(String... packages) {
+        ConfigurationBuilder configBuilder = new ConfigurationBuilder();
+        FilterBuilder filterBuilder = new FilterBuilder();
+        for (String p : packages) {
+            filterBuilder.includePackage(p);
+        }
+        configBuilder.filterInputsBy(filterBuilder);
+        configBuilder.setUrls(ClasspathHelper.forJavaClassPath());
+        configBuilder.setScanners(new TypeAnnotationsScanner(), new MethodAnnotationsScanner(), new FieldAnnotationsScanner());
+        Reflections reflections = new Reflections(configBuilder);
+        readSpecs(reflections);
+    }
+
+    /**
+     * Access the collected configuration documentation.
+     * @return the documentation, not null.
+     */
+    public DocumentedConfiguration getDocumentation(){
+        return docs;
+    }
+
+    private void readSpecs(Reflections reflections){
+        // types
+        for(Class type:reflections.getTypesAnnotatedWith(ConfigSpec.class)){
+            readConfigSpec(type);
+        }
+        for(Class type:reflections.getTypesAnnotatedWith(ConfigAreaSpec.class)){
+            readAreaSpec(type);
+        }
+        for(Class type:reflections.getTypesAnnotatedWith(ConfigAreaSpecs.class)){
+            readAreaSpecs(type);
+        }
+        for(Class type:reflections.getTypesAnnotatedWith(ConfigPropertySpec.class)){
+            readPropertySpec(type);
+        }
+        for(Class type:reflections.getTypesAnnotatedWith(ConfigPropertySpecs.class)){
+            readPropertySpecs(type);
+        }
+        // Fields
+        for(Field f:reflections.getFieldsAnnotatedWith(ConfigAreaSpec.class)){
+            readAreaSpec(f);
+        }
+        for(Field f:reflections.getFieldsAnnotatedWith(ConfigAreaSpecs.class)){
+            readAreaSpecs(f);
+        }
+        for(Field f:reflections.getFieldsAnnotatedWith(ConfigPropertySpec.class)){
+            readPropertySpec(f);
+        }
+        for(Field f:reflections.getFieldsAnnotatedWith(ConfigPropertySpecs.class)){
+            readPropertySpecs(f);
+        }
+        // Methods
+        for(Method m:reflections.getMethodsAnnotatedWith(ConfigAreaSpec.class)){
+            readAreaSpec(m);
+        }
+        for(Method m:reflections.getMethodsAnnotatedWith(ConfigAreaSpecs.class)){
+            readAreaSpecs(m);
+        }
+        for(Method m:reflections.getMethodsAnnotatedWith(ConfigPropertySpec.class)){
+            readPropertySpec(m);
+        }
+        for(Method m:reflections.getMethodsAnnotatedWith(ConfigPropertySpecs.class)){
+            readPropertySpecs(m);
+        }
+    }
+
+    private void readConfigSpec(Class type){
+        docs.init((ConfigSpec)type.getAnnotation(ConfigSpec.class), type);
+    }
+
+    private void readAreaSpecs(AnnotatedElement elem){
+        ConfigAreaSpecs areaSpecs = elem.getAnnotation(ConfigAreaSpecs.class);
+        for (ConfigAreaSpec areaSpec:areaSpecs.value()){
+            docs.addGroup(new DocumentedArea(areaSpec, elem));
+        }
+    }
+
+    private void readPropertySpecs(AnnotatedElement elem){
+        ConfigPropertySpecs propertySpecs = elem.getAnnotation(ConfigPropertySpecs.class);
+        for (ConfigPropertySpec propertySpec:propertySpecs.value()){
+            docs.addProperty(new DocumentedProperty(propertySpec, elem));
+        }
+    }
+
+    private void readAreaSpec(AnnotatedElement elem){
+        docs.addGroup(new DocumentedArea(elem.getAnnotation(ConfigAreaSpec.class), elem));
+    }
+
+    private void readPropertySpec(AnnotatedElement elem){
+        docs.addProperty(new DocumentedProperty(elem.getAnnotation(ConfigPropertySpec.class), elem));
+    }
+
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/ModelTarget.java b/documentation/src/main/java/org/apache/tamaya/doc/DocFormat.java
similarity index 68%
rename from validation/src/main/java/org/apache/tamaya/validation/ModelTarget.java
rename to documentation/src/main/java/org/apache/tamaya/doc/DocFormat.java
index 3af63ae..0f5e14a 100644
--- a/validation/src/main/java/org/apache/tamaya/validation/ModelTarget.java
+++ b/documentation/src/main/java/org/apache/tamaya/doc/DocFormat.java
@@ -16,22 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.tamaya.validation;
+package org.apache.tamaya.doc;
 
-/**
- * This enumeration defines the types createObject supported validations.
- */
-public enum ModelTarget {
-    /**
-     * A configuration section.
-     */
-    Section,
-    /**
-     * A configuration paramter.
-     */
-    Parameter,
-    /**
-     * ConfigModel that is a container createObject other validations.
-     */
-    Group,
+import java.util.function.Function;
+
+public interface DocFormat<T> extends Function<DocumentedConfiguration, T> {
+
 }
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedArea.java b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedArea.java
new file mode 100644
index 0000000..e2215b4
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedArea.java
@@ -0,0 +1,264 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc;
+
+import org.apache.tamaya.doc.annot.ConfigAreaSpec;
+import org.apache.tamaya.doc.annot.ConfigPropertySpec;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.inject.spi.InjectionUtils;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+public final class DocumentedArea {
+
+    private final AnnotatedElement owner;
+    private ConfigAreaSpec configArea;
+    private String path;
+    private String description;
+    private PropertyValue.ValueType groupType;
+    private Map<String, DocumentedProperty> properties = new HashMap<>();
+    private Map<String, DocumentedArea> areas = new HashMap<>();
+    private Class<?> valueType;
+
+    private int minCardinality;
+    private int maxCardinality;
+    private Set<DocumentedArea> dependsOnGroups = new TreeSet<>();
+    private Set<DocumentedProperty> dependsOnProperties = new TreeSet<>();
+
+    public DocumentedArea(ConfigAreaSpec areaSpec, AnnotatedElement owner){
+        this.owner = owner;
+        this.configArea = areaSpec;
+        if(!areaSpec.path().isEmpty()) {
+            this.path = areaSpec.path();
+        }else{
+           this.path = evaluatePath(owner);
+        }
+        if(!areaSpec.description().isEmpty()) {
+            this.description = areaSpec.description();
+        }
+        this.groupType = areaSpec.areaType();
+        if(areaSpec.max()>0) {
+            this.maxCardinality = areaSpec.max();
+        }
+        if(areaSpec.min()>0) {
+            this.minCardinality = areaSpec.min();
+        }
+        if(Object.class!=areaSpec.valueType()) {
+            this.valueType = areaSpec.valueType();
+        }else{
+            if(owner instanceof Class){
+                this.valueType = ((Class)owner);
+            }
+        }
+        for(ConfigPropertySpec ps:areaSpec.properties()) {
+            this.properties.put(ps.name(), new DocumentedProperty(ps, owner));
+        }
+    }
+
+    private String evaluatePath(AnnotatedElement owner) {
+        if(owner instanceof Field) {
+            return String.join(", ", InjectionUtils.getKeys((Field) owner));
+        }else if(owner instanceof Method) {
+            return String.join(", ", InjectionUtils.getKeys((Method) owner));
+        }else if(owner instanceof Class) {
+            ConfigDefaultSections sectionsAnnot = owner.getAnnotation(ConfigDefaultSections.class);
+            if(sectionsAnnot!=null){
+                return String.join(", ", sectionsAnnot.value());
+            }
+            return ((Class)owner).getName()+", "+((Class)owner).getSimpleName();
+        }
+        return "<root>";
+    }
+
+    void resolve(DocumentedConfiguration documentation){
+        if(configArea !=null){
+            for(String key: configArea.dependsOnAreas()){
+                this.dependsOnGroups.add(documentation.getGroup(key));
+            }
+            for(String key: configArea.dependsOnProperties()){
+                this.dependsOnProperties.add(documentation.getProperty(key));
+            }
+        }
+    }
+
+    public DocumentedArea addGroup(DocumentedArea group){
+        this.areas.put(group.path, group);
+        return this;
+    }
+
+    public DocumentedArea addProperty(DocumentedProperty property){
+        this.properties.put(property.getName(), property);
+        return this;
+    }
+
+    public AnnotatedElement getOwner() {
+        return owner;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public PropertyValue.ValueType getGroupType() {
+        return groupType;
+    }
+
+    public Map<String, DocumentedProperty> getProperties() {
+        return properties;
+    }
+
+    public List<DocumentedProperty> getPropertiesSorted() {
+        List<DocumentedProperty> result = new ArrayList<>(properties.values());
+        result.sort(Comparator.comparing(DocumentedProperty::getName));
+        return result;
+    }
+
+    public Map<String, DocumentedArea> getAreas() {
+        return areas;
+    }
+
+    public List<DocumentedArea> getAreasSorted() {
+        List<DocumentedArea> result = new ArrayList<>(areas.values());
+        result.sort(Comparator.comparing(DocumentedArea::getPath));
+        return result;
+    }
+
+    public Class<?> getValueType() {
+        return valueType;
+    }
+
+    public int getMinCardinality() {
+        return minCardinality;
+    }
+
+    public int getMaxCardinality() {
+        return maxCardinality;
+    }
+
+    public List<DocumentedArea> getDependsOnAreas() {
+        List<DocumentedArea> result = new ArrayList<>(dependsOnGroups);
+        result.sort(Comparator.comparing(DocumentedArea::getPath));
+        return result;
+    }
+
+    public List<DocumentedProperty> getDependsOnProperties() {
+        List<DocumentedProperty> result = new ArrayList<>(dependsOnProperties);
+        result.sort(Comparator.comparing(DocumentedProperty::getName));
+        return result;
+    }
+
+    public DocumentedArea path(String path) {
+        this.path = path;
+        return this;
+    }
+
+    public DocumentedArea description(String description) {
+        this.description = description;
+        return this;
+    }
+
+    public DocumentedArea groupType(PropertyValue.ValueType groupType) {
+        this.groupType = groupType;
+        return this;
+    }
+
+    public DocumentedArea properties(Map<String, DocumentedProperty> properties) {
+        this.properties = properties;
+        return this;
+    }
+
+    public DocumentedArea groups(Map<String, DocumentedArea> groups) {
+        this.areas = groups;
+        return this;
+    }
+
+    public DocumentedArea valueType(Class<?> valueType) {
+        this.valueType = valueType;
+        return this;
+    }
+
+    public DocumentedArea minCardinality(int minCardinality) {
+        this.minCardinality = minCardinality;
+        return this;
+    }
+
+    public DocumentedArea maxCardinality(int maxCardinality) {
+        this.maxCardinality = maxCardinality;
+        return this;
+    }
+
+    public DocumentedArea dependsOnGroups(Set<DocumentedArea> dependsOnGroups) {
+        this.dependsOnGroups = dependsOnGroups;
+        return this;
+    }
+
+    public DocumentedArea dependsOnProperties(Set<DocumentedProperty> dependsOnProperties) {
+        this.dependsOnProperties = dependsOnProperties;
+        return this;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        DocumentedArea that = (DocumentedArea) o;
+
+        return Objects.equals(this.dependsOnGroups, that.dependsOnGroups) &&
+                Objects.equals(this.dependsOnProperties, that.dependsOnProperties) &&
+                Objects.equals(this.description, that.description) &&
+                Objects.equals(this.areas, that.areas) &&
+                Objects.equals(this.groupType, that.groupType) &&
+                Objects.equals(this.maxCardinality, that.maxCardinality) &&
+                Objects.equals(this.minCardinality, that.minCardinality) &&
+                Objects.equals(this.path, that.path) &&
+                Objects.equals(this.properties, that.properties) &&
+                Objects.equals(this.valueType, that.valueType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(dependsOnGroups, dependsOnProperties, description, areas, groupType, maxCardinality,
+                minCardinality, path, properties, valueType);
+    }
+
+    @Override
+    public String toString() {
+        return "ConfigGroup{" +
+                "path='" + path + '\'' +
+                ", description='" + description + '\'' +
+                ", areaType=" + groupType +
+                ", properties=" + properties +
+                ", areas=" + areas +
+                ", valueType=" + valueType +
+                ", minCardinality=" + minCardinality +
+                ", maxCardinality=" + maxCardinality +
+                ", dependsOnAreas=" + dependsOnGroups +
+                ", dependsOnProperties=" + dependsOnProperties +
+                '}';
+    }
+
+
+}
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedConfiguration.java b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedConfiguration.java
new file mode 100644
index 0000000..62aa446
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedConfiguration.java
@@ -0,0 +1,186 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc;
+
+import org.apache.tamaya.doc.annot.ConfigSpec;
+
+import java.util.*;
+
+/**
+ * Documentation of an application configuration.
+ */
+public final class DocumentedConfiguration {
+
+    private String name;
+    private String version;
+    private Class ownerClass;
+
+    private Map<String, DocumentedProperty> properties = new TreeMap<>();
+    private Map<String, DocumentedArea> groups = new TreeMap<>();
+
+    /**
+     * Creates a new empty configuration documentation.
+     */
+    public DocumentedConfiguration(){}
+
+    /**
+     * Creates a new configuration documentation and initializes it with the values from the annotation given.
+     * @param annotation the spec annotation, not null.
+     */
+    public DocumentedConfiguration(ConfigSpec annotation){
+        init(annotation, null);
+    }
+
+    /**
+     * Initializes the instance with the given annotation.
+     * @param annotation the annotation , not null.
+     * @param ownerClass the annotaed class.
+     */
+    public void init(ConfigSpec annotation, Class ownerClass) {
+        this.name = annotation.name();
+        this.version = annotation.version();
+        this.ownerClass = ownerClass;
+    }
+
+    /**
+     * Get the current configuration name.
+     * @return the name, or {@code <undefined>}.
+     */
+    public String getName() {
+        if(name==null){
+            return "<undefined>";
+        }
+        return name;
+    }
+
+    /**
+     * Get the current configuration version.
+     * @return the version, or {@code <undefined>}.
+     */
+    public String getVersion() {
+        if(version==null){
+            return "<undefined>";
+        }
+        return version;
+    }
+
+    /**
+     * Get the annotated class.
+     * @return the class, or null.
+     */
+    public Class getOwnerClass() {
+        return ownerClass;
+    }
+
+    /**
+     * Get the documented properties.
+     * @return the properties, never null.
+     */
+    public Map<String, DocumentedProperty> getProperties() {
+        return properties;
+    }
+
+    /**
+     * Get the documented properties.
+     * @return the properties, never null.
+     */
+    public List<DocumentedArea> getAllAreasSorted() {
+        List<DocumentedArea> areas = new ArrayList<>();
+        areas.addAll(getAreas().values());
+        areas.sort(this::compareAreas);
+        return areas;
+    }
+
+    private int compareAreas(DocumentedArea area1, DocumentedArea area2) {
+        return area1.getPath().compareTo(area2.getPath());
+    }
+
+    /**
+     * Get the documented properties.
+     * @return the properties, never null.
+     */
+    public List<DocumentedProperty> getAllPropertiesSorted() {
+        List<DocumentedProperty> props = new ArrayList<>();
+        props.addAll(getProperties().values());
+        for(DocumentedArea area:getAreas().values()) {
+            props.addAll(area.getProperties().values());
+        }
+        props.sort(this::compareProperties);
+        return props;
+    }
+
+    private int compareProperties(DocumentedProperty property, DocumentedProperty property1) {
+        return property.getName().compareTo(property1.getName());
+    }
+
+    /**
+     * Get the documented areas.
+     * @return the areas, never null.
+     */
+    public Map<String, DocumentedArea> getAreas() {
+        return groups;
+    }
+
+    public DocumentedArea getGroup(String path) {
+        return null;
+    }
+
+    public DocumentedProperty getProperty(String path) {
+        return null;
+    }
+
+    public DocumentedConfiguration addProperty(DocumentedProperty property){
+        this.properties.put(property.getName(), property);
+        return this;
+    }
+
+    public DocumentedConfiguration addGroup(DocumentedArea group){
+        this.groups.put(group.getPath(), group);
+        return this;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof DocumentedConfiguration)) return false;
+
+        DocumentedConfiguration that = (DocumentedConfiguration) o;
+
+        if (!name.equals(that.name)) return false;
+        return version.equals(that.version);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = 31 * result + version.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "DocumentedConfiguration{" +
+                "name='" + name + '\'' +
+                ", version='" + version + '\'' +
+                ", properties=" + properties +
+                ", groups=" + groups +
+                '}';
+    }
+
+}
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/DocumentedProperty.java b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedProperty.java
new file mode 100644
index 0000000..b270aea
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/DocumentedProperty.java
@@ -0,0 +1,188 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc;
+
+import org.apache.tamaya.doc.annot.ConfigPropertySpec;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.spi.InjectionUtils;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.*;
+
+public final class DocumentedProperty {
+
+    private final AnnotatedElement owner;
+    private ConfigPropertySpec propertySpec;
+    private String name;
+    private String defaultValue;
+    private boolean required;
+    private String description;
+    private Class<?> valueType;
+
+    private Set<DocumentedArea> dependsOnGroups = new TreeSet<>();
+    private Set<DocumentedProperty> dependsOnProperties = new TreeSet<>();
+
+
+    public DocumentedProperty(ConfigPropertySpec annot, AnnotatedElement owner){
+        this.owner = owner;
+        this.propertySpec = annot;
+        if(!annot.name().isEmpty()) {
+            this.name = annot.name();
+        }else{
+            if(owner instanceof Field) {
+                this.name = String.join(", ", InjectionUtils.getKeys((Field) owner));
+            }else if(owner instanceof Method) {
+                this.name = String.join(", ", InjectionUtils.getKeys((Method) owner));
+            }
+        }
+        this.description = annot.description();
+        this.valueType = annot.valueType();
+        if(String.class.equals(this.valueType)){
+            if(owner instanceof Field){
+                Field f = (Field)owner;
+                this.valueType = f.getType();
+            }else if(owner instanceof Method){
+                Method m = (Method)owner;
+                this.valueType = m.getParameterTypes()[0];
+            }
+        }
+        Config configAnnot = owner.getAnnotation(Config.class);
+        if(configAnnot!=null){
+            this.required = configAnnot.required();
+            this.defaultValue = configAnnot.defaultValue();
+        }
+    }
+
+    void resolve(DocumentedConfiguration documentation){
+        if(propertySpec !=null){
+            for(String key: propertySpec.dependsOnAreas()){
+                this.dependsOnGroups.add(documentation.getGroup(key));
+            }
+            for(String key: propertySpec.dependsOnProperties()){
+                this.dependsOnProperties.add(documentation.getProperty(key));
+            }
+        }
+    }
+
+    public AnnotatedElement getOwner() {
+        return owner;
+    }
+
+    public String getDefaultValue() {
+        if(defaultValue==null){
+            return "";
+        }
+        return defaultValue;
+    }
+
+    public boolean isRequired() {
+        return required;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        if(description==null){
+            return "";
+        }
+        return description;
+    }
+
+    public Class<?> getValueType() {
+        return valueType;
+    }
+
+    public Set<DocumentedArea> getDependsOnGroups() {
+        return dependsOnGroups;
+    }
+
+    public Set<DocumentedProperty> getDependsOnProperties() {
+        return dependsOnProperties;
+    }
+
+    public DocumentedProperty path(String path) {
+        this.name = path;
+        return this;
+    }
+
+    public DocumentedProperty description(String description) {
+        this.description = description;
+        return this;
+    }
+
+    public DocumentedProperty valueType(Class<?> valueType) {
+        this.valueType = valueType;
+        return this;
+    }
+
+    public DocumentedProperty dependsOnGroups(Collection<DocumentedArea> dependsOnGroups) {
+        this.dependsOnGroups.addAll(dependsOnGroups);
+        return this;
+    }
+
+    public DocumentedProperty dependsOnGroups(DocumentedArea... dependsOnGroups) {
+        this.dependsOnGroups.addAll(Arrays.asList(dependsOnGroups));
+        return this;
+    }
+
+    public DocumentedProperty dependsOnProperties(Collection<DocumentedProperty> dependsOnProperties) {
+        this.dependsOnProperties.addAll(dependsOnProperties);
+        return this;
+    }
+
+    public DocumentedProperty dependsOnProperties(DocumentedProperty... dependsOnProperties) {
+        this.dependsOnProperties.addAll(Arrays.asList(dependsOnProperties));
+        return this;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        DocumentedProperty that = (DocumentedProperty) o;
+
+        return Objects.equals(this.dependsOnGroups, that.dependsOnGroups) &&
+                Objects.equals(this.dependsOnProperties, that.dependsOnProperties) &&
+                Objects.equals(this.description, that.description) &&
+                Objects.equals(this.name, that.name) &&
+                Objects.equals(this.valueType, that.valueType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(dependsOnGroups, dependsOnProperties, description, name, valueType);
+    }
+
+    @Override
+    public String toString() {
+        return "ConfigGroup{" +
+                "name='" + name + '\'' +
+                ", description='" + description + '\'' +
+                ", valueType=" + valueType +
+                ", dependsOnAreas=" + dependsOnGroups +
+                ", dependsOnProperties=" + dependsOnProperties +
+                '}';
+    }
+
+}
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpec.java b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpec.java
new file mode 100644
index 0000000..27c27fa
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpec.java
@@ -0,0 +1,94 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc.annot;
+
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation allows to specify a configuration area.
+ */
+@Repeatable(ConfigAreaSpecs.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+public @interface ConfigAreaSpec {
+    /**
+     * The areas configuration area path, e.g. {@code foo.bar}. An empty String means the root
+     * of the configuration tree.
+     * @return the path, not null.
+     */
+    String path()default"";
+
+    /**
+     * Define a description of the area.
+     * @return the description.
+     */
+    String description() default "";
+
+    /**
+     * Defines the value type that is represented by a given area path, e.g. all properties on level
+     * {@code foo.bar.Server} are mapped to some client classes {@code a.b.ServerConfig}.
+     * @return the type mapping, if any.
+     */
+    Class<?> valueType() default Object.class;
+
+    /**
+     * Allows to specifiy the node type of an area:
+     * <ul>
+     *     <li><b>ARRAY: </b> is an array of child items.</li>
+     *     <li><b>MAP: </b> is an map of named child items.</li>
+     * </ul>
+     * @return the area group type, default is {@link org.apache.tamaya.spi.PropertyValue.ValueType#MAP}.
+     */
+    PropertyValue.ValueType areaType() default PropertyValue.ValueType.MAP;
+
+    /**
+     * The minimal cardinality required. A cardinality &gt; 0 means that the corresponding area must be present
+     * in your configuration. This can be ensured/checked by a configuration validation system.
+     * @return the minimal cardinality.
+     */
+    int min() default 0;
+
+    /**
+     * The maximal cardinality allowed. A cardinality &gt; 0 means that the corresponding area must not be present
+     * in your configuration more than the configured times. This can be ensured/checked by a configuration validation
+     * system.
+     * @return the maximal cardinality.
+     */
+    int max() default 0;
+
+    /**
+     * The properties managed in this area.
+     * @return the properties managed within this area.
+     */
+    ConfigPropertySpec[] properties() default {};
+
+    /**
+     * Allows to define that this area is only required, if any of these configured areas are present in your config.
+     * @return the area dependencies. This can be ensured/checked by a configuration validation
+     */
+    String[] dependsOnAreas() default {};
+
+    /**
+     * Allows to define that this area is only required, if any of these configured properties are present in your config.
+     * @return the area dependencies. This can be ensured/checked by a configuration validation
+     */
+    String[] dependsOnProperties() default {};
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/ModelProviderSpi.java b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpecs.java
similarity index 60%
rename from validation/src/main/java/org/apache/tamaya/validation/spi/ModelProviderSpi.java
rename to documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpecs.java
index 74bccd1..5735c16 100644
--- a/validation/src/main/java/org/apache/tamaya/validation/spi/ModelProviderSpi.java
+++ b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigAreaSpecs.java
@@ -16,24 +16,23 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.tamaya.validation.spi;
+package org.apache.tamaya.doc.annot;
 
-import org.apache.tamaya.validation.ConfigModel;
-
-import java.util.Collection;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
- * Model createObject a configuration state. A model can be a full model, or a partial model, validating only
- * a configuration subset. This allows better user feedback because big configurations can be grouped
- * and validated by multiple (partial) models.
+ * This is the container annotation for the repeatable {@link ConfigAreaSpec} annotation.
  */
-public interface ModelProviderSpi {
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+public @interface ConfigAreaSpecs {
 
     /**
-     * Get the validation defined.
-     *
-     * @return the sections defined, never null.
+     * The contained child annotations.
+     * @return the contained annotations.
      */
-    Collection<ConfigModel> getConfigModels();
-
+    ConfigAreaSpec[] value()default{};
 }
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpec.java b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpec.java
new file mode 100644
index 0000000..49ee6df
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpec.java
@@ -0,0 +1,63 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc.annot;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+public @interface ConfigPropertySpec {
+
+//    boolean id() default false;
+
+    /**
+     * The property name. The full property key is a combination of the parent
+     * @return the name of the property, taken from the default resolution, if empty.
+     */
+    String name() default "";
+
+    /**
+     * Define a description of the property.
+     * @return the description.
+     */
+    String description() default "";
+
+    /**
+     * The property's value type, by default {@link String}.
+     * @return the property's value type.
+     */
+    Class<?> valueType() default String.class;
+
+    /**
+     * Allows to define that this property is only required, if any of these configured areas are present in your config.
+     * @return the area dependencies. This can be ensured/checked by a configuration validation
+     */
+    String[] dependsOnAreas() default {};
+
+    /**
+     * Allows to define that this property is only required, if any of these configured properties are present in your config.
+     * @return the area dependencies. This can be ensured/checked by a configuration validation
+     */
+    String[] dependsOnProperties() default {};
+
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/ModelProviderSpi.java b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpecs.java
similarity index 60%
copy from validation/src/main/java/org/apache/tamaya/validation/spi/ModelProviderSpi.java
copy to documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpecs.java
index 74bccd1..a8fd4f0 100644
--- a/validation/src/main/java/org/apache/tamaya/validation/spi/ModelProviderSpi.java
+++ b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigPropertySpecs.java
@@ -16,24 +16,23 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.tamaya.validation.spi;
+package org.apache.tamaya.doc.annot;
 
-import org.apache.tamaya.validation.ConfigModel;
-
-import java.util.Collection;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
- * Model createObject a configuration state. A model can be a full model, or a partial model, validating only
- * a configuration subset. This allows better user feedback because big configurations can be grouped
- * and validated by multiple (partial) models.
+ * This is the container annotation for the repeatable {@link ConfigPropertySpec} annotation.
  */
-public interface ModelProviderSpi {
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+public @interface ConfigPropertySpecs {
 
     /**
-     * Get the validation defined.
-     *
-     * @return the sections defined, never null.
+     * The contained child annotations.
+     * @return the contained annotations.
      */
-    Collection<ConfigModel> getConfigModels();
-
+    ConfigPropertySpec[] value()default{};
 }
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigSpec.java b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigSpec.java
new file mode 100644
index 0000000..5f0c798
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/annot/ConfigSpec.java
@@ -0,0 +1,48 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc.annot;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to specify the main configuration properties.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ConfigSpec {
+    String name() default "";
+    String version() default "";
+
+    /**
+     * Define a description of the configuration.
+     * @return the description.
+     */
+    String description() default "";
+
+    /**
+     * Should loading of the configuration fail, if a validation failed, default is {@code false}, where
+     * a warning is logged only.
+     * @return true to fail config load on configuration validation failures.
+     */
+    boolean failOnErrors() default false;
+}
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/formats/HtmlDocFormat.java b/documentation/src/main/java/org/apache/tamaya/doc/formats/HtmlDocFormat.java
new file mode 100644
index 0000000..b37bf80
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/formats/HtmlDocFormat.java
@@ -0,0 +1,127 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc.formats;
+
+import j2html.tags.ContainerTag;
+import org.apache.tamaya.doc.DocFormat;
+import org.apache.tamaya.doc.DocumentedArea;
+import org.apache.tamaya.doc.DocumentedConfiguration;
+import org.apache.tamaya.doc.DocumentedProperty;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static j2html.TagCreator.*;
+
+public class HtmlDocFormat implements DocFormat<String> {
+    @Override
+    public String apply(DocumentedConfiguration documentedConfiguration) {
+        List<ContainerTag> areaTags = new ArrayList<>();
+        for(DocumentedArea area:documentedConfiguration.getAllAreasSorted()) {
+            areaTags.addAll(createAreaEntries(area, null));
+        }
+        ContainerTag propertiesTable = createPropertiesTable(documentedConfiguration.getAllPropertiesSorted(), null);
+
+        ContainerTag head = createHead(documentedConfiguration);
+        ContainerTag body = body()
+                .with(
+                    h1("Configuration Documentation (" + documentedConfiguration.getName() + ")"),
+                    p("Version: " + documentedConfiguration.getVersion()),
+                    h2("Documented Areas")).with(areaTags)
+                .with(
+                    h2("Documented Properties"),
+                    propertiesTable);
+        String result = html(head, body).render();
+        writeResultToFile(result);
+        return result;
+    }
+
+    private void writeResultToFile(String result) {
+        File file = new File("./doc.html");
+        FileWriter w;
+        try {
+            w = new FileWriter(file);
+            w.append(result);
+            w.flush();
+            w.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private ContainerTag createHead(DocumentedConfiguration config) {
+        return head(title("Tamaya Configuration - " + config.getName() + " " +
+                        config.getVersion()),
+                meta().withCharset("utf-8"),
+                meta().withName("viewport").withContent("width=device-width, initial-scale=0.9, shrink-to-fit=yes"),
+                link().withRel("stylesheet")
+                        .withHref("https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css")
+                        .attr("integrity","sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm")
+                        .attr("crossorigin","anonymous"));
+    }
+
+    private ContainerTag createPropertiesTable(List<DocumentedProperty> properties, String parentArea) {
+        List<ContainerTag> propertyRows = new ArrayList<>();
+        for (DocumentedProperty prop : properties) {
+            propertyRows.add(tr(
+                    td(pre(prop.getName().replace(", ", "\n"))).attr("scope","row"),
+                    td(Object.class==prop.getValueType()?"":prop.getValueType().getName()),
+                    td(prop.getDescription()),
+                    td(i(prop.getDefaultValue()))
+            ));
+        }
+        ContainerTag propertiesTable = table(
+                thead(tr(
+                        th("Key(s)").attr("scope","col"),
+                        th("Valuetype").attr("scope","col"),
+                        th("Description").attr("width", "75%").attr("scope","col"),
+                        th("Default").attr("scope","col").attr("width", "15%")
+                )).withClass("thead-dark")
+        ).with(propertyRows.toArray(new ContainerTag[propertyRows.size()]))
+                .withClass("table table-striped table-hover table-bordered table-sm")
+                .attr("width", "90%");
+        return propertiesTable;
+    }
+
+    private List<ContainerTag> createAreaEntries(DocumentedArea area, String parentArea) {
+        List<ContainerTag> result = new ArrayList<>();
+        if(parentArea==null){
+            result.add(h4(area.getPath()));
+        }else{
+            result.add(h4(parentArea + "."+ area.getPath()));
+        }
+        result.add(ul(
+                li(b("Group Type: "), text(area.getGroupType().toString()),
+                li(b("Valuetype: "), text(area.getValueType().getName()))
+                        .withCondHidden(Object.class==area.getValueType()),
+                li(b("Description: "), text(area.getDescription()))
+                        .withCondHidden(area.getDescription()==null),
+                li(b("Properties: ")).with(createPropertiesTable(area.getPropertiesSorted(), area.getPath()))
+                        .withCondHidden(area.getProperties().isEmpty())
+        )));
+        for(DocumentedArea subArea:area.getAreasSorted()){
+            result.addAll(createAreaEntries(subArea, area.getPath()));
+        }
+        return result;
+    }
+
+}
diff --git a/documentation/src/main/java/org/apache/tamaya/doc/formats/TextDocFormat.java b/documentation/src/main/java/org/apache/tamaya/doc/formats/TextDocFormat.java
new file mode 100644
index 0000000..4172cb9
--- /dev/null
+++ b/documentation/src/main/java/org/apache/tamaya/doc/formats/TextDocFormat.java
@@ -0,0 +1,124 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc.formats;
+
+import org.apache.tamaya.doc.DocFormat;
+import org.apache.tamaya.doc.DocumentedConfiguration;
+import org.apache.tamaya.doc.DocumentedArea;
+import org.apache.tamaya.doc.DocumentedProperty;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class TextDocFormat implements DocFormat<String> {
+    @Override
+    public String apply(DocumentedConfiguration documentedConfiguration) {
+        StringBuilder b = new StringBuilder();
+        b.append("Configuration:\n");
+        b.append("  Spec    : ").append(documentedConfiguration.getName()).append('\n');
+        b.append("  Version : ").append(documentedConfiguration.getVersion()).append('\n');
+        if(documentedConfiguration.getOwnerClass()!=null){
+            b.append("  Owner   : ").append(documentedConfiguration.getOwnerClass().getName()).append('\n');
+        }
+        if(!documentedConfiguration.getAreas().isEmpty()) {
+            b.append("Areas: ").append('\n');
+            for (DocumentedArea area : documentedConfiguration.getAreas().values()) {
+                printArea("  ", area, b);
+            }
+        }
+        if(!documentedConfiguration.getProperties().isEmpty()) {
+            b.append("Properties: ").append('\n');
+            for (DocumentedProperty prop : documentedConfiguration.getProperties().values()) {
+                printProperty("  ", prop, b);
+            }
+        }
+        return b.toString();
+    }
+
+    private void printArea(String inset, DocumentedArea area, StringBuilder b) {
+        if(!area.getPath().isEmpty()) {
+            b.append(inset).append("- name     : ").append(area.getPath()).append("\n");
+        }else{
+            b.append(inset).append("- name     : NONE\n");
+        }
+//        b.append(inset).    append("  Type     : area\n");
+        if(area.getOwner()!=null){
+            b.append(inset).append("  Owner    : ").append(printOwner(area.getOwner())).append('\n');
+        }
+        if(area.getDescription()!=null) {
+            b.append(inset).append("  Descr    : ").append(area.getDescription()).append('\n');
+        }
+        b.append(inset).    append("  Areatype : ").append(area.getGroupType()).append('\n');
+        if(area.getMinCardinality()!=0) {
+            b.append(inset).append("  Min      : ").append(area.getMinCardinality()).append('\n');
+        }
+        if(area.getMaxCardinality()!=0) {
+            b.append(inset).append("  Max      : ").append(area.getMaxCardinality()).append('\n');
+        }
+        if(area.getValueType()!=Object.class) {
+            b.append(inset).append("  Value    : ").append(area.getValueType().getName()).append('\n');
+        }
+        if(!area.getProperties().isEmpty()) {
+            b.append(inset).append("  Properties : ").append('\n');
+            for (DocumentedProperty prop : area.getProperties().values()) {
+                printProperty(inset + "    ", prop, b);
+            }
+        }
+        if(!area.getAreas().isEmpty()) {
+            b.append(inset).append("  Areas   : ").append('\n');
+            for (DocumentedArea childArea : area.getAreas().values()) {
+                printArea(inset + "  ", childArea, b);
+            }
+        }
+    }
+
+    private void printProperty(String inset, DocumentedProperty prop, StringBuilder b) {
+        b.append(inset).append("- Name     : ").append(prop.getName()).append("\n");
+//        b.append(inset).append("  Type     : property\n");
+        if(prop.getOwner()!=null){
+            b.append(inset).append("  Owner    : ").append(printOwner(prop.getOwner())).append('\n');
+        }
+        if(prop.getDescription()!=null) {
+            b.append(inset).append("  Descr    : ").append(prop.getDescription()).append('\n');
+        }
+        b.append(inset).append("  Value    : ").append(prop.getValueType().getName()).append('\n');
+    }
+
+    private String printOwner(AnnotatedElement owner) {
+        if(owner instanceof Type){
+            return ((Type)owner).getTypeName();
+        }else if(owner instanceof Field){
+            Field f = (Field)owner;
+            return f.getDeclaringClass().getName()+ '#' + f.getName()+": " + f.getType().getName();
+        }
+        else if(owner instanceof Method){
+            Method m = (Method)owner;
+            return m.getDeclaringClass().getName()+ '#' + m.getName()+
+                    "("+String.join(", ", Stream.of(m.getParameterTypes()).map(c -> c.getName())
+                    .collect(Collectors.toList())) + "): " +
+                    m.getReturnType().getName();
+        }else{
+            return String.valueOf(owner);
+        }
+    }
+}
diff --git a/documentation/src/main/resources/META-INF/configmodel.properties b/documentation/src/main/resources/META-INF/configmodel.properties
new file mode 100644
index 0000000..3381a09
--- /dev/null
+++ b/documentation/src/main/resources/META-INF/configmodel.properties
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Contains definitions for default system property areas.
+_awt.model.target=Section
+_awt.model.transitive=true
+_file.model.target=Section
+_file.model.transitive=true
+_java.model.target=Section
+_java.model.transitive=true
+_line.model.target=Section
+_line.model.transitive=true
+_os.model.target=Section
+_os.model.transitive=true
+_path.model.target=Section
+_path.model.transitive=true
+_sun.model.target=Section
+_sun.model.transitive=true
+_user.model.target=Section
+_user.model.transitive=true
diff --git a/documentation/src/main/resources/META-INF/services/org.apache.tamaya.validation.spi.ConfigDocumentationMBean b/documentation/src/main/resources/META-INF/services/org.apache.tamaya.validation.spi.ConfigDocumentationMBean
new file mode 100644
index 0000000..576695e
--- /dev/null
+++ b/documentation/src/main/resources/META-INF/services/org.apache.tamaya.validation.spi.ConfigDocumentationMBean
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.validation.internal.ConfigDocumentationBean
\ No newline at end of file
diff --git a/documentation/src/main/resources/META-INF/services/org.apache.tamaya.validation.spi.ModelProviderSpi b/documentation/src/main/resources/META-INF/services/org.apache.tamaya.validation.spi.ModelProviderSpi
new file mode 100644
index 0000000..2788871
--- /dev/null
+++ b/documentation/src/main/resources/META-INF/services/org.apache.tamaya.validation.spi.ModelProviderSpi
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.validation.internal.ConfiguredPropertiesModelProviderSpi
+org.apache.tamaya.validation.internal.ConfiguredInlineModelProviderSpi
+org.apache.tamaya.validation.internal.ConfiguredResourcesModelProviderSpi
+org.apache.tamaya.validation.internal.ConfiguredTypeEventsModelProvider
\ No newline at end of file
diff --git a/documentation/src/main/resources/img/tamaya.png b/documentation/src/main/resources/img/tamaya.png
new file mode 100644
index 0000000..16df5d7
--- /dev/null
+++ b/documentation/src/main/resources/img/tamaya.png
Binary files differ
diff --git a/documentation/src/test/java/org/apache/tamaya/doc/AnnotBasedStandaloneConfigDocumentation.java b/documentation/src/test/java/org/apache/tamaya/doc/AnnotBasedStandaloneConfigDocumentation.java
new file mode 100644
index 0000000..e6bc60f
--- /dev/null
+++ b/documentation/src/test/java/org/apache/tamaya/doc/AnnotBasedStandaloneConfigDocumentation.java
@@ -0,0 +1,80 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc;
+
+import org.apache.tamaya.doc.annot.ConfigAreaSpec;
+import org.apache.tamaya.doc.annot.ConfigPropertySpec;
+import org.apache.tamaya.doc.annot.ConfigSpec;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.net.URL;
+
+@ConfigSpec(
+        name="Test",
+        version="0.1.0",
+        description = "Tomcat Configuration based on Tamaya"
+)
+@ConfigAreaSpec(
+        path = "kubernetes",
+        description = "Kubernetes Settings",
+        areaType = PropertyValue.ValueType.MAP,
+        max = 1
+)
+@ConfigAreaSpec(
+        path = "kubernetes.security",
+        description = "Kubernetes Security Settings",
+        areaType = PropertyValue.ValueType.MAP,
+        max = 1
+)
+@ConfigAreaSpec(
+        path = "kubernetes.cluster",
+        description = "Kubernetes Cluster Options",
+        areaType = PropertyValue.ValueType.MAP,
+        max = 1
+)
+@ConfigAreaSpec(
+        path = "<root>",
+        description = "Main Options",
+        areaType = PropertyValue.ValueType.MAP,
+        properties = {
+                @ConfigPropertySpec(name="log", description ="Log the server startup in detail, default: false.",
+                        valueType = Boolean.class),
+                @ConfigPropertySpec(name="refresh", description = "Refresh interval in millis, default: 1000ms",
+                        valueType = Long.class),
+        }
+)
+public interface AnnotBasedStandaloneConfigDocumentation {
+
+    @ConfigAreaSpec(
+            description = "Tomcat Server Endpoints",
+            min = 1,
+            areaType = PropertyValue.ValueType.ARRAY)
+    @ConfigDefaultSections("servers")
+    class Server{
+        @ConfigPropertySpec(description = "The server name.")
+        @Config(required = true)
+        private String name;
+        @ConfigPropertySpec(description = "The server url.")
+        @Config(required = true)
+        private URL url;
+    }
+
+}
diff --git a/documentation/src/test/java/org/apache/tamaya/doc/AnnotatedDocConfigBean.java b/documentation/src/test/java/org/apache/tamaya/doc/AnnotatedDocConfigBean.java
new file mode 100644
index 0000000..184c4ce
--- /dev/null
+++ b/documentation/src/test/java/org/apache/tamaya/doc/AnnotatedDocConfigBean.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.doc;
+
+import org.apache.tamaya.doc.annot.ConfigAreaSpec;
+import org.apache.tamaya.doc.annot.ConfigPropertySpec;
+import org.apache.tamaya.doc.annot.ConfigSpec;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.DynamicValue;
+import org.apache.tamaya.inject.api.NoConfig;
+import org.apache.tamaya.spi.PropertyValue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An example showing some basic annotations, using an interface to be proxied by the
+ * configuration system, nevertheless extending the overall Configuration interface.
+ * Created by Anatole on 15.02.14.
+ */
+@ConfigSpec(
+        name="Test",
+        version="0.1.0"
+)
+@ConfigAreaSpec(
+        path="",
+        description = "Default root configuration",
+        areaType = PropertyValue.ValueType.MAP
+)
+public class AnnotatedDocConfigBean {
+
+    @ConfigPropertySpec(description = "Tests a multi key resolution")
+    @Config(value = {"foo.bar.myprop", "mp", "common.testdata.myProperty"}, defaultValue = "ET")
+    public String myParameter;
+
+    @ConfigPropertySpec(description = "Tests a simple String description")
+    @Config("simple_value")
+    public String simpleValue;
+
+    @ConfigPropertySpec(description = "Another test value without any explicit definition")
+    @Config
+    String anotherValue;
+
+    @ConfigPropertySpec(description = "An explicit config parameter value.")
+    @Config("[host.name]")
+    private String hostName;
+
+    @ConfigPropertySpec(description = "An non String typed instance.")
+    @Config("host.name")
+    private DynamicValue<String> dynamicHostname;
+
+    @NoConfig
+    public String javaVersion;
+
+    public String getAnotherValue(){
+        return anotherValue;
+    }
+
+    public String getHostName(){
+        return hostName;
+    }
+
+    public DynamicValue<String> getDynamicValue(){
+        return dynamicHostname;
+    }
+
+    @NoConfig
+    private List<String> events = new ArrayList<>();
+
+    // verify we don't try to inject final fields
+    public static final String CONSTANT = "a constant";
+
+
+    @Config("java.version")
+    void setJavaVersion(String version){
+        this.javaVersion = version;
+    }
+
+}
diff --git a/documentation/src/test/java/org/apache/tamaya/doc/ConfigDocumenterTest.java b/documentation/src/test/java/org/apache/tamaya/doc/ConfigDocumenterTest.java
new file mode 100644
index 0000000..1979e74
--- /dev/null
+++ b/documentation/src/test/java/org/apache/tamaya/doc/ConfigDocumenterTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.doc;
+
+import org.apache.tamaya.doc.formats.HtmlDocFormat;
+import org.apache.tamaya.doc.formats.TextDocFormat;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ConfigDocumenterTest {
+
+    @Test
+    public void getDocumentationAndPrint_ConfigBean() {
+        ConfigDocumenter reader = new ConfigDocumenter();
+        reader.readClasses(AnnotatedDocConfigBean.class);
+        DocumentedConfiguration documentation = reader.getDocumentation();
+        assertNotNull(documentation);
+        System.out.println(new TextDocFormat().apply(documentation));
+    }
+
+    @Test
+    public void getDocumentationAndPrint_AnnotationType() {
+        ConfigDocumenter reader = new ConfigDocumenter();
+        reader.readClasses(AnnotBasedStandaloneConfigDocumentation.class);
+        DocumentedConfiguration documentation = reader.getDocumentation();
+        assertNotNull(documentation);
+        System.out.println(new TextDocFormat().apply(documentation));
+    }
+
+    @Test
+    public void getDocumentationAndPrint_Package() {
+        ConfigDocumenter reader = new ConfigDocumenter();
+        reader.readPackages("org.apache.tamaya.doc");
+        DocumentedConfiguration documentation = reader.getDocumentation();
+        assertNotNull(documentation);
+        System.out.println(new TextDocFormat().apply(documentation));
+    }
+
+    @Test
+    public void getDocumentationAndPrint_Package_html() {
+        ConfigDocumenter reader = new ConfigDocumenter();
+        reader.readPackages("org.apache.tamaya.doc");
+        DocumentedConfiguration documentation = reader.getDocumentation();
+        assertNotNull(documentation);
+        System.out.println(new HtmlDocFormat().apply(documentation));
+    }
+}
\ No newline at end of file
diff --git a/documentation/src/test/resources/META-INF/configmodel.properties b/documentation/src/test/resources/META-INF/configmodel.properties
new file mode 100644
index 0000000..7152615
--- /dev/null
+++ b/documentation/src/test/resources/META-INF/configmodel.properties
@@ -0,0 +1,96 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+###################################################################################
+# Example createObject a configuration metamodel expressed via properties.
+####################################################################################
+
+# Metamodel information
+_model.provider=ConfigModel Extension
+
+# reusable parameter definition, referenceable as MyNumber
+_MyNumber.model.target=Parameter
+_MyNumber.model.type=Integer
+_MyNumber.model.description=a (reusable) number type parameter (optional)
+
+####################################################################################
+# Description createObject Configuration Sections (minimal, can be extended by other modules).
+# By default its interpreted as a section !
+####################################################################################
+
+# a (section)
+_a.model.target=Section
+_a.params2.model.target=Parameter
+_a.params2.model.type=String
+_a.params2.model.required=true
+_a.params2.model.description=a required parameter
+
+_a.paramInt.model.target=Parameter
+_a.paramInt.model.type=ref:MyNumber
+_a.paramInt.model.description=an optional parameter (default)
+
+_a._number.model.target=Parameter
+_a._number.model.type=Integer
+_a._number.model.deprecated=true
+_a._number.model.mappedTo=a.paramInt
+
+# a.b.c (section)
+_a.b.c.model.target=Section
+_a.b.c.model.description=Just a test section
+
+# a.b.c.aRequiredSection (section)
+_a.b.c.aRequiredSection.model.target=Section
+_a.b.c.aRequiredSection.model.required=true
+_a.b.c.aRequiredSection.model.description=A section containing required parameters is called a required section.\
+         Sections can also explicitly be defined to be required, but without\
+         specifying the paramteres to be contained.,
+
+# a.b.c.aRequiredSection.subsection (section)
+_a.b.c.aRequiredSection.subsection.model.target=Section
+
+_a.b.c.aRequiredSection.subsection.param0.model.model.target=Parameter
+_a.b.c.aRequiredSection.subsection.param0.type=String
+_a.b.c.aRequiredSection.subsection.param0.model.description=a minmally documented String parameter
+# A minmal String parameter
+_a.b.c.aRequiredSection.subsection.param00.model.target=Parameter
+_a.b.c.aRequiredSection.subsection.param00.model.type=String
+
+# a.b.c.aRequiredSection.subsection (section)
+_a.b.c.aRequiredSection.subsection.param1.model.target=Parameter
+_a.b.c.aRequiredSection.subsection.param1.model.type = String
+_a.b.c.aRequiredSection.subsection.param1.model.required = true
+_a.b.c.aRequiredSection.subsection.intParam.model.target=Parameter
+_a.b.c.aRequiredSection.subsection.intParam.model.type = Integer
+_a.b.c.aRequiredSection.subsection.intParam.model.description=an optional parameter (default)
+
+# a.b.c.aRequiredSection.nonempty-subsection (section)
+_a.b.c.aRequiredSection.nonempty-subsection.model.target=Section
+_a.b.c.aRequiredSection.nonempty-subsection.model.required=true
+
+# a.b.c.aRequiredSection.optional-subsection (section)
+_a.b.c.aRequiredSection.optional-subsection.model.target=Section
+
+# a.b.c.aValidatedSection (section)
+_a.b.c.aValidatedSection.model.target=Section
+_a.b.c.aValidatedSection.model.description=A validated section.
+_a.b.c.aValidatedSection.model.validator=org.apache.tamaya.model.TestValidator
+
+
+
+
diff --git a/documentation/src/test/resources/META-INF/javaconfiguration.properties b/documentation/src/test/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..b0b8c22
--- /dev/null
+++ b/documentation/src/test/resources/META-INF/javaconfiguration.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+a.test.existing.aParam=existingValue
+a.test.existing.optionalParam=optionalValue
+a.test.existing.aABCParam=ABCparam
+a.test.existing.aABCParam2=MMM
diff --git a/documentation/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi b/documentation/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
new file mode 100644
index 0000000..9b29fda
--- /dev/null
+++ b/documentation/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.model.ConfigModelProviderTest
\ No newline at end of file
diff --git a/documentation/src/test/resources/examples/configmodel.ini b/documentation/src/test/resources/examples/configmodel.ini
new file mode 100644
index 0000000..0e10cc1
--- /dev/null
+++ b/documentation/src/test/resources/examples/configmodel.ini
@@ -0,0 +1,76 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+###################################################################################
+# Example of a configuration metamodel expressed via ini(tm).
+####################################################################################
+
+####################################################################################
+# Description of Configuration Sections (minimal, can be extended by other modules).
+# By default its interpreted as a section !
+####################################################################################
+[_a.model]
+class = Section
+params2.type = String
+params2.required = true
+params2.description = "a required parameter"
+paramInt.ref = MyNumber
+paramInt.description = "an optional parameter (default)"
+_number.type = Integer
+_number.deprecated = true
+_number.mappedTo = "a.paramInt"
+
+[_a.b.c.model]
+class = Section
+description = Just a test section
+
+[_a.b.c.aRequiredSection.model]
+class = Section
+required = true
+description = A section containing required parameters is called a required section.\
+         Sections can also explicitly be defined to be required, but without\
+         specifying the paramteres to be contained.,
+
+[_a.b.c.aRequiredSection.subsection.model]
+class = Section
+param0.type = String
+param0.description = "a minmally documented String parameter"
+# A minmal String parameter
+param00.type = String
+# description is optional
+param1.type = String
+param1.required = true
+intParam.type = Integer
+intParam.description = "an optional parameter (default)"
+
+[_a.b.c.aRequiredSection.nonempty-subsection.model]
+class = Section
+required = true
+
+[_a.b.c.aRequiredSection.optional-subsection.model]
+class = Section
+
+[_a.b.c.aValidatedSection.model]
+class = Section
+description = "A configModel section."
+configModels = org.apache.tamaya.model.TestValidator?max=3
+
+
+
+
diff --git a/documentation/src/test/resources/examples/configmodel.json b/documentation/src/test/resources/examples/configmodel.json
new file mode 100644
index 0000000..c6e5076
--- /dev/null
+++ b/documentation/src/test/resources/examples/configmodel.json
@@ -0,0 +1,108 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy current the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+//##################################################################################
+// Example createObject a configuration metamodel expressed via YAML(tm).
+//  Structure is shown through indentation (one or more spaces).
+//  Sequence items are denoted by a dash,
+//  key createValue pairs within a map are separated by a colon.
+//##################################################################################
+
+//##################################################################################
+// Metamodel information
+//##################################################################################
+{
+  "_model": {
+    "provider": "ConfigModel Extension",
+    // reusable parameter definition
+  },
+  "_MyNumber.model": {
+      "class": "Parameter",
+      "type": "Integer",
+      "template": true,
+      "description": "an (reusable) number type parameter (optional)"
+    },
+    //##################################################################################
+    // Description createObject Configuration Sections (minimal, can be extended by other modules).
+    //##################################################################################
+    "_a.model": {
+      "class": "Section",
+      // required, default is parameter!
+    },
+    "_a.params2.model": {
+        "required": true,
+        "description": "a required parameter"
+    },
+    "_a.paramInt.model": {
+        // references a shared parameter definition.
+        "ref": "MyNumber",
+        "description": "an optional parameter (default)"
+    },
+    "_a.number.model": {
+        "type": "Integer",
+        "deprecated": true,
+        // references a deprecated parameter, now mapped to 'a.paramInt'.
+        "mappedto": "a.paramInt"
+    },
+    "_a.b.c.model": {
+      "class": "Section",
+      "description": "Just a test section."
+      // a subsection, directly configured as child element.
+    },
+    "_a.b.c.aRequiredSection.model": {
+        "class": "Section",
+        "required": true,
+        "description": "A section containing required parameters is called a required section."
+    },
+    // a subsection, configured in its own section.
+    "_a.b.c.aRequiredSection.subsection.model": {
+      "class": "Section"
+    }
+    "_a.b.c.param0-model": {
+        "type": "String",
+        "description": "a minimally documented String parameter"
+    },
+      // A minimally defined String parameter
+    "_a.b.c.param00": {},
+    "_a.b.c.param1": {
+        "type": "String",
+        "required": true,
+        "description": "a required parameter"
+      },
+     "_a.b.c.intParam": {
+        "type": "Integer",
+        "required": true,
+        "description": "an optional parameter (default)"
+    },
+    "_a.b.c.aRequiredSection.nonempty-subsection.model": {
+      "class": "Section",
+      "required": true
+    },
+    "_a.b.c.aRequiredSection.optional-subsection.model": {
+      "class": "Section"
+    },
+    "_a.b.c.aRequiredSection.aValidatedSection.model": {
+      "class": "Section",
+      "description": "A validated section.",
+      "validations": "org.apache.tamaya.model.validation.MaxItemValidator?max=3"
+    }
+  }
+}
+
+
diff --git a/documentation/src/test/resources/examples/configmodel.properties b/documentation/src/test/resources/examples/configmodel.properties
new file mode 100644
index 0000000..a15798e
--- /dev/null
+++ b/documentation/src/test/resources/examples/configmodel.properties
@@ -0,0 +1,96 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+###################################################################################
+# Example createObject a configuration metamodel expressed via properties.
+####################################################################################
+
+# Metamodel information
+_model.provider=ConfigModel Extension
+
+# reusable parameter definition, referenceable as MyNumber
+_MyNumber.model.class=Parameter
+_MyNumber.model.type=Integer
+_MyNumber.model.description=a (reusable) number type parameter (optional)
+
+####################################################################################
+# Description createObject Configuration Sections (minimal, can be extended by other modules).
+# By default its interpreted as a section !
+####################################################################################
+
+# a (section)
+_a.model.class=Section
+_a.params2.model.class=Parameter
+_a.params2.model.type=String
+_a.params2.model.required=true
+_a.params2.model.description=a required parameter
+
+_a.paramInt.model.class=Parameter
+_a.paramInt.model.type=ref:MyNumber
+_a.paramInt.model.description=an optional parameter (default)
+
+_a._number.model.class=Parameter
+_a._number.model.type=Integer
+_a._number.model.deprecated=true
+_a._number.model.mappedTo=a.paramInt
+
+# a.b.c (section)
+_a.b.c.class=Section
+_a.b.c.description=Just a test section
+
+# a.b.c.aRequiredSection (section)
+_a.b.c.aRequiredSection.model.class=Section
+_a.b.c.aRequiredSection.model.required=true
+_a.b.c.aRequiredSection.model.description=A section containing required parameters is called a required section.\
+         Sections can also explicitly be defined to be required, but without\
+         specifying the paramteres to be contained.,
+
+# a.b.c.aRequiredSection.subsection (section)
+_a.b.c.aRequiredSection.model.subsection.class=Section
+
+_a.b.c.aRequiredSection.subsection.param0.model.class=Parameter
+_a.b.c.aRequiredSection.subsection.param0.model.type=String
+_a.b.c.aRequiredSection.subsection.param0.model.description=a minmally documented String parameter
+# A minmal String parameter
+_a.b.c.aRequiredSection.subsection.param00.model.class=Parameter
+_a.b.c.aRequiredSection.subsection.param00.model.type=String
+
+# a.b.c.aRequiredSection.subsection (section)
+_a.b.c.aRequiredSection.subsection.param1.model.class=Parameter
+_a.b.c.aRequiredSection.subsection.param1.model.type = String
+_a.b.c.aRequiredSection.subsection.param1.model.required = true
+_a.b.c.aRequiredSection.subsection.intParam.model.class=Parameter
+_a.b.c.aRequiredSection.subsection.intParam.model.type = Integer
+_a.b.c.aRequiredSection.subsection.intParam.model.description=an optional parameter (default)
+
+# a.b.c.aRequiredSection.nonempty-subsection (section)
+_a.b.c.aRequiredSection.nonempty-subsection.model.class=Section
+_a.b.c.aRequiredSection.nonempty-subsection.model.required=true
+
+# a.b.c.aRequiredSection.optional-subsection (section)
+_a.b.c.aRequiredSection.optional-subsection.model.class=Section
+
+# a.b.c.aValidatedSection (section)
+_a.b.c.aValidatedSection.model.class=Section
+_a.b.c.aValidatedSection.model.description=A validated section.
+_a.b.c.aValidatedSection.model.configModels=org.apache.tamaya.model.TestValidator
+
+
+
+
diff --git a/documentation/src/test/resources/examples/configmodel.xml b/documentation/src/test/resources/examples/configmodel.xml
new file mode 100644
index 0000000..412f85f
--- /dev/null
+++ b/documentation/src/test/resources/examples/configmodel.xml
@@ -0,0 +1,97 @@
+<!--
+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 createObject 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.
+-->
+
+<!--################################################################################
+# Example createObject a configuration metamodel expressed via YAML(tm).
+#   Structure is shown through indentation (one or more spaces).
+#   Sequence items are denoted by a dash,
+#   key createValue pairs within a map are separated by a colon.
+#################################################################################-->
+
+<!--################################################################################
+# Metamodel information
+#################################################################################-->
+
+<configuration>
+    <section name="{model}" __provider="ConfigModel Extension" version="1.0" __release-date="2001-01-23"
+            author="Anatole Tresch">
+        <!-- model-format>alternate format reader type</model-format -->
+        <__description>Late afternoon is best.
+            Backup contact is Nancy.
+        </__description>
+
+        <!--################################################################################
+        # Description createObject Configuration Sections (minimal, can be extended by other modules).
+        #################################################################################-->
+        <section name="a">
+            <param name="params">
+                <type>String</type>
+                <required>true</required>
+                <description>a required parameter</description>
+            </param>
+            <param name="paramInt">
+                <ref>MyNumber</ref>
+                <required>true</required>
+                <description>an optional parameter (default)</description>
+            </param>
+            <param name="_number">
+                <type>Integer</type>
+                <deprecated>true</deprecated>
+                <mappedto>a.paramInt</mappedto>
+            </param>
+            <section name="b.c">
+                <description>Just a test section.</description>
+                <section name="aRequiredSection">
+                    <description>A section containing required parameters is called a required section.
+                        Sections can also explicitly be defined to be required, but without
+                        specifying the paramteres to be contained.
+                    </description>
+                </section>
+            </section>
+        </section>
+
+        <section name="a.b.c.aRequiredSection.subsection">
+            <param name="param0" type="String">a minmally documented String parameter</param>
+            <!-- # A minmally defined String parameter -->
+            <param name="param00">
+                <type>String</type>
+            </param>
+            <param name="param1">
+                <type>String</type>
+                <required>true</required>
+                <description>a required parameter</description>description>
+            </param>
+            <param name="intParam">
+                <type>Integer</type>
+                <description>an optional parameter (default)</description>
+            </param>
+            <section name="b.c">
+                <description>Just a test section.</description>
+            </section>
+        </section>
+        <section name="a.b.c.aRequiredSection.nonempty-subsection">
+            <required>true</required>
+        </section>
+        <section name="a.b.c.aRequiredSection.optional-subsection"/>
+        <section name="a.b.c.aRequiredSection.aValidatedSection">
+            <configModels>org.apache.tamaya.model.configModel.MaxItemValidator?max=3"</configModels>
+            <description>A configModel section.</description>
+        </section>
+    </section>
+</configuration>
diff --git a/documentation/src/test/resources/examples/configmodel.yaml b/documentation/src/test/resources/examples/configmodel.yaml
new file mode 100644
index 0000000..eae9bec
--- /dev/null
+++ b/documentation/src/test/resources/examples/configmodel.yaml
@@ -0,0 +1,106 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+##################################################################################
+# Example createObject a configuration metamodel expressed via YAML(tm).
+#   Structure is shown through indentation (one or more spaces).
+#   Sequence items are denoted by a dash,
+#   key createValue pairs within a map are separated by a colon.
+####################################################################################
+
+####################################################################################
+# Metamodel information
+####################################################################################
+{model}: {
+  __name           :  'testmodel',
+  __provider       :  'ValidationProviderSpi Extension',
+  __version        :  '1.0',
+  __release-date   :  2001-01-23,
+  __author         :  'Anatole Tresch',
+  # model-format: 'alternate format reader type'
+  __description: >
+    Late afternoon is best.
+    Backup contact is Nancy.
+}
+
+####################################################################################
+# Description createObject Configuration Sections (minimal, can be extended by other modules).
+####################################################################################
+---
+{model}.a.params2: {
+  type          : 'String',
+  required      : true,
+  description   : 'a required parameter',
+  paramInt: 'Integer',                 'an optional parameter (default)',
+}
+---
+{model}.a.paramInt: {
+  type          : 'Integer',
+  description   : 'an optional parameter (default)',
+}
+---
+{model}.a.b.c: {
+  description:  'Just a test section.'
+}
+---
+{model}.a.b.c.aRequiredSection: {
+  required: true,
+  description: |
+             A section containing required parameters is called a required section.
+             Sections can also explicitly be defined to be required, but without
+             specifying the paramteres to be contained.,
+}
+---
+{model}.a.b.c.aRequiredSection.subsection: {
+  param0: {
+    type: 'String',
+    description: 'a minmally documented String parameter}'
+  },                 ,
+  param00:{
+    type: 'String'        # A minmally defined String parameter
+  },
+  param1: {
+    tpye: 'String',
+    required: true,
+    description: 'a required parameter'
+  },
+  intParam: {
+    type: 'Integer',
+    description: 'an optional parameter (default)'
+  }
+}
+...
+
+---
+{model}.a.b.c.aRequiredSection.nonempty-subsection: {
+  required: true
+}
+...
+
+---
+{model}.a.b.c.aRequiredSection.optional-subsection: {}
+...
+
+---
+{model}.a.b.c.aRequiredSection.aValidatedSection: {
+  description: 'A configModel section.',
+  configModels: 'org.apache.tamaya.model.configModel.MaxItemValidator?max=3'
+}
+
+
diff --git a/hjson/pom.xml b/hjson/pom.xml
new file mode 100644
index 0000000..27d6546
--- /dev/null
+++ b/hjson/pom.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy current the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.tamaya.ext</groupId>
+        <artifactId>tamaya-sandbox</artifactId>
+        <version>0.4-incubating-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <artifactId>tamaya-hjson_beta</artifactId>
+    <name>Apache Tamaya Modules - HJSON Support</name>
+    <packaging>jar</packaging>
+
+    <inceptionYear>2018</inceptionYear>
+
+    <description>
+        This modules provides format support
+        for using hjson files with Apache Tamaya.
+    </description>
+
+    <properties>
+        <hjson.version>3.0.0</hjson.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-core</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-formats</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hjson</groupId>
+            <artifactId>hjson</artifactId>
+            <version>${hjson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-formats</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/hjson/src/main/java/org/apache/tamaya/hjson/HJSONDataBuilder.java b/hjson/src/main/java/org/apache/tamaya/hjson/HJSONDataBuilder.java
new file mode 100644
index 0000000..2cf4fa5
--- /dev/null
+++ b/hjson/src/main/java/org/apache/tamaya/hjson/HJSONDataBuilder.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.ListValue;
+import org.apache.tamaya.spi.ObjectValue;
+import org.apache.tamaya.spi.PropertyValue;
+import org.hjson.JsonArray;
+import org.hjson.JsonObject;
+import org.hjson.JsonValue;
+
+import java.util.Objects;
+
+/**
+ * Visitor implementation to read a HJSON asString input source.
+ */
+class HJSONDataBuilder {
+
+    private String resource;
+    private PropertyValue data;
+    private JsonValue root;
+
+    HJSONDataBuilder(String resource, JsonValue root) {
+        this.resource = Objects.requireNonNull(resource);
+        this.root = root;
+    }
+
+    private void addJsonObject(JsonObject jsonObject, ObjectValue dataNode){
+        jsonObject.forEach((m) -> {
+            switch(m.getValue().getType()) {
+                case BOOLEAN:
+                    dataNode.setValue(m.getName(), String.valueOf(m.getValue().asBoolean()));
+                    break;
+                case NUMBER:
+                    dataNode.setValue(m.getName(), String.valueOf(m.getValue().asDouble()));
+                    break;
+                case STRING:
+                    dataNode.setValue(m.getName(),  m.getValue().asString());
+                    break;
+                case NULL:
+                    dataNode.setValue(m.getName(), null);
+                    break;
+                case OBJECT:
+                    ObjectValue oval = dataNode.setObject(m.getName());
+                    addJsonObject((JsonObject)m.getValue(), oval);
+                    break;
+                case ARRAY:
+                    ListValue aval = dataNode.setList(m.getName());
+                    addArray((JsonArray)m.getValue(), aval);
+                    break;
+                default:
+                    throw new ConfigException("Internal failure while processing JSON document.");
+            }
+        });
+    }
+
+    private void addArray(JsonArray array, ListValue dataNode) {
+        array.forEach(val -> {
+            switch(val.getType()) {
+                case NULL:
+                    break;
+                case BOOLEAN:
+                    dataNode.addValue(String.valueOf(val.asBoolean()));
+                    break;
+                case NUMBER:
+                case STRING:
+                    dataNode.addValue(val.toString());
+                    break;
+                case OBJECT:
+                    ObjectValue oval = dataNode.addObject();
+                    addJsonObject((JsonObject)val, oval);
+                    break;
+                case ARRAY:
+                    ListValue aval = dataNode.addList();
+                    addArray((JsonArray)val, aval);
+                    break;
+                default:
+                    throw new ConfigException("Internal failure while processing JSON document.");
+            }
+        });
+    }
+
+    public PropertyValue build() {
+        if (root instanceof JsonObject) {
+            data = PropertyValue.createObject("");
+            addJsonObject((JsonObject)root, (ObjectValue) data);
+        } else if (root instanceof JsonArray) {
+            JsonArray array = (JsonArray)root;
+            data = PropertyValue.createList("");
+            addArray(array, (ListValue)data);
+        } else {
+            throw new ConfigException("Unknown JsonType encountered: " + root.getClass().getName());
+        }
+        data.setMeta("resource", resource);
+        data.setMeta("format", "json");
+        return data;
+    }
+
+}
diff --git a/hjson/src/main/java/org/apache/tamaya/hjson/HJSONFormat.java b/hjson/src/main/java/org/apache/tamaya/hjson/HJSONFormat.java
new file mode 100644
index 0000000..3e7f3ed
--- /dev/null
+++ b/hjson/src/main/java/org/apache/tamaya/hjson/HJSONFormat.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.ConfigurationFormat;
+import org.hjson.JsonValue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Implementation of the {@link ConfigurationFormat}
+ * able to read configuration properties with comments represented in HJSON
+ *
+ * @see <a href="http://www.hjson.org">JSON format specification</a>
+ */
+public class HJSONFormat implements ConfigurationFormat {
+
+    @Override
+    public String getName() {
+        return "hjson";
+    }
+
+    @Override
+    public boolean accepts(URL url) {
+        return Objects.requireNonNull(url).getPath().endsWith(".hjson");
+    }
+
+    @Override
+    public ConfigurationData readConfiguration(String resource, InputStream inputStream)
+    throws IOException{
+        try{
+            JsonValue root = JsonValue.readHjson(new InputStreamReader(inputStream,  Charset.forName("UTF-8")));
+            HJSONDataBuilder dataBuilder = new HJSONDataBuilder(resource, root);
+            return new ConfigurationData(resource, this, dataBuilder.build());
+        } catch(Exception e) {
+            throw new IOException("Failed to read data from " + resource, e);
+        }
+    }
+}
diff --git a/hjson/src/main/java/org/apache/tamaya/hjson/HJSONPropertySource.java b/hjson/src/main/java/org/apache/tamaya/hjson/HJSONPropertySource.java
new file mode 100644
index 0000000..c086e29
--- /dev/null
+++ b/hjson/src/main/java/org/apache/tamaya/hjson/HJSONPropertySource.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.hjson.JsonValue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static java.lang.String.format;
+
+/**
+ * Property source based on a HJSON file.
+ */
+public class HJSONPropertySource implements PropertySource {
+    /** The underlying resource. */
+    private final URL urlResource;
+    /** The values read. */
+    private final Map<String, PropertyValue> values;
+    /** The evaluated ordinal. */
+    private int ordinal;
+
+
+    /**
+     * Constructor, hereby using 0 as the default ordinal.
+     * @param resource the resource modelled as URL, not null.
+     * @throws IOException if reading the resource fails.
+     */
+    public HJSONPropertySource(URL resource)throws IOException {
+        this(resource, 0);
+    }
+
+    /**
+     * Constructor.
+     * @param resource the resource modelled as URL, not null.
+     * @param defaultOrdinal the defaultOrdinal to be used.
+     * @throws IOException if reading the resource fails.
+     */
+    public HJSONPropertySource(URL resource, int defaultOrdinal)throws IOException {
+        urlResource = Objects.requireNonNull(resource);
+        this.ordinal = defaultOrdinal; // may be overriden by read...
+        this.values = readConfig(urlResource);
+        if (this.values.containsKey(TAMAYA_ORDINAL)) {
+            this.ordinal = Double.valueOf(this.values.get(TAMAYA_ORDINAL).getValue()).intValue();
+        }
+    }
+
+
+    public int getOrdinal() {
+        PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
+        if(configuredOrdinal!=null){
+            try{
+                return Integer.parseInt(configuredOrdinal.getValue());
+            } catch(Exception e){
+                Logger.getLogger(getClass().getName()).log(Level.WARNING,
+                        "Configured Ordinal is not an int number: " + configuredOrdinal, e);
+            }
+        }
+        return ordinal;
+    }
+
+    @Override
+    public String getName() {
+        return urlResource.toExternalForm();
+    }
+
+    @Override
+    public PropertyValue get(String key) {
+        return getProperties().get(key);
+    }
+
+    @Override
+    public Map<String, PropertyValue> getProperties() {
+
+        return Collections.unmodifiableMap(values);
+    }
+
+    /**
+     * Reads the configuration.
+     * @param urlResource soure of the configuration.
+     * @return the configuration read from the given resource URL.
+     * @throws ConfigException if resource URL cannot be read.
+     * @throws IOException if reading the urlResource fails.
+     */
+    protected Map<String, PropertyValue> readConfig(URL urlResource) throws IOException{
+        try (InputStream is = urlResource.openStream()) {
+            JsonValue root = JsonValue.readHjson(new InputStreamReader(is, Charset.forName("UTF-8")));
+            HJSONDataBuilder visitor = new HJSONDataBuilder(urlResource.toString(), root);
+            Map<String, String> values = visitor.build().toMap();
+            Map<String, PropertyValue> result = new HashMap<>();
+            for(Map.Entry<String,String> en:values.entrySet()){
+                result.put(en.getKey(), PropertyValue.of(en.getKey(), en.getValue(), getName()));
+            }
+            return result;
+        }catch(IOException ioe){
+            throw ioe;
+        }catch (Exception t) {
+            throw new IOException(format("Failed to read properties from %s", urlResource.toExternalForm()), t);
+        }
+    }
+
+}
diff --git a/hjson/src/main/java/org/apache/tamaya/hjson/PathBasedHJSONPropertySourceProvider.java b/hjson/src/main/java/org/apache/tamaya/hjson/PathBasedHJSONPropertySourceProvider.java
new file mode 100644
index 0000000..f6fa174
--- /dev/null
+++ b/hjson/src/main/java/org/apache/tamaya/hjson/PathBasedHJSONPropertySourceProvider.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.apache.tamaya.resource.AbstractPathPropertySourceProvider;
+import org.apache.tamaya.spi.PropertySource;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Path based default provider for hjson formatted config files.
+ */
+public class PathBasedHJSONPropertySourceProvider extends AbstractPathPropertySourceProvider{
+
+    private static final Logger LOG = Logger.getLogger(PathBasedHJSONPropertySourceProvider.class.getName());
+    private HJSONFormat jsonFormat = new HJSONFormat();
+
+    public PathBasedHJSONPropertySourceProvider(String... paths) {
+        super(paths);
+    }
+
+    @Override
+    protected Collection<PropertySource> getPropertySources(URL url) {
+        if(jsonFormat.accepts(url)){
+            try {
+                return Collections.singletonList(
+                        jsonFormat.readConfiguration(url.toString(), url.openStream()).toPropertySource());
+            } catch (IOException e) {
+                LOG.log(Level.SEVERE, "Failed to read yaml file: " +url, e);
+            }
+        }
+        return Collections.emptyList();
+    }
+
+}
+
+
diff --git a/hjson/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat b/hjson/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
new file mode 100644
index 0000000..e8f9bd4
--- /dev/null
+++ b/hjson/src/main/resources/META-INF/services/org.apache.tamaya.format.ConfigurationFormat
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.tamaya.hjson.HJSONFormat
\ No newline at end of file
diff --git a/hjson/src/test/java/org/apache/tamaya/hjson/CommonHJSONTestCaseCollection.java b/hjson/src/test/java/org/apache/tamaya/hjson/CommonHJSONTestCaseCollection.java
new file mode 100644
index 0000000..8bc7c88
--- /dev/null
+++ b/hjson/src/test/java/org/apache/tamaya/hjson/CommonHJSONTestCaseCollection.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.spisupport.PropertySourceComparator;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.URL;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Class with a collection of common test cases each JSON processing
+ * class must be able to pass.
+ */
+public abstract class CommonHJSONTestCaseCollection {
+
+    abstract PropertySource getPropertiesFrom(URL source) throws Exception;
+
+    @Test
+    public void canReadNonLatinCharacters() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class
+             .getResource("/configs/valid/cyrillic.hjson");
+
+        assertThat(configURL, Matchers.notNullValue());
+
+        PropertySource propertySource = getPropertiesFrom(configURL);
+
+        assertThat(propertySource.get("name"), Matchers.notNullValue());
+        assertThat(propertySource.get("name").getValue(), equalTo("\u041e\u043b\u0438\u0432\u0435\u0440"));
+        assertThat(propertySource.get("\u0444\u0430\u043c\u0438\u043b\u0438\u044f"), Matchers.notNullValue());
+        assertThat(propertySource.get("\u0444\u0430\u043c\u0438\u043b\u0438\u044f").getValue(), Matchers.equalTo("Fischer"));
+    }
+
+    @Test
+    public void canReadUnicodeCharacters() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class
+                .getResource("/configs/valid/kanji.hjson");
+
+        assertThat(configURL, Matchers.notNullValue());
+
+        PropertySource propertySource = getPropertiesFrom(configURL);
+
+        assertThat(propertySource.get("onamae"), Matchers.notNullValue());
+        // 霊屋 = Tamaya
+        assertThat(propertySource.get("onamae").getValue(), equalTo("\u970a\u5c4b"));
+    }
+
+    @Test
+    public void canReadNestedStringOnlyJSONConfigFile2() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class
+                .getResource("/configs/valid/simple-nested-string-only-config-1.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        PropertySource properties = getPropertiesFrom(configURL);
+
+        System.out.println("simple-nested-string-only-config-1.json -> " + properties.getProperties().values());
+
+        assertTrue(properties.getProperties().keySet().size()>=5);
+
+        PropertyValue keyB = properties.get("b");
+        PropertyValue keyDO = properties.get("d.o");
+        PropertyValue keyDP = properties.get("d.p");
+
+        assertThat(keyB, notNullValue());
+        assertThat(keyB.getValue(), equalTo("B"));
+        assertThat(keyDO, notNullValue());
+        assertThat(keyDO.getValue(), equalTo("O"));
+        assertThat(keyDP, Matchers.notNullValue());
+        assertThat(keyDP.getValue(), is("P"));
+    }
+
+    @Test
+    public void canReadNestedStringOnlyJSONConfigFileWithObjectInTheMiddle()
+            throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class
+                .getResource("/configs/valid/simple-nested-string-only-config-2.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        PropertySource properties = getPropertiesFrom(configURL);
+
+        assertTrue(properties.getProperties().keySet().size()>=4);
+
+        PropertyValue keyA = properties.get("a");
+        PropertyValue keyDO = properties.get("b.o");
+        PropertyValue keyDP = properties.get("b.p");
+        PropertyValue keyC = properties.get("c");
+
+        assertThat(keyA, notNullValue());
+        assertThat(keyA.getValue(), is("A"));
+        assertThat(keyC, notNullValue());
+        assertThat(keyC.getValue(), equalTo("C"));
+        assertThat(keyDO, notNullValue());
+        assertThat(keyDO.getValue(), equalTo("O"));
+        assertThat(keyDP, notNullValue());
+        assertThat(keyDP.getValue(), is("P"));
+    }
+
+    @Test
+    public void canHandleIllegalJSONFileWhichContainsAnArray() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class.getResource("/configs/invalid/with-array.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        getPropertiesFrom(configURL).getProperties();
+    }
+
+    @Test(expected = IOException.class)
+    public void canHandleIllegalJSONFileConsistingOfOneOpeningBracket() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class.getResource("/configs/invalid/only-opening-bracket.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        getPropertiesFrom(configURL).getProperties();
+    }
+
+    @Test
+    public void canHandleIllegalJSONFileWhichIsEmpty() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class.getResource("/configs/invalid/empty-file.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        getPropertiesFrom(configURL).getProperties();
+    }
+
+    @Test
+    public void priorityInConfigFileOverwriteExplicitlyGivenPriority() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class.getResource("/configs/valid/with-explicit-priority.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        PropertySource properties = getPropertiesFrom(configURL);
+
+        assertThat(PropertySourceComparator.getOrdinal(properties), is(16784));
+    }
+
+    @Test
+    public void canReadFlatStringOnlyJSONConfigFile() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class.getResource("/configs/valid/simple-flat-string-only-config.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        PropertySource properties = getPropertiesFrom(configURL);
+
+        assertEquals(3, properties.getProperties().size());
+
+        PropertyValue keyA = properties.get("a");
+        PropertyValue keyB = properties.get("b");
+        PropertyValue keyC = properties.get("c");
+
+        assertThat(keyA, notNullValue());
+        assertThat(keyA.getValue(), equalTo("A"));
+        assertThat(keyB, notNullValue());
+        assertThat(keyB.getValue(), is("B"));
+        assertThat(keyC, notNullValue());
+        assertThat(keyC.getValue(), is("C"));
+    }
+
+    @Test
+    public void emptyJSONFileResultsInConfigException() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class.getResource("/configs/invalid/empty-file.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        PropertySource properties = getPropertiesFrom(configURL);
+
+        properties.getProperties();
+    }
+
+    @Test
+    public void canHandleEmptyJSONObject() throws Exception {
+        URL configURL = CommonHJSONTestCaseCollection.class.getResource("/configs/valid/empty-object-config.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        PropertySource properties = getPropertiesFrom(configURL);
+
+        assertTrue(properties.getProperties().keySet().size()>=0);
+    }
+}
diff --git a/hjson/src/test/java/org/apache/tamaya/hjson/HJSONFormatIT.java b/hjson/src/test/java/org/apache/tamaya/hjson/HJSONFormatIT.java
new file mode 100644
index 0000000..976c781
--- /dev/null
+++ b/hjson/src/test/java/org/apache/tamaya/hjson/HJSONFormatIT.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.apache.tamaya.format.ConfigurationFormat;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * Integration tests for {@link HJSONFormat}.
+ */
+public class HJSONFormatIT {
+    @Test
+    public void jsonFormatCanBeFoundViaServiceLoader() throws Exception {
+        List<ConfigurationFormat> formats = ServiceContextManager.getServiceContext()
+                                                          .getServices(ConfigurationFormat.class);
+
+        ConfigurationFormat format = null;
+        for (ConfigurationFormat f : formats) {
+            if (f instanceof HJSONFormat) {
+                format = f;
+                break;
+            }
+        }
+        assertThat(format, notNullValue());
+    }
+}
diff --git a/hjson/src/test/java/org/apache/tamaya/hjson/HJSONFormatTest.java b/hjson/src/test/java/org/apache/tamaya/hjson/HJSONFormatTest.java
new file mode 100644
index 0000000..2713b0f
--- /dev/null
+++ b/hjson/src/test/java/org/apache/tamaya/hjson/HJSONFormatTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.hjson;
+
+
+import org.apache.tamaya.format.ConfigurationData;
+import org.apache.tamaya.format.MappedConfigurationDataPropertySource;
+import org.apache.tamaya.spi.PropertySource;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+public class HJSONFormatTest extends CommonHJSONTestCaseCollection {
+    private final HJSONFormat format = new HJSONFormat();
+
+    @Test(expected = NullPointerException.class)
+    public void acceptsNeedsNonNullParameter() throws Exception {
+        format.accepts(null);
+    }
+
+    @Test
+    public void aNonJSONFileBasedURLIsNotAccepted() throws Exception {
+        URL url = new URL("file:///etc/service/conf.conf");
+
+        assertThat(format.accepts(url), is(false));
+    }
+
+    @Test
+    public void aJSONFileBasedURLIsAccepted() throws Exception {
+        URL url = new URL("file:///etc/service/conf.hjson");
+
+        assertThat(format.accepts(url), is(true));
+    }
+
+    @Test
+    public void aHTTPBasedURLIsNotAccepted() throws Exception {
+        URL url = new URL("http://nowhere.somewhere/conf.hjson");
+        assertThat(format.accepts(url), is(true));
+    }
+
+    @Test
+    public void aFTPBasedURLIsNotAccepted() throws Exception {
+        URL url = new URL("ftp://nowhere.somewhere/a/b/c/d/conf.hjson");
+
+        assertThat(format.accepts(url), is(true));
+    }
+
+    @Override
+    PropertySource getPropertiesFrom(URL source) throws Exception {
+        try (InputStream is = source.openStream()) {
+            ConfigurationData data = format.readConfiguration(source.toString(), is);
+            return new MappedConfigurationDataPropertySource(data);
+        }
+    }
+}
\ No newline at end of file
diff --git a/hjson/src/test/java/org/apache/tamaya/hjson/HJSONPropertySourceTest.java b/hjson/src/test/java/org/apache/tamaya/hjson/HJSONPropertySourceTest.java
new file mode 100644
index 0000000..25c9f6d
--- /dev/null
+++ b/hjson/src/test/java/org/apache/tamaya/hjson/HJSONPropertySourceTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+
+import java.net.URL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+public class HJSONPropertySourceTest extends CommonHJSONTestCaseCollection {
+
+    @Test
+    public void tamayaOrdinalKeywordIsNotPropagatedAsNormalProperty() throws Exception {
+        URL configURL = HJSONPropertySourceTest.class.getResource("/configs/valid/with-explicit-priority.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        HJSONPropertySource source = new HJSONPropertySource(configURL, 4);
+        assertEquals(source.getOrdinal(), 16784);
+    }
+    
+    @Test
+    public void testAcceptJsonArrays() throws Exception {
+        URL configURL = HJSONPropertySourceTest.class.getResource("/configs/invalid/array.hjson");
+
+        assertThat(configURL, CoreMatchers.notNullValue());
+
+        new HJSONPropertySource(configURL);
+    }
+
+    @Override
+    PropertySource getPropertiesFrom(URL source) throws Exception {
+        return new HJSONPropertySource(source);
+    }
+}
diff --git a/hjson/src/test/java/org/apache/tamaya/hjson/HJSONVisitorTest.java b/hjson/src/test/java/org/apache/tamaya/hjson/HJSONVisitorTest.java
new file mode 100644
index 0000000..a662dc8
--- /dev/null
+++ b/hjson/src/test/java/org/apache/tamaya/hjson/HJSONVisitorTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.apache.tamaya.spi.ObjectValue;
+import org.apache.tamaya.spi.PropertyValue;
+import org.hjson.JsonArray;
+import org.hjson.JsonObject;
+import org.hjson.JsonValue;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class HJSONVisitorTest {
+
+	@Test
+	public void ensureJSONisParsedProperlyWithDifferentValueTypesFilteringOutEmptyValues() {
+		JsonObject startNode = new JsonObject().//
+				add("key.sub", "createValue").//
+				add("anotherKey", true).//
+				add("notAnotherKey", false).//
+				add("number", 4711).//
+				add("null", JsonValue.NULL).//
+				add("empty", "");
+		HJSONDataBuilder visitor = new HJSONDataBuilder("Test:ensureJSONisParsedProperlyWithDifferentValueTypesFilteringOutEmptyValues", startNode);
+
+		PropertyValue data = visitor.build();
+		assertThat(data).isNotNull();
+
+		ObjectValue ov = data.toObjectValue();
+		assertThat(ov.getValues().size()).isEqualTo(6);
+		assertThat(data.toMap()).containsKeys("key.sub", "anotherKey", "notAnotherKey", "number", "null");
+		assertThat(data.toMap()).containsEntry("key.sub", "createValue");
+		assertThat(data.toMap()).containsEntry("null", null);
+		assertThat(data.toMap()).containsEntry("anotherKey", "true");
+		assertThat(data.toMap()).doesNotContainEntry("empty", null);
+	}
+
+	@Test
+	public void parsingWorksOnEmptyObject() {
+		JsonObject startNode = new JsonObject();
+
+		Map<String, String> targetStore = new HashMap<>();
+
+		HJSONDataBuilder visitor = new HJSONDataBuilder("Test:parsingWorksOnEmptyObject", startNode);
+		PropertyValue data = visitor.build();
+		assertThat(data).isNotNull();
+		assertThat(data.isLeaf());
+	}
+
+	@Test
+	public void arrayInObject() {
+		JsonObject startNode = new JsonObject().
+				add("arrayKey", new JsonArray());
+		HJSONDataBuilder visitor = new HJSONDataBuilder("Test:array", startNode);
+		PropertyValue data = visitor.build();
+		assertThat(data).isNotNull();
+		System.out.println(data.asString());
+	}
+
+	@Test
+	public void array() {
+		JsonArray startNode = new JsonArray().
+				add(new JsonObject().add("k1", 1).add("k2", 2)).
+				add(new JsonObject().add("k1", 1).add("k2", 2)).
+				add(new JsonArray().add(new JsonObject().add("k31", "v31").add("k32", false)));
+		HJSONDataBuilder visitor = new HJSONDataBuilder("Test:array", startNode);
+		PropertyValue data = visitor.build();
+		assertThat(data).isNotNull();
+		System.out.println(data.asString());
+	}
+
+}
diff --git a/hjson/src/test/java/org/apache/tamaya/hjson/PathBasedHJSONPropertySourceProviderTest.java b/hjson/src/test/java/org/apache/tamaya/hjson/PathBasedHJSONPropertySourceProviderTest.java
new file mode 100644
index 0000000..ab9c5d2
--- /dev/null
+++ b/hjson/src/test/java/org/apache/tamaya/hjson/PathBasedHJSONPropertySourceProviderTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.hjson;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Tests for {@link PathBasedHJSONPropertySourceProvider}.
+ */
+public class PathBasedHJSONPropertySourceProviderTest {
+
+    @Test
+    public void getPropertySources() {
+        PathBasedHJSONPropertySourceProvider provider = new PathBasedHJSONPropertySourceProvider(
+                "configs/valid/*.hjson"
+        );
+        assertNotNull(provider.getPropertySources());
+        assertEquals(7, provider.getPropertySources().size());
+    }
+
+    @Test
+    public void getPropertySources_one() {
+        PathBasedHJSONPropertySourceProvider provider = new PathBasedHJSONPropertySourceProvider(
+                "configs/valid/cyril*.hjson"
+        );
+        assertNotNull(provider.getPropertySources());
+        assertEquals(1, provider.getPropertySources().size());
+    }
+
+    @Test
+    public void getPropertySources_two() {
+        PathBasedHJSONPropertySourceProvider provider = new PathBasedHJSONPropertySourceProvider(
+                "configs/valid/simple-*.hjson"
+        );
+        assertNotNull(provider.getPropertySources());
+        assertEquals(3, provider.getPropertySources().size());
+    }
+
+    @Test
+    public void getPropertySources_none() {
+        PathBasedHJSONPropertySourceProvider provider = new PathBasedHJSONPropertySourceProvider(
+                "configs/valid/foo*.hjson", "configs/valid/*.HJSON"
+        );
+        assertNotNull(provider.getPropertySources());
+        assertEquals(0, provider.getPropertySources().size());
+    }
+}
\ No newline at end of file
diff --git a/hjson/src/test/resources/META-INF/javaconfiguration.properties b/hjson/src/test/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..e66e448
--- /dev/null
+++ b/hjson/src/test/resources/META-INF/javaconfiguration.properties
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# The space before the actual date is intended!
+dateTimeValue= 2010-08-08T14:00:15.5+10:00
+dateTimeZoneValueA=UTC
+dateTimeZoneValueB=+01:00
+periodValueA=P1Y1M1W1DT1H1M1S
diff --git a/hjson/src/test/resources/configs/invalid/array.hjson b/hjson/src/test/resources/configs/invalid/array.hjson
new file mode 100644
index 0000000..0c2058a
--- /dev/null
+++ b/hjson/src/test/resources/configs/invalid/array.hjson
@@ -0,0 +1,21 @@
+/*
+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.
+*/
+[
+
+]
\ No newline at end of file
diff --git a/hjson/src/test/resources/configs/invalid/empty-file.hjson b/hjson/src/test/resources/configs/invalid/empty-file.hjson
new file mode 100644
index 0000000..f396085
--- /dev/null
+++ b/hjson/src/test/resources/configs/invalid/empty-file.hjson
@@ -0,0 +1,18 @@
+/*
+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.
+*/
\ No newline at end of file
diff --git a/hjson/src/test/resources/configs/invalid/only-opening-bracket.hjson b/hjson/src/test/resources/configs/invalid/only-opening-bracket.hjson
new file mode 100644
index 0000000..b936f69
--- /dev/null
+++ b/hjson/src/test/resources/configs/invalid/only-opening-bracket.hjson
@@ -0,0 +1,19 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy 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.
+*/
+{
\ No newline at end of file
diff --git a/hjson/src/test/resources/configs/invalid/with-array.hjson b/hjson/src/test/resources/configs/invalid/with-array.hjson
new file mode 100644
index 0000000..e623e49
--- /dev/null
+++ b/hjson/src/test/resources/configs/invalid/with-array.hjson
@@ -0,0 +1,27 @@
+/*
+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.
+*/
+{
+  "a" : "A",
+  "b" : {
+    "c" : "C",
+    "d" : [
+      "1", "2"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/hjson/src/test/resources/configs/valid/cyrillic.hjson b/hjson/src/test/resources/configs/valid/cyrillic.hjson
new file mode 100644
index 0000000..da86e77
--- /dev/null
+++ b/hjson/src/test/resources/configs/valid/cyrillic.hjson
@@ -0,0 +1,22 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+{
+  name : "Оливер",
+  фамилия : "Fischer"
+}
\ No newline at end of file
diff --git a/hjson/src/test/resources/configs/valid/empty-object-config.hjson b/hjson/src/test/resources/configs/valid/empty-object-config.hjson
new file mode 100644
index 0000000..103c28d
--- /dev/null
+++ b/hjson/src/test/resources/configs/valid/empty-object-config.hjson
@@ -0,0 +1,20 @@
+/*
+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.
+*/
+{
+}
\ No newline at end of file
diff --git a/hjson/src/test/resources/configs/valid/kanji.hjson b/hjson/src/test/resources/configs/valid/kanji.hjson
new file mode 100644
index 0000000..1d1c54a
--- /dev/null
+++ b/hjson/src/test/resources/configs/valid/kanji.hjson
@@ -0,0 +1,21 @@
+/*
+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.
+*/
+{
+  onamae : 霊屋
+}
\ No newline at end of file
diff --git a/hjson/src/test/resources/configs/valid/simple-flat-string-only-config.hjson b/hjson/src/test/resources/configs/valid/simple-flat-string-only-config.hjson
new file mode 100644
index 0000000..d961b62
--- /dev/null
+++ b/hjson/src/test/resources/configs/valid/simple-flat-string-only-config.hjson
@@ -0,0 +1,23 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy 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.
+*/
+{
+  a : A
+  b : B
+  c : C
+}
\ No newline at end of file
diff --git a/hjson/src/test/resources/configs/valid/simple-nested-string-only-config-1.hjson b/hjson/src/test/resources/configs/valid/simple-nested-string-only-config-1.hjson
new file mode 100644
index 0000000..622cf29
--- /dev/null
+++ b/hjson/src/test/resources/configs/valid/simple-nested-string-only-config-1.hjson
@@ -0,0 +1,27 @@
+/*
+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.
+*/
+{
+  a: A
+  b: B
+  c: C
+  d: {
+    o: O
+    p: P
+  }
+}
diff --git a/hjson/src/test/resources/configs/valid/simple-nested-string-only-config-2.hjson b/hjson/src/test/resources/configs/valid/simple-nested-string-only-config-2.hjson
new file mode 100644
index 0000000..a43aee6
--- /dev/null
+++ b/hjson/src/test/resources/configs/valid/simple-nested-string-only-config-2.hjson
@@ -0,0 +1,26 @@
+/*
+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.
+*/
+{
+  a : A
+  b : {
+    o : O
+    p : P
+  }
+  c : C
+}
diff --git a/hjson/src/test/resources/configs/valid/with-explicit-priority.hjson b/hjson/src/test/resources/configs/valid/with-explicit-priority.hjson
new file mode 100644
index 0000000..aa0d8e1
--- /dev/null
+++ b/hjson/src/test/resources/configs/valid/with-explicit-priority.hjson
@@ -0,0 +1,25 @@
+/*
+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.
+*/
+{
+  /*
+   some useful comment here
+   */
+  tamaya.ordinal : 16784
+  a : A // another comment
+}
diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java
index ae915a4..1f16afa 100644
--- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/ComponentConfigurator.java
@@ -37,9 +37,9 @@
     private ComponentConfigurator(){}
 
     /**
-     * Configures the given instance with whatever is defined in the current child getList.
+     * Configures the given instance with whatever is defined in the current child values.
      * @param instance the instance to be configured, not null.
-     * @param node the getField containing any configuration child getList, not null.
+     * @param node the value containing any configuration child values, not null.
      */
     public static void configure(Object instance, Node node) {
         Map<String,String> params = extractParameters(node);
@@ -47,9 +47,9 @@
     }
 
     /**
-     * Configures the given instance with whatever is defined in the current child getList.
+     * Configures the given instance with whatever is defined in the current child values.
      * @param instance the instance to be configured, not null.
-     * @param params the getField containing any configuration child getList, not null.
+     * @param params the value containing any configuration child values, not null.
      */
     public static void configure(Object instance, Map<String,String> params) {
         LOG.finest("Configuring instance: " + instance + " with " + params);
diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java
index 0c42f8c..f3be30a 100644
--- a/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/internal/PropertySourceReader.java
@@ -109,7 +109,7 @@
     /**
      * Decorates a property source to be refreshable or filtered.
      * @param ps the wrapped property source
-     *@param configNode the XML config getField
+     *@param configNode the XML config value
      * @param params the extracted parameter createList   @return the property source to be added to the context.
      */
     private PropertySource decoratePropertySource(PropertySource ps, Node configNode, Map<String, String> params){
@@ -161,7 +161,7 @@
     /**
      * Decorates a property source provider to be refreshable or filtered.
      * @param prov the property source provider to be wrapped.
-     * @param configNode the XML config getField
+     * @param configNode the XML config value
      * @param params the extracted parameter createList   @return the property source provider to be added to the context.
      */
     private PropertySourceProvider decoratePropertySourceProvider(PropertySourceProvider prov, Node configNode, Map<String, String> params){
diff --git a/pom.xml b/pom.xml
index 37b2b58..7967c3c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,7 +55,7 @@
         <json.spec.version>1.0</json.spec.version>
         <johnzon.version>1.1.8</johnzon.version>
         <junit.version>4.12</junit.version>
-        <assertj.version>3.8.0</assertj.version>
+        <assertj.version>3.10.0</assertj.version>
         <surefire.version>2.21.0</surefire.version>
 
         <!-- Java EE modules for compiling on JDK9+ -->
@@ -819,6 +819,8 @@
         <module>uom</module>
         <module>vertx</module>
         <module>configjsr</module>
+        <module>documentation</module>
+        <module>hjson</module>
         <!-- Once the API is officially available ... -->
         <!--   module>configjsr</module-->
     </modules>
diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java
index 43e88f6..dea25c7 100644
--- a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java
+++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java
@@ -117,7 +117,7 @@
 
     /**
      * Access access details for a given class.
-     * @param type class to getField usage access stats for, not null.
+     * @param type class to value usage access stats for, not null.
      * @return the usage ref, if present, or null.
      */
     public Collection<AccessStats> getAccessDetails(Class type){
@@ -126,7 +126,7 @@
 
     /**
      * Access access details for a given package.
-     * @param pack package to getField usage access stats for, not null.
+     * @param pack package to determine usage access stats for, not null.
      * @return the usage ref, if present, or null.
      */
     public Collection<AccessStats> getAccessDetails(Package pack){
diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java
index f3811d5..181daf4 100644
--- a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java
+++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java
@@ -25,7 +25,6 @@
 import org.apache.tamaya.usagetracker.spi.ConfigUsageSpi;
 
 import javax.annotation.Priority;
-import java.util.logging.Filter;
 
 /**
  * Configuration filter to be applied at the end of the filter chain. This filter
@@ -39,9 +38,9 @@
     public PropertyValue filterProperty(PropertyValue value, FilterContext context) {
         ConfigUsageSpi tracker = ServiceContextManager.getServiceContext().getService(ConfigUsageSpi.class);
         if (context.isSinglePropertyScoped()) {
-            tracker.recordSingleKeyAccess(value, context.current());
+            tracker.recordSingleKeyAccess(value, context.getConfigurationContext());
         } else {
-            tracker.recordAllPropertiesAccess(context.current());
+            tracker.recordAllPropertiesAccess(context.getConfigurationContext());
         }
         return value;
     }
diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java
index cdaad4f..a74a14f 100644
--- a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java
+++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java
@@ -84,7 +84,7 @@
     void recordAllPropertiesAccess(ConfigurationContext context);
 
     /**
-     * Track the access of {@code Configuration#getField(String)} for
+     * Track the access of {@code Configuration#getProperty(String)} for
      * usage statistics.
      * @param context the corresponding context.
      * @param value createValue to track for
diff --git a/validation/pom.xml b/validation/pom.xml
index c3ef7cf..e97dd66 100644
--- a/validation/pom.xml
+++ b/validation/pom.xml
@@ -51,28 +51,13 @@
         </dependency>
         <dependency>
             <groupId>org.apache.tamaya.ext</groupId>
-            <artifactId>tamaya-events</artifactId>
+            <artifactId>tamaya-functions</artifactId>
             <version>${project.parent.version}</version>
-            <scope>provided</scope>
-            <optional>true</optional>
         </dependency>
         <dependency>
             <groupId>org.apache.tamaya.ext</groupId>
-            <artifactId>tamaya-json</artifactId>
+            <artifactId>tamaya-doc_alpha</artifactId>
             <version>${project.parent.version}</version>
-            <scope>provided</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.johnzon</groupId>
-            <artifactId>johnzon-core</artifactId>
-            <version>${johnzon.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-json_1.0_spec</artifactId>
-            <version>1.0-alpha-1</version>
-            <scope>compile</scope>
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
diff --git a/validation/src/main/java/org/apache/tamaya/validation/ConfigModel.java b/validation/src/main/java/org/apache/tamaya/validation/ConfigModel.java
deleted file mode 100644
index 259ff99..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/ConfigModel.java
+++ /dev/null
@@ -1,78 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation;
-
-import org.apache.tamaya.Configuration;
-
-import java.util.Collection;
-
-/**
- * Base structure describing a validated item, by default a parameter or a section.
- */
-public interface ConfigModel {
-
-    /**
-     * Access the owner.
-     * @return the owner createObject this model, never null.
-     */
-    String getOwner();
-
-    /**
-     * Get the type createObject item that is modelled.
-     * @return the modelled type, never null.
-     */
-    ModelTarget getType();
-
-    /**
-     * Get the item's name, it should minimally describe the validation. Examples are:
-     * <pre>
-     *     Sections: a.b.c
-     *     Params: a.b.c.paramName
-     *     Filter: a.b.c.FilterImplClass
-     *     Dependency: mydepClassname
-     *     CombinationPolicy: a.b.c.MyCombinationPolicyClass
-     * </pre>
-     * @return the item's name.
-     */
-    String getName();
-
-    /**
-     * Check if this validation is a required one.
-     * @return true, if this validation is required.
-     */
-    boolean isRequired();
-
-    /**
-     * Get an description createObject the item, using the default locale. The description is basically optional
-     * though it is higly recommended to provide a description, so the validation issues is well
-     * resolvable.
-     *
-     * @return the description required, or null.
-     */
-    String getDescription();
-
-    /**
-     * Validates the item and all its getList against the given configuration.
-     *
-     * @param config the configuration to be validated against, not null.
-     * @return the validation result, or null, if not applicable.
-     */
-    Collection<Validation> validate(Configuration config);
-
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/ConfigModelManager.java b/validation/src/main/java/org/apache/tamaya/validation/ConfigModelManager.java
deleted file mode 100644
index ed6a545..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/ConfigModelManager.java
+++ /dev/null
@@ -1,285 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.validation.spi.ConfigDocumentationMBean;
-import org.apache.tamaya.validation.spi.ModelProviderSpi;
-import org.apache.tamaya.spi.ServiceContextManager;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Validator accessor to validate the current configuration.
- */
-public final class ConfigModelManager {
-
-    /** The logger used. */
-    private static final Logger LOG = Logger.getLogger(ConfigModelManager.class.getName());
-
-    /**
-     * Singleton constructor.
-     */
-    private ConfigModelManager() {
-    }
-
-    /**
-     * Access the usage statistics for the recorded uses createObject configuration.
-     * @param inModels the target models, not null.
-     * @return usage statistics
-     */
-    public static String getConfigModelDescription(Collection<ConfigModel> inModels){
-        StringBuilder b = new StringBuilder();
-        List<ConfigModel> models = new ArrayList<>(inModels);
-        Collections.sort(models, (k1, k2) -> {
-                return k2.getName().compareTo(k2.getName());
-            });
-        b.append("TYPE    OWNER      NAME                                              MANDATORY   DESCRIPTION\n");
-        b.append("-----------------------------------------------------------------------------------------------------\n");
-        for(ConfigModel model:models){
-            switch(model.getType()){
-                case Parameter:
-                    b.append("PARAM   ");
-                    break;
-                case Section:
-                    b.append("SECTION ");
-                    break;
-                case Group:
-                    b.append("GROUP   ");
-                    break;
-                default:
-                    break;
-            }
-            b.append(formatWithFixedLength(model.getOwner(), 10)).append(' ');
-            b.append(formatWithFixedLength(model.getName(), 50));
-            if(model.isRequired()){
-                b.append(formatWithFixedLength("yes", 12));
-            }else{
-                b.append(formatWithFixedLength("no", 12));
-            }
-            if(model.getDescription()!=null){
-                b.append(model.getDescription().replace("\n", "\\\n").replace("\"", "'")).append("\"");
-            }
-            b.append("\n");
-        }
-        return b.toString();
-    }
-
-    /**
-     * Get the validations defined, using the default classloader.
-     *
-     * @return the sections defined, never null.
-     * @see ServiceContextManager#getDefaultClassLoader()
-     */
-    public static Collection<ConfigModel> getModels() {
-        return getModels(ServiceContextManager.getDefaultClassLoader());
-    }
-
-    /**
-     * Get the validations defined.
-     *
-     * @param classLoader the target classloader, not null.
-     * @return the sections defined, never null.
-     */
-    public static Collection<ConfigModel> getModels(ClassLoader classLoader) {
-        List<ConfigModel> result = new ArrayList<>();
-        for (ModelProviderSpi model : ServiceContextManager.getServiceContext(classLoader).getServices(ModelProviderSpi.class)) {
-            result.addAll(model.getConfigModels());
-        }
-        return result;
-    }
-
-
-    /**
-     * Find the validations by checking the validation's name using the given regular expression and
-     * the default classloader.
-     *
-     * @param namePattern the regular expression to use, not null.
-     * @param targets the target types only to be returned (optional).
-     * @return the sections defined, never null.
-     * @see ServiceContextManager#getDefaultClassLoader()
-     */
-    public static Collection<ConfigModel> findModels(String namePattern, ModelTarget... targets) {
-        return findModels(namePattern, ServiceContextManager.getDefaultClassLoader(), targets);
-    }
-
-    /**
-     * Find the validations by checking the validation's name using the given regular expression.
-     *
-     * @param classLoader the target classloader, not null.
-     * @param namePattern the regular expression to use, not null.
-     * @param targets the target types only to be returned (optional).
-     * @return the sections defined, never null.
-     */
-    public static Collection<ConfigModel> findModels(String namePattern, ClassLoader classLoader, ModelTarget... targets) {
-        List<ConfigModel> result = new ArrayList<>();
-        for (ModelProviderSpi model : ServiceContextManager.getServiceContext(classLoader).getServices(ModelProviderSpi.class)) {
-            for(ConfigModel configModel : model.getConfigModels()) {
-                if(configModel.getName().matches(namePattern)) {
-                    if(targets.length>0){
-                        for(ModelTarget tgt:targets){
-                            if(configModel.getType().equals(tgt)){
-                                result.add(configModel);
-                                break;
-                            }
-                        }
-                    }else {
-                        result.add(configModel);
-                    }
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Validates the given configuration.
-     *
-     * @param config the configuration to be validated against, not null.
-     * @return the validation results, never null.
-     */
-    public static Collection<Validation> validate(Configuration config) {
-        return validate(config, false);
-    }
-
-    /**
-     * Validates the given configuration.
-     *
-     * @param config the configuration to be validated against, not null.
-     * @param showUndefined allows filtering for undefined configuration elements.
-     * @return the validation results, never null.
-     */
-    public static Collection<Validation> validate(Configuration config, boolean showUndefined) {
-        List<Validation> result = new ArrayList<>();
-        for (ConfigModel defConf : getModels(config.getContext().getServiceContext().getClassLoader())) {
-            result.addAll(defConf.validate(config));
-        }
-        if(showUndefined){
-            Map<String,String> map = new HashMap<>(config.getProperties());
-            Set<String> areas = extractTransitiveAreas(map.keySet());
-            for (ConfigModel defConf : getModels()) {
-                if(ModelTarget.Section.equals(defConf.getType())){
-                    for (Iterator<String> iter = areas.iterator();iter.hasNext();){
-                        String area = iter.next();
-                        if(area.matches(defConf.getName())){
-                            iter.remove();
-                        }
-                    }
-                }
-                if(ModelTarget.Parameter.equals(defConf.getType())){
-                    map.remove(defConf.getName());
-                }
-            }
-            outer:for(Map.Entry<String,String> entry:map.entrySet()){
-                for (ConfigModel defConf : getModels()) {
-                    if(ModelTarget.Section.equals(defConf.getType())){
-                        if(defConf.getName().endsWith(".*") && entry.getKey().matches(defConf.getName())){
-                            // Ignore parameters that are part createObject transitive section.
-                            continue outer;
-                        }
-                    }
-                }
-                result.add(Validation.createUndefined("<auto>", entry.getKey(), ModelTarget.Parameter));
-            }
-            for(String area:areas){
-                result.add(Validation.createUndefined("<auto>", area, ModelTarget.Section));
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Registers the {@link ConfigDocumentationMBean} mbean for accessing config documentation into the local platform
-     * mbean server.
-     */
-    public static void registerMBean() {
-        registerMBean(null);
-    }
-
-    /**
-     * Registers the {@link ConfigDocumentationMBean} mbean for accessing config documentation into the local platform
-     * mbean server.
-     * 
-     * @param context allows to specify an additional MBean context, maybe {@code null}. 
-     */
-    public static void registerMBean(String context) {
-        try{
-            ConfigDocumentationMBean configMbean = ServiceContextManager.getServiceContext()
-                    .getService(ConfigDocumentationMBean.class);
-            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-            ObjectName on = context==null?new ObjectName("org.apache.tamaya.model:type=ConfigDocumentationMBean"):
-                    new ObjectName("org.apache.tamaya.model:type=ConfigDocumentationMBean,context="+context);
-            try{
-                mbs.getMBeanInfo(on);
-                LOG.warning("Cannot register mbean " + on + ": already existing.");
-            } catch(InstanceNotFoundException e) {
-                LOG.info("Registering mbean " + on + "...");
-                mbs.registerMBean(configMbean, on);
-            }
-        } catch(Exception e){
-            LOG.log(Level.WARNING,
-                    "Failed to register ConfigDocumentationMBean.", e);
-        }
-    }
-
-    private static String formatWithFixedLength(String name, int targetLength) {
-        targetLength = targetLength-1;
-        StringBuilder b = new StringBuilder();
-        if(name.length() > targetLength){
-            name = name.substring(0, targetLength);
-        }
-        b.append(name);
-        for(int i=0;i<(targetLength-name.length());i++){
-            b.append(' ');
-        }
-        b.append(' ');
-        return b.toString();
-    }
-
-
-
-    private static java.util.Set<java.lang.String> extractTransitiveAreas(Set<String> keys) {
-        Set<String> transitiveClosure = new HashSet<>();
-        for(String key:keys){
-            int index = key.lastIndexOf('.');
-            while(index>0){
-                String areaKey = key.substring(0,index);
-                transitiveClosure.add(areaKey);
-                index = areaKey.lastIndexOf('.');
-            }
-        }
-        return transitiveClosure;
-    }
-
-
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/ConfigValidation.java b/validation/src/main/java/org/apache/tamaya/validation/ConfigValidation.java
new file mode 100644
index 0000000..b934b52
--- /dev/null
+++ b/validation/src/main/java/org/apache/tamaya/validation/ConfigValidation.java
@@ -0,0 +1,122 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.validation;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationSnapshot;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.validation.spi.ConfigValidator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Validator manager to validate a configuration.
+ */
+public final class ConfigValidation {
+
+    /** The logger used. */
+    private static final Logger LOG = Logger.getLogger(ConfigValidation.class.getName());
+    /** The validators used. */
+    private List<org.apache.tamaya.validation.spi.ConfigValidator> validators = new ArrayList<>();
+
+    /**
+     * Private constructor.
+     */
+    private ConfigValidation(){}
+
+    /**
+     * Access a singleton using the default classloader.
+     */
+    public static ConfigValidation getInstance() {
+        return ServiceContextManager.getServiceContext(
+                ServiceContextManager.getDefaultClassLoader()
+        ).getService(ConfigValidation.class, ConfigValidation::new);
+    }
+
+    /**
+     * Access a singleton using the given target classloader.
+     * @param classLoader the classloader, not null.
+     */
+    public static ConfigValidation getInstance(ClassLoader classLoader){
+        return ServiceContextManager.getServiceContext(classLoader).getService(ConfigValidation.class, ConfigValidation::new);
+    }
+
+    /**
+     * Add a validator.
+     * @param validator the new validator, not null.
+     */
+    public void addValidator(ConfigValidator validator){
+        if(!validators.contains(validator)) {
+            this.validators.add(validator);
+        }
+    }
+
+    /**
+     * Removes a vlidator.
+     * @param validator the validator, not null.
+     */
+    public void removeValidator(ConfigValidator validator){
+        this.validators.remove(validator);
+    }
+
+    /**
+     * Get the validations defined, using the default classloader.
+     *
+     * @return the sections defined, never null.
+     * @see ServiceContextManager#getDefaultClassLoader()
+     */
+    public Collection<org.apache.tamaya.validation.spi.ConfigValidator> getValidators() {
+        return getValidators(ServiceContextManager.getDefaultClassLoader());
+    }
+
+    /**
+     * Get the validations defined.
+     *
+     * @param classLoader the target classloader, not null.
+     * @return the sections defined, never null.
+     */
+    public Collection<org.apache.tamaya.validation.spi.ConfigValidator> getValidators(ClassLoader classLoader) {
+        return validators;
+    }
+
+    /**
+     * Validates the given configuration.
+     *
+     * @param config the configuration to be validated against, not null.
+     * @return the validation results, never null.
+     */
+    public ValidationResult validate(Configuration config) {
+        ConfigurationSnapshot snapshot = config.getSnapshot();
+        List<ValidationCheck> result = new ArrayList<>();
+        for (org.apache.tamaya.validation.spi.ConfigValidator validator : this.validators) {
+            result.addAll(validator.validate(config));
+        }
+        return new ValidationResult(snapshot, result);
+    }
+
+    @Override
+    public String toString() {
+        return "ConfigValidation{" +
+                "validators=" + validators +
+                '}';
+    }
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/Validation.java b/validation/src/main/java/org/apache/tamaya/validation/Validation.java
deleted file mode 100644
index 128efee..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/Validation.java
+++ /dev/null
@@ -1,203 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.validation.spi.AbstractConfigModel;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Objects;
-
-/**
- * Models a partial configuration configModel result.
- */
-public final class Validation {
-    /**
-     * the config section.
-     */
-    private final ConfigModel configModel;
-    /**
-     * The configModel result.
-     */
-    private final ValidationResult result;
-    /**
-     * The configModel message.
-     */
-    private final String message;
-
-    /**
-     * Creates a new ValidationResult.
-     *
-     * @param configModel the configModel item, not null.
-     * @return a new validation result containing valid parts createObject the given model.
-     */
-    public static Validation createValid(ConfigModel configModel) {
-        return new Validation(configModel, ValidationResult.VALID, null);
-    }
-
-    /**
-     * Creates a new ValidationResult.
-     *
-     * @param configModel the configModel item, not null.
-     * @return a new validation result containing missing parts createObject the given model.
-     */
-    public static Validation createMissing(ConfigModel configModel) {
-        return new Validation(configModel, ValidationResult.MISSING, null);
-    }
-
-    /**
-     * Creates a new ValidationResult.
-     *
-     * @param configModel the configModel item, not null.
-     * @param message Additional message to be shown (optional).
-     * @return a new validation result containing missing parts createObject the given model with a message.
-     */
-    public static Validation createMissing(ConfigModel configModel, String message) {
-        return new Validation(configModel, ValidationResult.MISSING, message);
-    }
-
-    /**
-     * Creates a new ValidationResult.
-     *
-     * @param configModel the configModel item, not null.
-     * @param error error message to addNode.
-     * @return a new validation result containing erroneous parts createObject the given model with the given error message.
-     */
-    public static Validation createError(ConfigModel configModel, String error) {
-        return new Validation(configModel, ValidationResult.ERROR, error);
-    }
-
-    /**
-     * Creates a new ValidationResult.
-     *
-     * @param configModel the configModel item, not null.
-     * @param warning warning message to addNode.
-     * @return a new validation result containing warning parts createObject the given model with the given warning message.
-     */
-    public static Validation createWarning(ConfigModel configModel, String warning) {
-        return new Validation(configModel, ValidationResult.WARNING, warning);
-    }
-
-    /**
-     * Creates a new ValidationResult.
-     *
-     * @param configModel the configModel item, not null.
-     * @param alternativeUsage allows setting a message to indicate non-deprecated replacement, maybe null.
-     * @return a new validation result containing deprecated parts createObject the given model with an optional message.
-     */
-    public static Validation createDeprecated(ConfigModel configModel, String alternativeUsage) {
-        return new Validation(configModel, ValidationResult.DEPRECATED, alternativeUsage != null ? "Use instead: " + alternativeUsage : null);
-    }
-
-    /**
-     * Creates a new ValidationResult.
-     *
-     * @param configModel the configModel item, not null.
-     * @return a new validation result containing deprecated parts createObject the given model.
-     */
-    public static Validation createDeprecated(ConfigModel configModel) {
-        return new Validation(configModel, ValidationResult.DEPRECATED, null);
-    }
-
-    /**
-     * Creates a new ValidationResult.
-     *
-     * @param owner owner
-     * @param key the name/model key
-     * @param type model type 
-     * @return a corresponding configModel item
-     */
-    public static Validation createUndefined(final String owner, final String key, final ModelTarget type) {
-        return new Validation(new AbstractConfigModel(owner, key, false, "Undefined key: " + key) {
-
-            @Override
-            public ModelTarget getType() {
-                return type;
-            }
-
-            @Override
-            public Collection<Validation> validate(Configuration config) {
-                return Collections.emptyList();
-            }
-        }, ValidationResult.UNDEFINED, null);
-    }
-
-
-    /**
-     * Constructor.
-     *
-     * @param configModel the configModel item, not null.
-     * @param result     the configModel result, not null.
-     * @param message    the detail message.
-     * @return new validation result.
-     */
-    public static Validation create(ConfigModel configModel, ValidationResult result, String message) {
-        return new Validation(configModel, result, message);
-    }
-
-
-    /**
-     * Constructor.
-     *
-     * @param configModel the configModel item, not null.
-     * @param result     the configModel result, not null.
-     * @param message    the detail message.
-     */
-    private Validation(ConfigModel configModel, ValidationResult result, String message) {
-        this.message = message;
-        this.configModel = Objects.requireNonNull(configModel);
-        this.result = Objects.requireNonNull(result);
-    }
-
-    /**
-     * Get the configModel section.
-     *
-     * @return the section, never null.
-     */
-    public ConfigModel getConfigModel() {
-        return configModel;
-    }
-
-    /**
-     * Get the configModel result.
-     *
-     * @return the result, never null.
-     */
-    public ValidationResult getResult() {
-        return result;
-    }
-
-    /**
-     * Get the detail message.
-     *
-     * @return the detail message, or null.
-     */
-    public String getMessage() {
-        return message;
-    }
-
-    @Override
-    public String toString() {
-        if (message != null) {
-            return result + ": " + configModel.getName() + " (" + configModel.getType() + ") -> " + message + '\n';
-        }
-        return result + ": " + configModel.getName() + " (" + configModel.getType() + ")";
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/ValidationCheck.java b/validation/src/main/java/org/apache/tamaya/validation/ValidationCheck.java
new file mode 100644
index 0000000..d4ad293
--- /dev/null
+++ b/validation/src/main/java/org/apache/tamaya/validation/ValidationCheck.java
@@ -0,0 +1,203 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.validation;
+
+import org.apache.tamaya.doc.annot.ConfigAreaSpec;
+import org.apache.tamaya.doc.annot.ConfigPropertySpec;
+
+import java.util.Objects;
+
+/**
+ * Models a partial configuration validation result.
+ */
+public final class ValidationCheck {
+
+    /**
+     * Enum type describing the different validation results supported.
+     */
+    public enum Finding {
+        /**
+         * The validated item is valid
+         */
+        VALID,
+        /**
+         * The validated item is deprecated.
+         */
+        DEPRECATED,
+        /**
+         * The validated item is correct, but the createValue is worth a warning.
+         */
+        WARNING,
+        /**
+         * A required parameter or section is missing.
+         */
+        MISSING,
+        /**
+         * The validated item has an invalid createValue.
+         */
+        ERROR;
+
+        /**
+         * Method to quickly evaluate if the current state is an error state.
+         *
+         * @return true, if the state is not ERROR or MISSING.
+         */
+        boolean isError() {
+            return this.ordinal() == MISSING.ordinal() || this.ordinal() == ERROR.ordinal();
+        }
+    }
+
+    /**
+     * The finding level.
+     */
+    private final Finding result;
+
+    /**
+     * The message.
+     */
+    private final String message;
+
+    /**
+     * The validation source.
+     */
+    private final Object source;
+
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param source the source item, not null.
+     * @param message the message, not null.
+     * @return a new validation check containing valid parts createObject the given model.
+     */
+    public static ValidationCheck createValid(Object source, String message) {
+        return new ValidationCheck(source, Finding.VALID, null);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param source the validated source, not null.
+     * @param message the message, not null.
+     * @return a new validation check containing missing parts createObject the given model.
+     */
+    public static ValidationCheck createMissing(Object source, String message) {
+        return new ValidationCheck(source, Finding.MISSING, message);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param source the validated source, not null.
+     * @param message error message, not null.
+     * @return a new validation check containing erroneous parts createObject the given model with the given error message.
+     */
+    public static ValidationCheck createError(Object source, String message) {
+        return new ValidationCheck(source, Finding.ERROR, message);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param source the validated source, not null.
+     * @param message warning message to, not null.
+     * @return a new validation check containing warning parts createObject the given model with the given warning message.
+     */
+    public static ValidationCheck createWarning(Object source, String message) {
+        return new ValidationCheck(source, Finding.WARNING, message);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param source the validated source, not null.
+     * @param message allows the message, not null.
+     * @return a new validation check containing deprecated parts createObject the given model with an optional message.
+     */
+    public static ValidationCheck createDeprecated(Object source, String message) {
+        return new ValidationCheck(source, Finding.DEPRECATED, message);
+    }
+
+    /**
+     * Creates a new ValidationResult.
+     *
+     * @param source the validated source, not null.
+     * @return a new validation result containing deprecated parts createObject the given model.
+     */
+    public static ValidationCheck createDeprecated(Object source) {
+        return new ValidationCheck(source, Finding.DEPRECATED, "Deprecated: " + source);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * @param source the validated specification, not null.
+     * @param result     the configModel result, not null.
+     * @param message    the detail message.
+     */
+    private ValidationCheck(Object source, Finding result, String message) {
+        this.message = Objects.requireNonNull(message);
+        this.source = Objects.requireNonNull(source);
+        this.result = Objects.requireNonNull(result);
+    }
+
+    /**
+     * Get the validation result.
+     *
+     * @return the result, never null.
+     */
+    public Finding getResult() {
+        return result;
+    }
+
+    /**
+     * Get the validation message.
+     *
+     * @return the detail message, or null.
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * Get the checks source.
+     * @return the source, not null.
+     */
+    public Object getSource(){
+        return source;
+    }
+
+    @Override
+    public String toString() {
+        String finalMessage = "";
+        if (message != null) {
+            finalMessage = " -> " + message;
+        }
+        if(source instanceof ConfigPropertySpec){
+            ConfigPropertySpec pspec = (ConfigPropertySpec) source;
+            return result + ": " + pspec.name() + " (property)"+finalMessage + '\n';
+        }
+        else if(source instanceof ConfigAreaSpec){
+            ConfigAreaSpec gspec = (ConfigAreaSpec) source;
+            return result + ": " + gspec.path() + " (group)"+finalMessage + '\n';
+        }
+        return result + ": " + source + ")"+finalMessage + '\n';
+    }
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/ValidationResult.java b/validation/src/main/java/org/apache/tamaya/validation/ValidationResult.java
index 942a755..3c1dad0 100644
--- a/validation/src/main/java/org/apache/tamaya/validation/ValidationResult.java
+++ b/validation/src/main/java/org/apache/tamaya/validation/ValidationResult.java
@@ -18,42 +18,80 @@
  */
 package org.apache.tamaya.validation;
 
+import org.apache.tamaya.ConfigurationSnapshot;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
 /**
- * Enum type describing the different validation results supported.
+ * Result of a validation performed on a configuration.
  */
-public enum ValidationResult {
-    /**
-     * The validated item is valid
-     */
-    VALID,
-    /**
-     * The validated item is deprecated.
-     */
-    DEPRECATED,
-    /**
-     * The validated item is correct, but the createValue is worth a warning.
-     */
-    WARNING,
-    /**
-     * The given section or parameter is not a defined/validated item. It may be still valid, but typically,
-     * when validation is fully implemented, such a parameter or section should be removed.
-     */
-    UNDEFINED,
-    /**
-     * A required parameter or section is missing.
-     */
-    MISSING,
-    /**
-     * The validated item has an invalid createValue.
-     */
-    ERROR;
+public final class ValidationResult {
+    private ConfigurationSnapshot snapshot;
+    private List<ValidationCheck> result;
 
     /**
-     * Method to quickly evaluate if the current state is an error state.
-     *
-     * @return true, if the state is not ERROR or MISSING.
+     * Creates a new validation result.
+     * @param snapshot the snapshpt config, not null.
+     * @param result the result, not null.
      */
-    boolean isError() {
-        return this.ordinal() == MISSING.ordinal() || this.ordinal() == ERROR.ordinal();
+    public ValidationResult(ConfigurationSnapshot snapshot, List<ValidationCheck> result) {
+        this.snapshot = Objects.requireNonNull(snapshot);
+        this.result = Objects.requireNonNull(result);
+    }
+
+    /**
+     * Access the validated snapshot.
+     * @return the snapshot, not null.
+     */
+    public ConfigurationSnapshot getSnapshot() {
+        return snapshot;
+    }
+
+    /**
+     * Access the validation findings.
+     * @return the findings, not null.
+     */
+    public List<ValidationCheck> getResult() {
+        return result;
+    }
+
+    /**
+     * Checks if the validation does not include errors.
+     * @return true if no errors were identified.
+     */
+    public boolean isSuccessfull(){
+        for(ValidationCheck check:this.result){
+            if(check.getResult().isError()){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Get the the findings filtered by Finding types given.
+     * @param findingTypes the findingTypes.
+     * @return the filterered list.
+     */
+    public List<ValidationCheck> getResultByFindings(ValidationCheck.Finding... findingTypes){
+        List<ValidationCheck.Finding> findings = Arrays.asList(findingTypes);
+        if(findings.isEmpty()){
+            return result;
+        }else{
+            return result.stream()
+                    .filter(f -> findings.contains(f))
+                    .collect(Collectors.toList());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "ValidationResult{" +
+                "snapshot=" + snapshot +
+                ", result=" + result +
+                '}';
     }
 }
diff --git a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfigDocumentationBean.java b/validation/src/main/java/org/apache/tamaya/validation/internal/ConfigDocumentationBean.java
deleted file mode 100644
index 14d4d02..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfigDocumentationBean.java
+++ /dev/null
@@ -1,196 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.internal;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.ConfigModelManager;
-import org.apache.tamaya.validation.ModelTarget;
-import org.apache.tamaya.validation.Validation;
-import org.apache.tamaya.validation.spi.ConfigDocumentationMBean;
-
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * MBean implementation createObject {@link ConfigDocumentationMBean}.
- */
-public class ConfigDocumentationBean implements ConfigDocumentationMBean{
-
-    private final JsonWriterFactory writerFactory;
-
-    private static final Comparator<Validation> COMPARATOR = new Comparator<Validation>() {
-        @Override
-        public int compare(Validation v1, Validation v2) {
-            int compare = VAL_COMPARATOR.compare(v1.getConfigModel(), v2.getConfigModel());
-            if(compare==0){
-                compare = v1.getResult().compareTo(v2.getResult());
-            }
-            if(compare==0){
-                return v1.getMessage().compareTo(v2.getMessage());
-            }
-            return compare;
-        }
-    };
-    private static final Comparator<ConfigModel> VAL_COMPARATOR = new Comparator<ConfigModel>() {
-        @Override
-        public int compare(ConfigModel v1, ConfigModel v2) {
-            int compare = v1.getType().compareTo(v2.getType());
-            if(compare==0){
-                compare = v1.getName().compareTo(v2.getName());
-            }
-            return compare;
-        }
-    };
-
-    private Configuration config;
-
-    /**
-     * Default constructor, using the current configuration being available.
-     */
-    public ConfigDocumentationBean(){
-        this(null);
-    }
-
-
-    /**
-     * Creates an mbean bound to the given configuration. This is useful, when multiple mbeans for each
-     * context should be used, e.g. one mbean per ear, app deployment.
-     * @param config the configuration to be used.
-     */
-    public ConfigDocumentationBean(Configuration config){
-        this.config = config;
-        Map<String, Object> writerProperties = new HashMap<>(1);
-        writerProperties.put(JsonGenerator.PRETTY_PRINTING, true);
-        writerFactory = Json.createWriterFactory(writerProperties);
-    }
-
-    /**
-     * Access the configuration.
-     * @return either the configuration bound to this bean, or the current configuration.
-     */
-    private Configuration getConfig(){
-        return config!=null?config: Configuration.current();
-    }
-
-    @Override
-    public String validate(boolean showUndefined) {
-        List<Validation> validations = new ArrayList<>(ConfigModelManager.validate(getConfig(), showUndefined));
-        Collections.sort(validations, COMPARATOR);
-        JsonArrayBuilder builder = Json.createArrayBuilder();
-        for(Validation val:validations){
-            builder.add(toJsonObject(val));
-        }
-        return formatJson(builder.build());
-    }
-
-
-
-    @Override
-    public String getConfigurationModel() {
-        List<ConfigModel> configModels = new ArrayList<>(ConfigModelManager.getModels());
-        Collections.sort(configModels, VAL_COMPARATOR);
-        JsonArrayBuilder result = Json.createArrayBuilder();
-        for(ConfigModel val: configModels){
-            result.add(toJsonObject(val));
-        }
-        return formatJson(result.build());
-    }
-
-    @Override
-    public String getConfigurationModel(ModelTarget type) {
-        return findValidationModels(".*", type);
-    }
-
-    @Override
-    public String findConfigurationModels(String namePattern) {
-        List<ConfigModel> configModels = new ArrayList<>(ConfigModelManager.findModels(namePattern));
-        Collections.sort(configModels, VAL_COMPARATOR);
-        JsonArrayBuilder result = Json.createArrayBuilder();
-        for(ConfigModel val: configModels){
-            result.add(toJsonObject(val));
-        }
-        return formatJson(result.build());
-    }
-
-    @Override
-    public String findValidationModels(String namePattern, ModelTarget... type) {
-        List<ConfigModel> configModels = new ArrayList<>(ConfigModelManager.findModels(namePattern, type));
-        Collections.sort(configModels, VAL_COMPARATOR);
-        JsonArrayBuilder result = Json.createArrayBuilder();
-        for(ConfigModel val: configModels){
-            result.add(toJsonObject(val));
-        }
-        return formatJson(result.build());
-    }
-
-    @Override
-    public String toString(){
-        return "ConfigDocumentationBean, config: " + (this.config!=null?this.config.toString():"<current>");
-    }
-
-
-    private JsonObject toJsonObject(ConfigModel val) {
-        JsonObjectBuilder valJson = Json.createObjectBuilder().add("target", val.getType().toString())
-                .add("name", val.getName());
-        if(val.getDescription()!=null) {
-            valJson.add("description", val.getDescription());
-        }
-        if(val.isRequired()){
-            valJson.add("required",true);
-        }
-        return valJson.build();
-    }
-
-    private JsonObject toJsonObject(Validation val) {
-        JsonObjectBuilder valJson = Json.createObjectBuilder().add("target", val.getConfigModel().getType().toString())
-                .add("name", val.getConfigModel().getName());
-        if(val.getConfigModel().isRequired()){
-            valJson.add("required",true);
-        }
-        if(val.getConfigModel().getDescription() != null){
-            valJson.add("description", val.getConfigModel().getDescription());
-        }
-        valJson.add("result", val.getResult().toString());
-        if( val.getMessage() != null) {
-            valJson.add("message", val.getMessage());
-        }
-        return valJson.build();
-    }
-
-    private String formatJson(JsonArray data) {
-        StringWriter writer = new StringWriter();
-        JsonWriter gen = writerFactory.createWriter(writer);
-        gen.writeArray(data);
-        return writer.toString();
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfigValidationDocumentationReader.java b/validation/src/main/java/org/apache/tamaya/validation/internal/ConfigValidationDocumentationReader.java
new file mode 100644
index 0000000..67b2979
--- /dev/null
+++ b/validation/src/main/java/org/apache/tamaya/validation/internal/ConfigValidationDocumentationReader.java
@@ -0,0 +1,98 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.validation.internal;
+
+import java.util.*;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.doc.ConfigDocumenter;
+import org.apache.tamaya.doc.DocumentedArea;
+import org.apache.tamaya.doc.DocumentedConfiguration;
+import org.apache.tamaya.doc.DocumentedProperty;
+import org.apache.tamaya.spi.ClassloaderAware;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.validation.spi.ConfigValidator;
+import org.apache.tamaya.validation.ValidationCheck;
+import org.apache.tamaya.validation.spi.AreaValidator;
+import org.apache.tamaya.validation.spi.PropertyValidator;
+
+/**
+ * Utility class to read metamodel information from properties. Hereby these properties can be part createObject a
+ * configuration (containing other entriees as well) or be dedicated model definition properties read
+ * from any kind createObject source.
+ */
+public class ConfigValidationDocumentationReader implements ClassloaderAware {
+
+    private ClassLoader classLoader;
+
+    public static ConfigValidationDocumentationReader getInstance(){
+        return ServiceContextManager.getServiceContext()
+                .getService(ConfigValidationDocumentationReader.class, ConfigValidationDocumentationReader::new);
+    }
+
+    public static ConfigValidationDocumentationReader getInstance(ClassLoader classLoader){
+        return ServiceContextManager.getServiceContext(classLoader)
+                .getService(ConfigValidationDocumentationReader.class, ConfigValidationDocumentationReader::new);
+    }
+
+
+    /**
+     * Loads validations as configured in the given properties.
+     * @param classLoader the target classLoader, not null.
+     * @return a collection createObject config validations.
+     */
+    public List<ConfigValidator> loadValidations(ClassLoader classLoader) {
+        List<ConfigValidator> result = new ArrayList<>();
+        DocumentedConfiguration configDoc = ConfigDocumenter.getInstance(classLoader).getDocumentation();
+        for(DocumentedArea docArea: configDoc.getAllAreasSorted()){
+            loadValidations(docArea, result);
+        }
+        for(DocumentedProperty docProp: configDoc.getAllPropertiesSorted()){
+            result.add(new PropertyValidator(docProp));
+        }
+        return result;
+    }
+
+    private void loadValidations(DocumentedArea docArea, List<ConfigValidator> result) {
+        result.add(new AreaValidator(docArea));
+        for(DocumentedProperty propDoc:docArea.getPropertiesSorted()){
+            result.add(new PropertyValidator(propDoc));
+        }
+        for(DocumentedArea area:docArea.getAreasSorted()){
+            loadValidations(area, result);
+        }
+    }
+
+    @Override
+    public void init(ClassLoader classLoader) {
+        this.classLoader = Objects.requireNonNull(classLoader);
+    }
+
+    @Override
+    public ClassLoader getClassLoader() {
+        return classLoader;
+    }
+
+    public List<ValidationCheck> validateConfiguration(Configuration config){
+        List<ValidationCheck> result = new ArrayList<>();
+
+        return result;
+    }
+
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredInlineModelProviderSpi.java b/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredInlineModelProviderSpi.java
deleted file mode 100644
index 685271e..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredInlineModelProviderSpi.java
+++ /dev/null
@@ -1,83 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.internal;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.spi.ClassloaderAware;
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.spi.ConfigModelReader;
-import org.apache.tamaya.validation.spi.ModelProviderSpi;
-
-import java.util.*;
-import java.util.logging.Logger;
-
-/**
- * ConfigModel provider that reads model metadata from the current {@link org.apache.tamaya.Configuration}.
- */
-public class ConfiguredInlineModelProviderSpi implements ModelProviderSpi, ClassloaderAware {
-
-    /** The logger. */
-    private static final Logger LOG = Logger.getLogger(ConfiguredInlineModelProviderSpi.class.getName());
-    /** parameter to disable this provider. By default the provider is active. */
-    private static final String MODEL_EANABLED_PARAM = "org.apache.tamaya.model.integrated.enabled";
-
-    /** The configModels read. */
-    private List<ConfigModel> configModels = new ArrayList<>();
-    /** The target classloader used. */
-    private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
-    /**
-     * Constructor, typically called by the {@link java.util.ServiceLoader}.
-     */
-    public ConfiguredInlineModelProviderSpi() {
-        load();
-    }
-
-    /**
-     * Loads the models from the underlying service provider.
-     */
-    public void load(){
-        String enabledVal = Configuration.current(classLoader).get(MODEL_EANABLED_PARAM);
-        boolean enabled = enabledVal == null || "true".equalsIgnoreCase(enabledVal);
-        if (enabled) {
-            LOG.info("Reading model configuration from config...");
-            Map<String,String> config = Configuration.current().getProperties();
-            String owner = config.get("_model.provider");
-            if(owner==null){
-                owner = config.toString();
-            }
-            configModels.addAll(ConfigModelReader.loadValidations(owner, config));
-        }
-        configModels = Collections.unmodifiableList(configModels);
-    }
-
-    public Collection<ConfigModel> getConfigModels() {
-        return configModels;
-    }
-
-    @Override
-    public void init(ClassLoader classLoader) {
-        this.classLoader = Objects.requireNonNull(classLoader);
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        return classLoader;
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredPropertiesModelProviderSpi.java b/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredPropertiesModelProviderSpi.java
deleted file mode 100644
index 623e0e9..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredPropertiesModelProviderSpi.java
+++ /dev/null
@@ -1,154 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.internal;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.spi.ConfigModelReader;
-import org.apache.tamaya.validation.spi.ModelProviderSpi;
-import org.apache.tamaya.spisupport.propertysource.MapPropertySource;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * ConfigModel provider that reads model metadata from property files from
- * {@code classpath*:META-INF/configmodel.properties} in the following format:
- * <pre>
- * ###################################################################################
- * # Example createObject a configuration metamodel expressed via properties.
- * ####################################################################################
- *
- * # Metamodel information
- * [model].provider=ConfigModel Extension
- *
- * ####################################################################################
- * # Description createObject Configuration Sections (minimal, can be extended by other modules).
- * # By default its interpreted as a section !
- * ####################################################################################
- *
- * # a (section)
- * {model}a.class=Section
- * {model}a.params2.class=Parameter
- * {model}a.params2.type=String
- * {model}a.params2.required=true
- * {model}a.params2.description=a required parameter
- *
- * {model}a.paramInt.class=Parameter
- * {model}a.paramInt.ref=MyNumber
- * {model}a.paramInt.description=an optional parameter (default)
- *
- * {model}a._number.class=Parameter
- * {model}a._number.type=Integer
- * {model}a._number.deprecated=true
- * {model}a._number.mappedTo=a.paramInt
- *
- * # a.b.c (section)
- * {model}a.b.c.class=Section
- * {model}a.b.c.description=Just a test section
- *
- * # a.b.c.aRequiredSection (section)
- * {model}a.b.c.aRequiredSection.class=Section
- * {model}a.b.c.aRequiredSection.required=true
- * {model}a.b.c.aRequiredSection.description=A section containing required parameters is called a required section.\
- * Sections can also explicitly be defined to be required, but without\
- * specifying the paramteres to be contained.,
- *
- * # a.b.c.aRequiredSection.subsection (section)
- * {model}a.b.c.aRequiredSection.subsection.class=Section
- *
- * {model}a.b.c.aRequiredSection.subsection.param0.class=Parameter
- * {model}a.b.c.aRequiredSection.subsection.param0.type=String
- * {model}a.b.c.aRequiredSection.subsection.param0.description=a minmally documented String parameter
- * # A minmal String parameter
- * {model}a.b.c.aRequiredSection.subsection.param00.class=Parameter
- * {model}a.b.c.aRequiredSection.subsection.param00.type=String
- *
- * # a.b.c.aRequiredSection.subsection (section)
- * {model}a.b.c.aRequiredSection.subsection.param1.class=Parameter
- * {model}a.b.c.aRequiredSection.subsection.param1.type = String
- * {model}a.b.c.aRequiredSection.subsection.param1.required = true
- * {model}a.b.c.aRequiredSection.subsection.intParam.class=Parameter
- * {model}a.b.c.aRequiredSection.subsection.intParam.type = Integer
- * {model}a.b.c.aRequiredSection.subsection.intParam.description=an optional parameter (default)
- *
- * # a.b.c.aRequiredSection.nonempty-subsection (section)
- * {model}a.b.c.aRequiredSection.nonempty-subsection.class=Section
- * {model}a.b.c.aRequiredSection.nonempty-subsection.required=true
- *
- * # a.b.c.aRequiredSection.optional-subsection (section)
- * {model}a.b.c.aRequiredSection.optional-subsection.class=Section
- *
- * # a.b.c.aValidatedSection (section)
- * {model}a.b.c.aValidatedSection.class=Section
- * {model}a.b.c.aValidatedSection.description=A validated section.
- * {model}a.b.c.aValidatedSection.configModels=org.apache.tamaya.model.TestValidator
- * </pre>
- */
-public class ConfiguredPropertiesModelProviderSpi implements ModelProviderSpi {
-
-    /** The logger. */
-    private static final Logger LOG = Logger.getLogger(ConfiguredPropertiesModelProviderSpi.class.getName());
-    /** parameter to disable this provider. By default the provider is active. */
-    private static final String MODEL_EANABLED_PARAM = "org.apache.tamaya.model.default.enabled";
-    /** The configModels read. */
-    private List<ConfigModel> configModels = new ArrayList<>();
-
-    public ConfiguredPropertiesModelProviderSpi() {
-        String enabledVal = Configuration.current().get(MODEL_EANABLED_PARAM);
-        boolean enabled = enabledVal == null || "true".equalsIgnoreCase(enabledVal);
-        if(!enabled){
-            LOG.info("Reading model data from META-INF/configmodel.properties has been disabled.");
-            return;
-        }
-        try {
-            LOG.info("Reading model data from META-INF/configmodel.properties...");
-            Enumeration<URL> configs = getClass().getClassLoader().getResources("META-INF/configmodel.properties");
-            while (configs.hasMoreElements()) {
-                URL config = configs.nextElement();
-                try (InputStream is = config.openStream()) {
-                    Properties props = new Properties();
-                    props.load(is);
-                    Map<String,String> data = MapPropertySource.getMap(props);
-                    String owner = data.get("_model.owner");
-                    if(owner==null){
-                        owner = config.toString();
-                    }
-                    configModels.addAll(ConfigModelReader.loadValidations(owner,
-                            data));
-                } catch (Exception e) {
-                    Logger.getLogger(getClass().getName()).log(Level.SEVERE,
-                            "Error loading config metadata from " + config, e);
-                }
-            }
-        } catch (Exception e) {
-            LOG.log(Level.SEVERE,
-                    "Error loading config metadata from META-INF/configmodel.properties", e);
-        }
-        configModels = Collections.unmodifiableList(configModels);
-    }
-
-
-    public Collection<ConfigModel> getConfigModels() {
-        return configModels;
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredResourcesModelProviderSpi.java b/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredResourcesModelProviderSpi.java
deleted file mode 100644
index 6edb411..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredResourcesModelProviderSpi.java
+++ /dev/null
@@ -1,186 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.format.ConfigurationData;
-import org.apache.tamaya.format.ConfigurationFormats;
-import org.apache.tamaya.resource.ResourceResolver;
-import org.apache.tamaya.spi.ClassloaderAware;
-import org.apache.tamaya.spi.PropertyValue;
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.spi.ConfigModelReader;
-import org.apache.tamaya.validation.spi.ModelProviderSpi;
-
-/**
- * ConfigModel provider that reads model metadata from property files from
- * {@code classpath*:META-INF/configmodel.json} in the following format:
- * <pre>
- *  Example createObject a configuration metamodel expressed via YAML.
- *  Structure is shown through indentation (one or more spaces).
- *  Sequence items are denoted by a dash,
- *  key createValue pairs within a map are separated by a colon.
- * </pre>
- */
-public class ConfiguredResourcesModelProviderSpi implements ModelProviderSpi, ClassloaderAware {
-
-    /**
-     * The logger.
-     */
-    private static final Logger LOG = Logger.getLogger(ConfiguredResourcesModelProviderSpi.class.getName());
-    /**
-     * The parameter that can be used to configure the location createObject the configuration model resources.
-     */
-    private static final String MODEL_RESOURCE_PARAM = "org.apache.tamaya.model.resources";
-    /**
-     * The resource class to checked for testing the availability createObject the resources extension module.
-     */
-    private static final String CONFIG_RESOURCE_CLASS = "org.apache.tamaya.resource.ConfigResource";
-    /**
-     * The resource class to checked for testing the availability createObject the formats extension module.
-     */
-    private static final String CONFIGURATION_FORMATS_CLASS = "org.apache.tamaya.format.ConfigurationFormats";
-    /**
-     * Initializes the flag showing if the formats module is present (required).
-     */
-    private static final boolean AVAILABLE = checkAvailabilityFormats();
-    /**
-     * Initializes the flag showing if the resources module is present (optional).
-     */
-    private static final boolean RESOURCES_EXTENSION_AVAILABLE = checkAvailabilityResources();
-
-    /**
-     * The configModels read.
-     */
-    private List<ConfigModel> configModels = new ArrayList<>();
-
-    /** The target classloader. */
-    private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
-
-    /**
-     * Initializes the flag showing if the formats module is present (required).
-     */
-    private static boolean checkAvailabilityFormats() {
-        try {
-            Class.forName(CONFIGURATION_FORMATS_CLASS);
-            return true;
-        } catch (final Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Initializes the flag showing if the resources module is present (optional).
-     */
-    private static boolean checkAvailabilityResources() {
-        try {
-            Class.forName(CONFIG_RESOURCE_CLASS);
-            return true;
-        } catch (final Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Constructor, mostly called from {@link java.util.ServiceLoader}
-     */
-    public ConfiguredResourcesModelProviderSpi() {
-        if (!AVAILABLE) {
-            LOG.info("tamaya-format extension is required to read model configuration, No extended model support AVAILABLE.");
-        } else {
-            reload();
-        }
-    }
-
-    /**
-     * Reloads the provider using resources from the current classloader.
-     */
-    public void reload(){
-        final String resources = Configuration.current().get(MODEL_RESOURCE_PARAM);
-        if (resources == null || resources.trim().isEmpty()) {
-            LOG.info("Mo model resources location configured in " + MODEL_RESOURCE_PARAM + ".");
-            return;
-        }
-        Collection<URL> urls;
-        if (RESOURCES_EXTENSION_AVAILABLE) {
-            LOG.info("Using tamaya-resources extension to read model configuration from " + resources);
-            urls = ResourceResolver.getInstance(classLoader).getResources(resources.split(","));
-        } else {
-            LOG.info("Using default classloader resource location to read model configuration from " + resources);
-            urls = new ArrayList<>();
-            for (final String resource : resources.split(",")) {
-                if (!resource.trim().isEmpty()) {
-                    Enumeration<URL> configs;
-                    try {
-                        configs = getClass().getClassLoader().getResources(resource);
-                        while (configs.hasMoreElements()) {
-                            urls.add(configs.nextElement());
-                        }
-                    } catch (final IOException e) {
-                        Logger.getLogger(getClass().getName()).log(Level.SEVERE,
-                                "Error evaluating config model locations from " + resource, e);
-                    }
-                }
-            }
-        }
-        // Reading configs
-        for (final URL config : urls) {
-            try (InputStream is = config.openStream()) {
-                final ConfigurationData data = ConfigurationFormats.getInstance()
-                   .readConfigurationData(config);
-                Map<String,String> props = new HashMap<>();
-                for(PropertyValue val:data.getData()){
-                    props.putAll(val.toMap());
-                }
-                String owner = props.get("_model.provider");
-                if(owner==null){
-                    owner = config.toString();
-                }
-                configModels.addAll(ConfigModelReader.loadValidations(owner, props));
-            } catch (final Exception e) {
-                Logger.getLogger(getClass().getName()).log(Level.SEVERE,
-                        "Error loading config model data from " + config, e);
-            }
-        }
-        configModels = Collections.unmodifiableList(configModels);
-    }
-
-    @Override
-    public Collection<ConfigModel> getConfigModels() {
-        return configModels;
-    }
-
-    @Override
-    public void init(ClassLoader classLoader) {
-        this.classLoader = Objects.requireNonNull(classLoader);
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        return classLoader;
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredTypeEventsModelPopulator.java b/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredTypeEventsModelPopulator.java
deleted file mode 100644
index 7436a81..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredTypeEventsModelPopulator.java
+++ /dev/null
@@ -1,124 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.internal;
-
-import org.apache.tamaya.events.ConfigEvent;
-import org.apache.tamaya.events.ConfigEventListener;
-import org.apache.tamaya.inject.spi.ConfiguredField;
-import org.apache.tamaya.inject.spi.ConfiguredMethod;
-import org.apache.tamaya.inject.spi.ConfiguredType;
-import org.apache.tamaya.spi.ClassloaderAware;
-import org.apache.tamaya.spi.ServiceContextManager;
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.ConfigModelManager;
-import org.apache.tamaya.validation.spi.ModelProviderSpi;
-import org.apache.tamaya.validation.spi.ParameterModel;
-
-import java.util.Collection;
-import java.util.Objects;
-import java.util.logging.Logger;
-
-/**
- * Internal facade that registers all kind createObject injected fields as {@link org.apache.tamaya.validation.ConfigModel} entries,
- * so all configured injection points are visible as documented configuration hooks.
- */
-public final class ConfiguredTypeEventsModelPopulator implements ConfigEventListener, ClassloaderAware {
-
-    /**
-     * The logger.
-     */
-    private static final Logger LOG = Logger.getLogger(ConfiguredTypeEventsModelPopulator.class.getName());
-
-    /** System property to be setCurrent to deactivate auto documentation createObject configured classes published thorugh
-     * ConfiguredType events.
-     */
-    private static final String ENABLE_EVENT_DOC = "org.apache.tamaya.model.autoModelEvents";
-    private ClassLoader classLoader = ServiceContextManager.getDefaultClassLoader();
-
-    @Override
-    public void onConfigEvent(ConfigEvent event) {
-        if(event.getResourceType()!=ConfiguredType.class){
-            return;
-        }
-        String value = System.getProperty(ENABLE_EVENT_DOC);
-        if(value == null || Boolean.parseBoolean(value)) {
-            ConfiguredType confType = (ConfiguredType)event.getResource();
-            for (ConfiguredField field : confType.getConfiguredFields()) {
-                Collection<String> keys = field.getConfiguredKeys();
-                for (String key : keys) {
-                    ParameterModel val = getModel(key, ParameterModel.class, classLoader);
-                    if (val == null) {
-                        ConfiguredTypeEventsModelProvider.addConfigModel(
-                                new ParameterModel.Builder(confType.getName(), key)
-                                .setType(field.getType().getName())
-                                .setDescription("Injected field: " +
-                                        field.getAnnotatedField().getDeclaringClass().getName() + '.' + field.toString() +
-                                        ", \nconfigured with keys: " + keys)
-                                .build());
-                    }
-                }
-            }
-            for (ConfiguredMethod method : confType.getConfiguredMethods()) {
-                Collection<String> keys = method.getConfiguredKeys();
-                for (String key : keys) {
-                    ParameterModel val = getModel(key, ParameterModel.class, classLoader);
-                    if (val == null) {
-                        ConfiguredTypeEventsModelProvider.addConfigModel(
-                                new ParameterModel.Builder(confType.getName(), key)
-                                .setType(method.getParameterTypes()[0].getName())
-                                .setDescription("Injected field: " +
-                                        method.getAnnotatedMethod().getDeclaringClass().getName() + '.' + method.toString() +
-                                        ", \nconfigured with keys: " + keys)
-                                .build());
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Find the validations by matching the validation's name against the given model type.
-     *
-     * @param classLoader the target classloader, not null.
-     * @param name the name to use, not null.
-     * @param modelType classname createObject the target model type.
-     * @param <T> type createObject the model to filter for.
-     * @return the sections defined, never null.
-     */
-    private static <T extends ConfigModel> T getModel(String name, Class<T> modelType, ClassLoader classLoader) {
-        for (ModelProviderSpi model : ServiceContextManager.getServiceContext(classLoader).getServices(ModelProviderSpi.class)) {
-            for(ConfigModel configModel : model.getConfigModels()) {
-                if(configModel.getName().equals(name) && configModel.getClass().equals(modelType)) {
-                    return modelType.cast(configModel);
-                }
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public void init(ClassLoader classLoader) {
-        this.classLoader = Objects.requireNonNull(classLoader);
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        return classLoader;
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredTypeEventsModelProvider.java b/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredTypeEventsModelProvider.java
deleted file mode 100644
index e1708eb..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/internal/ConfiguredTypeEventsModelProvider.java
+++ /dev/null
@@ -1,51 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.internal;
-
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.spi.ModelProviderSpi;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Model provider that adds model definitions for the items published as
- * {@link org.apache.tamaya.inject.spi.ConfiguredType} events.
- */
-public class ConfiguredTypeEventsModelProvider implements ModelProviderSpi {
-    /** The collected models. */
-    private static Collection<ConfigModel> configModels = new ArrayList<>();
-
-    /**
-     * Adds a model, called from the registered listener class.
-     * @param configModel adds the config model.
-     */
-    static void addConfigModel(ConfigModel configModel){
-        List<ConfigModel> newList = new ArrayList<>(configModels);
-        newList.add(configModel);
-        ConfiguredTypeEventsModelProvider.configModels = newList;
-    }
-
-    @Override
-    public Collection<ConfigModel> getConfigModels() {
-        return Collections.unmodifiableCollection(configModels);
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/AbstractConfigModel.java b/validation/src/main/java/org/apache/tamaya/validation/spi/AbstractConfigModel.java
deleted file mode 100644
index 37fbfe1..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/spi/AbstractConfigModel.java
+++ /dev/null
@@ -1,88 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.spi;
-
-import org.apache.tamaya.validation.ConfigModel;
-
-import java.util.Objects;
-
-/**
- * Default configuration Model for a configuration area.
- */
-public abstract class AbstractConfigModel implements ConfigModel, Comparable<ConfigModel> {
-    private final String owner;
-    private final String name;
-    private final String description;
-    private boolean required = false;
-
-
-    protected AbstractConfigModel(String owner, String name, boolean required, String description) {
-        this.name = Objects.requireNonNull(name);
-        this.owner = Objects.requireNonNull(owner);
-        this.description = description;
-        this.required = required;
-    }
-
-    @Override
-    public String getOwner() {
-        return owner;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public String getDescription() {
-        return description;
-    }
-
-    @Override
-    public boolean isRequired() {
-        return required;
-    }
-
-    @Override
-    public int compareTo(ConfigModel configModel) {
-        int compare = getType().compareTo(configModel.getType());
-        if (compare != 0) {
-            return compare;
-        }
-        return getName().compareTo(configModel.getName());
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        AbstractConfigModel that = (AbstractConfigModel) o;
-        return getType().equals(that.getType()) && name.equals(that.name);
-
-    }
-
-    @Override
-    public int hashCode() {
-        return getType().hashCode() + name.hashCode();
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/AbstractValidator.java b/validation/src/main/java/org/apache/tamaya/validation/spi/AbstractValidator.java
new file mode 100644
index 0000000..15de27a
--- /dev/null
+++ b/validation/src/main/java/org/apache/tamaya/validation/spi/AbstractValidator.java
@@ -0,0 +1,107 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.validation.spi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.validation.ValidationCheck;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Base class for a validator.
+ */
+public abstract class AbstractValidator implements ConfigValidator {
+
+    /** The target key to validate. */
+    private String key;
+    /** The optional description. */
+    private String description;
+    /** The required flag. */
+    private boolean required;
+
+    /**
+     * Internal constructor.
+     * @param key the target configuration key, not null.
+     * @param required true, if the value/validation must be successful.
+     * @param description the description, not null.
+     */
+    protected AbstractValidator(String key, boolean required, String description) {
+        this.required = required;
+        this.description = description;
+    }
+
+    /**
+     * Get the area or paramter key.
+     * @return
+     */
+    public String getKey() {
+        return key;
+    }
+
+    /**
+     * Get the description of the validation.
+     * @return the description.
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Checks if the validation will declare an error if not met.
+     * @return true, if the validation must not fail.
+     */
+    public boolean isRequired() {
+        return required;
+    }
+
+    @Override
+    public List<ValidationCheck> validate(Configuration config) {
+        List<ValidationCheck> result = new ArrayList<>(1);
+        List<PropertyValue> configValues = config.get(key, new TypeLiteral<List<PropertyValue>>());
+        if (configValues.isEmpty() && required) {
+            result.add(ValidationCheck.createMissing(this, "Key " + key +" must be present"));
+        }else{
+            validateValues(configValues, result);
+        }
+        return result;
+    }
+
+    /**
+     * Internal method to override.
+     * @param configValues the config values read in order of precedence.
+     * @param result the result list, where the validation checks done should be added.
+     */
+    protected abstract void validateValues(List<PropertyValue> configValues, List<ValidationCheck> result);
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append(getClass().getSimpleName()).append("{\n");
+        if (isRequired()) {
+            b.append("  required: ").append(isRequired()).append('\n');
+        }
+        b.append("  key: ").append(key).append('\n');
+        b.append("  description: ").append(description).append("\n}\n");
+        return b.toString();
+    }
+
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/AreaValidator.java b/validation/src/main/java/org/apache/tamaya/validation/spi/AreaValidator.java
new file mode 100644
index 0000000..79e5e27
--- /dev/null
+++ b/validation/src/main/java/org/apache/tamaya/validation/spi/AreaValidator.java
@@ -0,0 +1,278 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.validation.spi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.doc.DocumentedArea;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.apache.tamaya.validation.ValidationCheck;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Default configuration Model for a configuration parameter.
+ */
+public class AreaValidator implements ConfigValidator {
+
+    /** The fully qualified parameter name. */
+    private String name;
+    /** The optional description. */
+    private String description;
+    /** The min cardinality. */
+    private int minCardinality;
+    /** The max cardinality. */
+    private int maxCardinality;
+    /** The owner instance, not null. */
+    private Object owner;
+    /** The parameter's target type. */
+    private Class<?> type;
+
+    /**
+     * Create a new property validator.
+     * @param documentedArea the property docs, not null.
+     */
+    public AreaValidator(DocumentedArea documentedArea) {
+        this.name = Objects.requireNonNull(documentedArea.getPath());
+        this.description = documentedArea.getDescription();
+        this.minCardinality = documentedArea.getMinCardinality();
+        this.maxCardinality = documentedArea.getMaxCardinality();
+        this.owner = documentedArea;
+        this.type = documentedArea.getValueType();
+    }
+
+    /**
+     * Create a new property validator.
+     * @param builder the builder, not null.
+     */
+    private AreaValidator(Builder builder) {
+        this.name = Objects.requireNonNull(builder.name);
+        this.description = builder.description;
+        this.minCardinality = builder.minCardinality;
+        this.maxCardinality = builder.maxCardinality;
+        this.owner = builder.owner;
+        this.type = builder.type;
+    }
+
+
+    @Override
+    public List<ValidationCheck> validate(Configuration config) {
+        List<ValidationCheck> result = new ArrayList<>(1);
+        Configuration section = config.map(ConfigurationFunctions.section(name));
+        int size = section.getProperties().size();
+        String baseText = description;
+        if(baseText==null){
+            baseText = "Validation failure for area '" + name + "': ";
+        }else{
+            baseText = baseText + " Validation failure: ";
+        }
+        if(minCardinality!=0 && minCardinality>size){
+            result.add(ValidationCheck.createError(this, baseText + "Min cardinality required: " + minCardinality +", was: " + size));
+        }
+        if(maxCardinality!=0 && maxCardinality<size){
+            result.add(ValidationCheck.createError(this, baseText + "Max cardinality exceeded: " + maxCardinality +", was: " + size));
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append(type).append(": ").append(name);
+        if (minCardinality>0) {
+            b.append(", min: ").append(minCardinality);
+        }
+        if (maxCardinality>0) {
+            b.append(", max: ").append(maxCardinality);
+        }
+        return b.toString();
+    }
+
+    /**
+     * Creates a new Builder instance.
+     * @param owner the owner name, not null.
+     * @param name the fully qualified parameter name.
+     * @return a new builder, never null.
+     */
+    public static Builder builder(String owner, String name) {
+        return new Builder(owner, name);
+    }
+
+    /**
+     * Creates a new ConfigModel
+     * @param owner the owner name, not null.
+     * @param name the fully qualified parameter name.
+     * @param required the required flag.
+     * @return the new ConfigModel instance.
+     */
+    public static AreaValidator of(Object owner, String name, boolean required) {
+        return new Builder(name, owner).setRequired().build();
+    }
+
+    /**
+     * Creates a new ConfigModel
+     * @param owner the owner name, not null.
+     * @param name the fully qualified parameter name.
+     * @param required the required flag.
+     * @return the new ConfigModel instance.
+     */
+    public static AreaValidator of(String owner, String name, boolean required) {
+        return new Builder(owner, name).setRequired().build();
+    }
+
+    /**
+     * Creates a new ConfigModel
+     * @param owner the owner name, not null.
+     * @param name the fully qualified parameter name.
+     * @param min the minimal cardinality.
+     * @param max the maximal cardinality.
+     * @return the new ConfigModel instance.
+     */
+    public static AreaValidator of(String owner, String name, int min, int max) {
+        return new Builder(owner, name).setMinCardinality(min).setMaxCardinality(max).build();
+    }
+
+    /**
+     * Creates a new ConfigModel. The parameter will be defined as optional.
+     * @param owner the owner name, not null.
+     * @param name the fully qualified parameter name.
+     * @return the new ConfigModel instance.
+     */
+    public static AreaValidator of(String owner, String name) {
+        return new Builder(owner, name).build();
+    }
+
+
+    /**
+     * A new Builder for creating ParameterModel instances.
+     */
+    public static class Builder {
+        /** The parameter's target type. */
+        private Class<?> type;
+        /** The fully qualified parameter name. */
+        private String name;
+        /** The optional description. */
+        private String description;
+        /** The min cardinality. */
+        private int minCardinality;
+        /** The max cardinality. */
+        private int maxCardinality;
+        /** The validation owner. */
+        private Object owner;
+
+        /**
+         * Creates a new Builder.
+         * @param name the fully qualified parameter name, not null.
+         */
+        public Builder(String name, Object owner) {
+            this.name = Objects.requireNonNull(name);
+            this.owner = Objects.requireNonNull(owner);
+        }
+
+        /**
+         * Sets the target type.
+         * @param type the type, not null.
+         * @return the Builder for chaining
+         */
+        public Builder setType(String type) {
+            try {
+                this.type = Class.forName(type);
+            } catch (ClassNotFoundException e) {
+                try {
+                    this.type = Class.forName("java.ui.lang."+type);
+                } catch (ClassNotFoundException e2) {
+                    Logger.getLogger(getClass().getName()).log(Level.INFO, "Failed to load parameter type: " + type, e2);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Sets the minimum cardinality required.
+         * @param minCardinality the minimum cardinality.
+         * @return the Builder for chaining
+         */
+        public Builder setMinCardinality(int minCardinality) {
+            this.minCardinality = minCardinality;
+            return this;
+        }
+
+        /**
+         * Sets the maximum cardinality required.
+         * @param maxCardinality the maximum cardinality.
+         * @return the Builder for chaining
+         */
+        public Builder setMaxCardinality(int maxCardinality) {
+            this.maxCardinality = maxCardinality;
+            return this;
+        }
+
+        /**
+         * Sets the minimum cardinality required to {@code 1}.
+         * @return the Builder for chaining
+         */
+        public Builder setRequired() {
+            this.minCardinality = 1;
+            this.maxCardinality = 0;
+            return this;
+        }
+
+
+        /**
+         * Sets the optional description
+         * @param description the description
+         * @return the Builder for chaining
+         */
+        public Builder setDescription(String description) {
+            this.description = description;
+            return this;
+        }
+
+        /**
+         * Sets the owner name.
+         * @param owner the owner name, not null.
+         * @return the Builder for chaining
+         */
+        public Builder setOwner(Object owner) {
+            this.owner = Objects.requireNonNull(owner);
+            return this;
+        }
+
+        /**
+         * Sets the fully qualified parameter name.
+         * @param name the fully qualified parameter name, not null.
+         * @return the Builder for chaining
+         */
+        public Builder setName(String name) {
+            this.name = Objects.requireNonNull(name);
+            return this;
+        }
+
+        /**
+         * Creates a new ConfigModel with the given parameters.
+         * @return a new ConfigModel , never null.
+         */
+        public AreaValidator build() {
+            return new AreaValidator(this);
+        }
+    }
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/ConfigDocumentationMBean.java b/validation/src/main/java/org/apache/tamaya/validation/spi/ConfigDocumentationMBean.java
deleted file mode 100644
index 21e5ea1..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/spi/ConfigDocumentationMBean.java
+++ /dev/null
@@ -1,53 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.spi;
-
-import org.apache.tamaya.validation.ModelTarget;
-
-/**
- * JMX Management bean for accessing current configuration information
- */
-public interface ConfigDocumentationMBean {
-    /**
-     * Validates the configuration for the given context.
-     *
-     * @param showUndefined allows filtering for undefined configuration elements.
-     * @return the validation results, never null.
-     */
-    String validate(boolean showUndefined);
-
-    String getConfigurationModel();
-
-    String getConfigurationModel(ModelTarget type);
-
-    /**
-     * Find the validations by checking the validation's name using the given regular expression.
-     * @param namePattern the regular expression to use, not null.
-     * @return the sections defined, never null.
-     */
-    String findConfigurationModels(String namePattern);
-
-    /**
-     * Find the validations by checking the validation's name using the given regular expression.
-     * @param type the target ModelTypes (optional), not null.
-     * @param namePattern the regular expression to use, not null.
-     * @return the sections defined, never null.
-     */
-    String findValidationModels(String namePattern, ModelTarget... type);
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/ConfigModelReader.java b/validation/src/main/java/org/apache/tamaya/validation/spi/ConfigModelReader.java
deleted file mode 100644
index 5b806af..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/spi/ConfigModelReader.java
+++ /dev/null
@@ -1,142 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.spi;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.tamaya.validation.ConfigModel;
-
-/**
- * Utility class to read metamodel information from properties. Hereby these properties can be part createObject a
- * configuration (containing other entriees as well) or be dedicated model definition properties read
- * from any kind createObject source.
- */
-public final class ConfigModelReader {
-
-    /** The default model entries selector. */
-    private static final String DEFAULT_META_INFO_SELECTOR = ".model";
-
-    /**
-     * Utility class only.
-     */
-    private ConfigModelReader(){}
-
-
-    /**
-     * Loads validations as configured in the given properties.
-     * @param owner owner, not null.
-     * @param props the properties to be read
-     * @return a collection createObject config validations.
-     */
-    public static Collection<ConfigModel> loadValidations(String owner, Map<String,String> props) {
-        List<ConfigModel> result = new ArrayList<>();
-        Set<String> itemKeys = new HashSet<>();
-        for (Object key : props.keySet()) {
-            if (key.toString().startsWith("_") &&
-                    key.toString().endsWith(DEFAULT_META_INFO_SELECTOR + ".target")) {
-                itemKeys.add(key.toString().substring(0, key.toString().length() - ".model.target".length()));
-            }
-        }
-        for (String baseKey : itemKeys) {
-            String target = props.get(baseKey + ".model.target");
-            String type = props.get(baseKey + ".model.type");
-            if (type == null) {
-                type = String.class.getName();
-            }
-            String value = props.get(baseKey + ".model.transitive");
-            boolean transitive = false;
-            if(value!=null) {
-                transitive = Boolean.parseBoolean(value);
-            }
-            String description = props.get(baseKey + ".model.description");
-            String regEx = props.get(baseKey + ".model.expression");
-            String validations = props.get(baseKey + ".model.validations");
-            String requiredVal = props.get(baseKey + ".model.required");
-            String targetKey = baseKey.substring(1);
-            if ("Parameter".equalsIgnoreCase(target)) {
-                result.add(createParameterValidation(owner, targetKey,
-                        description, type, requiredVal, regEx, validations));
-            } else if ("Section".equalsIgnoreCase(target)) {
-                if(transitive){
-                    result.add(createSectionValidation(owner, targetKey+".*",
-                            description, requiredVal, validations));
-                } else {
-                    result.add(createSectionValidation(owner, targetKey,
-                            description, requiredVal, validations));
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Creates a parameter validation.
-     * @param paramName the param name, not null.
-     * @param description the optional description
-     * @param type the param type, default is String.
-     * @param reqVal the required createValue, default is 'false'.
-     * @param regEx an optional regular expression to be checked for this param
-     * @param validations the optional custom validations to be performed.
-     * @return the new validation for this parameter.
-     */
-    private static ConfigModel createParameterValidation(String owner, String paramName, String description, String type, String reqVal,
-                                                         String regEx, String validations) {
-        boolean required = "true".equalsIgnoreCase(reqVal);
-        ParameterModel.Builder builder = ParameterModel.builder(owner, paramName).setRequired(required)
-                .setDescription(description).setExpression(regEx).setType(type);
-//        if (validations != null) {
-//            try {
-//                // TODO define validator API
-////                builder.addValidations(loadValidations(validations));
-//            } catch (Exception e) {
-//                LOGGER.log(Level.WARNING, "Failed to load validations for " + paramName, e);
-//            }
-//        }
-       return builder.build();
-    }
-
-    /**
-     * Creates a section validation.
-     * @param sectionName the section's name, not null.
-     * @param description the optional description
-     * @param reqVal the required createValue, default is 'false'.
-     * @param validations the optional custom validations to be performed.
-     * @return the new validation for this section.
-     */
-    private static ConfigModel createSectionValidation(String owner, String sectionName, String description, String reqVal,
-                                                       String validations) {
-        boolean required = "true".equalsIgnoreCase(reqVal);
-        SectionModel.Builder builder = SectionModel.builder(owner, sectionName).setRequired(required)
-                .setDescription(description);
-//        if (validations != null) {
-//            try {
-//                // TODO define validator API
-////                builder.addValidations(loadValidations(valiadtions));
-//            } catch (Exception e) {
-//                LOGGER.log(Level.WARNING, "Failed to load validations for " + sectionName, e);
-//            }
-//        }
-        return builder.build();
-    }
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/ModelTarget.java b/validation/src/main/java/org/apache/tamaya/validation/spi/ConfigValidator.java
similarity index 65%
copy from validation/src/main/java/org/apache/tamaya/validation/ModelTarget.java
copy to validation/src/main/java/org/apache/tamaya/validation/spi/ConfigValidator.java
index 3af63ae..50be637 100644
--- a/validation/src/main/java/org/apache/tamaya/validation/ModelTarget.java
+++ b/validation/src/main/java/org/apache/tamaya/validation/spi/ConfigValidator.java
@@ -16,22 +16,22 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.tamaya.validation;
+package org.apache.tamaya.validation.spi;
 
-/**
- * This enumeration defines the types createObject supported validations.
- */
-public enum ModelTarget {
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.validation.ValidationCheck;
+
+import java.util.List;
+import java.util.function.Function;
+
+@FunctionalInterface
+public interface ConfigValidator {
+
     /**
-     * A configuration section.
+     * Validaters the configuration.
+     * @param config the configuration to validate, not null.
+     * @return the findings evaluated.
      */
-    Section,
-    /**
-     * A configuration paramter.
-     */
-    Parameter,
-    /**
-     * ConfigModel that is a container createObject other validations.
-     */
-    Group,
+    List<ValidationCheck> validate(Configuration config);
+
 }
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/GroupModel.java b/validation/src/main/java/org/apache/tamaya/validation/spi/GroupModel.java
deleted file mode 100644
index 2957576..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/spi/GroupModel.java
+++ /dev/null
@@ -1,110 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.spi;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.ModelTarget;
-import org.apache.tamaya.validation.Validation;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Default configuration Model for a configuration area.
- */
-public class GroupModel implements ConfigModel {
-
-    private final String owner;
-    private final String name;
-    private boolean required;
-    private List<ConfigModel> childModels = new ArrayList<>();
-
-    public GroupModel(String owner, String name, ConfigModel... configModels){
-        this(owner, name, Arrays.asList(configModels));
-    }
-
-    public GroupModel(String owner, String name, Collection<ConfigModel> configModels){
-        this.owner = Objects.requireNonNull(owner);
-        this.name = Objects.requireNonNull(name);
-        this.childModels.addAll(configModels);
-        this.childModels = Collections.unmodifiableList(childModels);
-        for(ConfigModel val: configModels) {
-            if(val.isRequired()){
-                this.required = true;
-                break;
-            }
-        }
-    }
-
-    @Override
-    public String getOwner() {
-        return owner;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public boolean isRequired() {
-        return required;
-    }
-
-    @Override
-    public ModelTarget getType() {
-        return ModelTarget.Group;
-    }
-
-    @Override
-    public String getDescription() {
-        if(childModels.isEmpty()){
-            return null;
-        }
-        StringBuilder b = new StringBuilder();
-        for(ConfigModel val: childModels){
-            b.append("  >> ").append(val);
-        }
-        return b.toString();
-    }
-
-    public Collection<ConfigModel> getValidations(){
-        return childModels;
-    }
-
-    @Override
-    public Collection<Validation> validate(Configuration config) {
-        List<Validation> result = new ArrayList<>(1);
-        for(ConfigModel child: childModels){
-            result.addAll(child.validate(config));
-        }
-        return result;
-    }
-
-    @Override
-    public String toString(){
-        return String.valueOf(getType()) + ", getNumChilds: " + childModels.size() + ": " + getDescription();
-    }
-
-}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/ParameterModel.java b/validation/src/main/java/org/apache/tamaya/validation/spi/PropertyValidator.java
similarity index 65%
rename from validation/src/main/java/org/apache/tamaya/validation/spi/ParameterModel.java
rename to validation/src/main/java/org/apache/tamaya/validation/spi/PropertyValidator.java
index cf5372f..afce656 100644
--- a/validation/src/main/java/org/apache/tamaya/validation/spi/ParameterModel.java
+++ b/validation/src/main/java/org/apache/tamaya/validation/spi/PropertyValidator.java
@@ -19,12 +19,10 @@
 package org.apache.tamaya.validation.spi;
 
 import org.apache.tamaya.Configuration;
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.ModelTarget;
-import org.apache.tamaya.validation.Validation;
+import org.apache.tamaya.doc.DocumentedProperty;
+import org.apache.tamaya.validation.ValidationCheck;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
 import java.util.logging.Level;
@@ -33,48 +31,56 @@
 /**
  * Default configuration Model for a configuration parameter.
  */
-public class ParameterModel extends AbstractConfigModel {
-    /** Optional regular expression for validating the createValue. */
-    private final String regEx;
-    /** The target type into which the createValue must be convertible. */
-    private final Class<?> type;
+public class PropertyValidator implements ConfigValidator {
+
+    /** The parameter's target type. */
+    private Class<?> type;
+    /** The fully qualified parameter name. */
+    private String name;
+    /** The optional description. */
+    private String description;
+    /** The required flag. */
+    private boolean required;
+    /** The owner instance, not null. */
+    private Object owner;
 
     /**
-     * Internal constructor.
+     * Create a new property validator.
+     * @param documentedProperty the property docs, not null.
+     */
+    public PropertyValidator(DocumentedProperty documentedProperty) {
+        this.name = Objects.requireNonNull(documentedProperty.getName());
+        this.description = documentedProperty.getDescription();
+        this.required = documentedProperty.isRequired();
+        this.owner = documentedProperty;
+        this.type = documentedProperty.getValueType();
+    }
+
+    /**
+     * Create a new property validator.
      * @param builder the builder, not null.
      */
-    protected ParameterModel(Builder builder) {
-        super(builder.owner, builder.name, builder.required, builder.description);
-        this.regEx = builder.regEx;
+    private PropertyValidator(Builder builder) {
+        this.name = Objects.requireNonNull(builder.name);
+        this.description = builder.description;
+        this.required = builder.required;
+        this.owner = builder.owner;
         this.type = builder.type;
     }
 
-    @Override
-    public ModelTarget getType() {
-        return ModelTarget.Parameter;
-    }
-
-    /**
-     * Get the required parameter type.
-     *
-     * @return the type.
-     */
-    public Class<?> getParameterType() {
-        return type;
-    }
 
     @Override
-    public Collection<Validation> validate(Configuration config) {
-        List<Validation> result = new ArrayList<>(1);
-        String configValue = config.get(getName());
-        if (configValue == null && isRequired()) {
-            result.add(Validation.createMissing(this));
+    public List<ValidationCheck> validate(Configuration config) {
+        List<ValidationCheck> result = new ArrayList<>(1);
+        String configValue = config.getOrDefault(name, null);
+        String baseText = description;
+        if(baseText==null){
+            baseText = "Validation failure for property '" + name + "': ";
+        }else{
+            baseText = baseText + " Validation failure: ";
         }
-        if (configValue != null && regEx != null) {
-            if (!configValue.matches(regEx)) {
-                result.add(Validation.createError(this, "Config createValue not matching expression: " + regEx + ", was " +
-                        configValue));
-            }
+        if (configValue == null && required) {
+            result.add(ValidationCheck.createMissing(this, baseText + " Missing."));
         }
         return result;
     }
@@ -82,12 +88,9 @@
     @Override
     public String toString() {
         StringBuilder b = new StringBuilder();
-        b.append(getType()).append(": ").append(getName());
-        if (isRequired()) {
-            b.append(", required: ").append(isRequired());
-        }
-        if (regEx != null) {
-            b.append(", expression: ").append(regEx);
+        b.append(type).append(": ").append(name);
+        if (required) {
+            b.append(", required: ").append(required);
         }
         return b.toString();
     }
@@ -107,11 +110,10 @@
      * @param owner the owner name, not null.
      * @param name the fully qualified parameter name.
      * @param required the required flag.
-     * @param expression an optional regular expression to validate a createValue.
      * @return the new ConfigModel instance.
      */
-    public static ConfigModel of(String owner, String name, boolean required, String expression) {
-        return new Builder(owner, name).setRequired(required).setExpression(expression).build();
+    public static PropertyValidator of(Object owner, String name, boolean required) {
+        return new Builder(name, owner).setRequired(required).build();
     }
 
     /**
@@ -121,7 +123,7 @@
      * @param required the required flag.
      * @return the new ConfigModel instance.
      */
-    public static ConfigModel of(String owner, String name, boolean required) {
+    public static PropertyValidator of(String owner, String name, boolean required) {
         return new Builder(owner, name).setRequired(required).build();
     }
 
@@ -131,7 +133,7 @@
      * @param name the fully qualified parameter name.
      * @return the new ConfigModel instance.
      */
-    public static ConfigModel of(String owner, String name) {
+    public static PropertyValidator of(String owner, String name) {
         return new Builder(owner, name).setRequired(false).build();
     }
 
@@ -142,25 +144,22 @@
     public static class Builder {
         /** The parameter's target type. */
         private Class<?> type;
-        /** The owner. */
-        private String owner;
         /** The fully qualified parameter name. */
         private String name;
-        /** The optional validation expression. */
-        private String regEx;
         /** The optional description. */
         private String description;
         /** The required flag. */
         private boolean required;
+        /** The validation owner. */
+        private Object owner;
 
         /**
          * Creates a new Builder.
-         * @param owner owner, not null.
          * @param name the fully qualified parameter name, not null.
          */
-        public Builder(String owner, String name) {
-            this.owner = Objects.requireNonNull(owner);
+        public Builder(String name, Object owner) {
             this.name = Objects.requireNonNull(name);
+            this.owner = Objects.requireNonNull(owner);
         }
 
         /**
@@ -202,21 +201,11 @@
         }
 
         /**
-         * Sets the optional validation expression
-         * @param expression the validation expression
-         * @return the Builder for chaining
-         */
-        public Builder setExpression(String expression) {
-            this.regEx = expression;
-            return this;
-        }
-
-        /**
          * Sets the owner name.
          * @param owner the owner name, not null.
          * @return the Builder for chaining
          */
-        public Builder setOwner(String owner) {
+        public Builder setOwner(Object owner) {
             this.owner = Objects.requireNonNull(owner);
             return this;
         }
@@ -235,8 +224,8 @@
          * Creates a new ConfigModel with the given parameters.
          * @return a new ConfigModel , never null.
          */
-        public ConfigModel build() {
-            return new ParameterModel(this);
+        public PropertyValidator build() {
+            return new PropertyValidator(this);
         }
     }
 }
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/RegexPropertyValidator.java b/validation/src/main/java/org/apache/tamaya/validation/spi/RegexPropertyValidator.java
new file mode 100644
index 0000000..a630cf2
--- /dev/null
+++ b/validation/src/main/java/org/apache/tamaya/validation/spi/RegexPropertyValidator.java
@@ -0,0 +1,105 @@
+/*
+ * 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 createObject the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.validation.spi;
+
+import org.apache.tamaya.spi.PropertyValue;
+import org.apache.tamaya.validation.ValidationCheck;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Default configuration Model for a configuration parameter.
+ */
+public class RegexPropertyValidator extends AbstractValidator {
+
+    /** Regular expression for validating the value. */
+    private final String regEx;
+
+    private boolean warningOnly;
+
+    private boolean validateAll;
+
+    /**
+     * Creates a new validator.
+     * @param regEx the regular expression to check.
+     * @param validateAll true, if all property values provided should be validated.
+     * @param warningOnly if activated only warning will be generated.
+     * @param key the property key
+     * @param description a description of the check.
+     */
+    public RegexPropertyValidator(String key, String regEx, boolean validateAll, boolean warningOnly, String description) {
+        super(key, false, description);
+        this.regEx = Objects.requireNonNull(regEx);
+        this.validateAll = validateAll;
+        this.warningOnly = warningOnly;
+    }
+
+    /**
+     * Creates a new validator.
+     * @param regEx the regular expression to check.
+     * @param key the property key
+     * @param description a description of the check.
+     */
+    public RegexPropertyValidator(String key, String regEx, String description) {
+        super(key, false, description);
+        this.regEx = Objects.requireNonNull(regEx);
+    }
+
+
+    @Override
+    protected void validateValues(List<PropertyValue> configValues, List<ValidationCheck> result) {
+        if (configValues.isEmpty() && isRequired()) {
+            result.add(ValidationCheck.createMissing(this, "Missing key: " + getKey()));
+        }
+        String baseText = getDescription();
+        if(baseText==null){
+            baseText = "Validation failure for property '" + getKey() + "': ";
+        }else{
+            baseText = baseText + " Validation failure: ";
+        }
+        if (regEx != null) {
+            for(PropertyValue value:configValues) {
+                if (!value.getValue().matches(regEx)) {
+                    if(warningOnly){
+                        result.add(ValidationCheck.createWarning(this, baseText + " Value not matching expression: " + regEx + ", was " +
+                                configValues.get(0).getValue()));
+                    }else {
+                        result.add(ValidationCheck.createError(this, baseText + " Value not matching expression: " + regEx + ", was " +
+                                configValues.get(0).getValue()));
+                    }
+                }
+                if(!validateAll){
+                    break;
+                }
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder();
+        b.append(getClass().getSimpleName()).append("{\n");
+        b.append("  key       : ").append(getKey()).append('\n');
+        b.append("  required  : ").append(isRequired()).append('\n');
+        b.append("  expression: ").append(regEx).append("\n}\n");
+        return b.toString();
+    }
+
+}
diff --git a/validation/src/main/java/org/apache/tamaya/validation/spi/SectionModel.java b/validation/src/main/java/org/apache/tamaya/validation/spi/SectionModel.java
deleted file mode 100644
index 79ee50e..0000000
--- a/validation/src/main/java/org/apache/tamaya/validation/spi/SectionModel.java
+++ /dev/null
@@ -1,202 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.spi;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.validation.ConfigModel;
-import org.apache.tamaya.validation.ModelTarget;
-import org.apache.tamaya.validation.Validation;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Default configuration Model for a configuration section.
- */
-public class SectionModel extends GroupModel {
-
-    /**
-     * Creates a new builder.
-     * @param owner owner, not null.
-     * @param name the section name.
-     * @return a new builder instance.
-     */
-    public static Builder builder(String owner, String name){
-        return new Builder(owner, name);
-    }
-
-    /**
-     * Creates a section validation for the given section.
-     * @param owner owner, not null.
-     * @param name the fully qualified section name
-     * @param required flag, if the section is required to be present.
-     * @return the ConfigModel instance
-     */
-    public static ConfigModel of(String owner, String name, boolean required){
-        return new Builder(owner, name).setRequired(required).build();
-    }
-
-    /**
-     * Creates a section validation for the given section.
-     * @param owner owner, not null.
-     * @param name the fully qualified section name
-     * @param required flag, if the section is required to be present.
-     * @param configModels additional configModels
-     * @return a new builder, never null.
-     */
-    public static ConfigModel of(String owner, String name, boolean required, ConfigModel... configModels){
-        return new Builder(owner, name).setRequired(required).addValidations(configModels).build();
-    }
-
-    /**
-     * Internal constructor.
-     * @param builder the builder, not null.
-     */
-    protected SectionModel(Builder builder) {
-        super(builder.owner, builder.name, builder.childConfigModels);
-    }
-
-    @Override
-    public ModelTarget getType(){
-        return ModelTarget.Section;
-    }
-
-    @Override
-    public Collection<Validation> validate(Configuration config) {
-        Map<String,String> map = config.getProperties();
-        String lookupKey = getName() + '.';
-        boolean present = false;
-        for(String key:map.keySet()){
-            if(key.startsWith("_")){
-                continue;
-            }
-            if(key.startsWith(lookupKey)){
-                present = true;
-                break;
-            }
-        }
-        List<Validation> result = new ArrayList<>(1);
-        if(isRequired() && !present) {
-            result.add(Validation.createMissing(this));
-        }
-        result.addAll(super.validate(config));
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder b = new StringBuilder();
-        b.append(getType()).append(": ").append(getName());
-        if(isRequired()) {
-            b.append(", required: " ).append(isRequired());
-        }
-        for(ConfigModel val:getValidations()){
-             b.append(", ").append(val.toString());
-        }
-        return b.toString();
-    }
-
-    /**
-     * Builder for setting up a AreaConfigModel instance.
-     */
-    public static class Builder{
-        /** The section owner. */
-        private String owner;
-        /** The section name. */
-        private String name;
-        /** The optional description. */
-        private String description;
-        /** The required flag. */
-        private boolean required;
-        /** The (optional) custom validations.*/
-        private final List<ConfigModel> childConfigModels = new ArrayList<>();
-
-        /**
-         * Creates a new Builder.
-         * @param owner owner, not null.
-         * @param sectionName the section name, not null.
-         */
-        public Builder(String owner, String sectionName){
-            this.owner = Objects.requireNonNull(owner);
-            this.name = Objects.requireNonNull(sectionName);
-        }
-
-        /**
-         * Add configModels.
-         * @param configModels the configModels, not null.
-         * @return the Builder for chaining.
-         */
-        public Builder addValidations(ConfigModel... configModels){
-            this.childConfigModels.addAll(Arrays.asList(configModels));
-            return this;
-        }
-
-        /**
-         * Add configModels.
-         * @param configModels the configModels, not null.
-         * @return the Builder for chaining.
-         */
-        public Builder addValidations(Collection<ConfigModel> configModels){
-            this.childConfigModels.addAll(configModels);
-            return this;
-        }
-
-        /**
-         * Sets the required flag.
-         * @param required zhe flag.
-         * @return the Builder for chaining.
-         */
-        public Builder setRequired(boolean required){
-            this.required = required;
-            return this;
-        }
-
-        /**
-         * Set the )optional) description.
-         * @param description the description.
-         * @return the Builder for chaining.
-         */
-        public Builder setDescription(String description){
-            this.description = description;
-            return this;
-        }
-
-        /**
-         * Set the section name
-         * @param name the section name, not null.
-         * @return the Builder for chaining.
-         */
-        public Builder setName(String name){
-            this.name = Objects.requireNonNull(name);
-            return this;
-        }
-
-        /**
-         * Build a new ConfigModel instance.
-         * @return the new ConfigModel instance, not null.
-         */
-        public ConfigModel build(){
-            return new SectionModel(this);
-        }
-    }
-}
diff --git a/validation/src/test/java/org/apache/tamaya/validation/ConfigModelProviderTest.java b/validation/src/test/java/org/apache/tamaya/validation/ConfigModelProviderTest.java
deleted file mode 100644
index 8edf50d..0000000
--- a/validation/src/test/java/org/apache/tamaya/validation/ConfigModelProviderTest.java
+++ /dev/null
@@ -1,68 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation;
-
-import org.apache.tamaya.validation.spi.SectionModel;
-import org.apache.tamaya.validation.spi.ParameterModel;
-import org.apache.tamaya.validation.spi.GroupModel;
-import org.apache.tamaya.validation.spi.ModelProviderSpi;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-
-/**
- * Created by Anatole on 09.08.2015.
- */
-public class ConfigModelProviderTest implements ModelProviderSpi {
-
-    private List<ConfigModel> configModels = new ArrayList<>(1);
-
-    public ConfigModelProviderTest(){
-        configModels.add(new TestConfigModel());
-        configModels = Collections.unmodifiableList(configModels);
-    }
-
-    public Collection<ConfigModel> getConfigModels() {
-        return configModels;
-    }
-
-    private static final class TestConfigModel extends GroupModel {
-
-        public TestConfigModel(){
-            super("TestConfigModel", "TestConfig", new SectionModel.Builder("TestConfigModel",
-                    "a.test.existing").setRequired(true).build(),
-                    ParameterModel.of("TestConfigModel", "a.test.existing.aParam", true),
-                    ParameterModel.of("TestConfigModel", "a.test.existing.optionalParam"),
-                    ParameterModel.of("TestConfigModel", "a.test.existing.aABCParam", false, "[ABC].*"),
-                    new SectionModel.Builder("TestConfigModel", "a.test.notexisting").setRequired(true).build(),
-                    ParameterModel.of("TestConfigModel", "a.test.notexisting.aParam", true),
-                    ParameterModel.of("TestConfigModel", "a.test.notexisting.optionalParam"),
-                    ParameterModel.of("TestConfigModel", "a.test.existing.aABCParam2", false, "[ABC].*"));
-        }
-        @Override
-        public String getName() {
-            return "TestConfigConfigModel";
-        }
-
-    }
-
-}
diff --git a/validation/src/test/java/org/apache/tamaya/validation/ValidationTests.java b/validation/src/test/java/org/apache/tamaya/validation/ValidationTests.java
deleted file mode 100644
index bca328c..0000000
--- a/validation/src/test/java/org/apache/tamaya/validation/ValidationTests.java
+++ /dev/null
@@ -1,53 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation;
-
-import org.apache.tamaya.Configuration;
-import org.junit.Test;
-
-/**
- * Created by Anatole on 10.08.2015.
- */
-public class ValidationTests {
-
-    @Test
-    public void testValidate_Config(){
-        System.err.println(ConfigModelManager.validate(Configuration.current()));
-    }
-
-    @Test
-    public void testAllValidations(){
-        System.err.println(ConfigModelManager.getModels());
-    }
-
-    @Test
-    public void testConfigInfo(){
-        System.err.println(ConfigModelManager.getConfigModelDescription(ConfigModelManager.getModels()));
-    }
-
-    @Test
-    public void testValidateAll(){
-        System.err.println("Including UNDEFINED: \n" + ConfigModelManager.validate(Configuration.current(), true));
-    }
-
-    @Test
-    public void testModels(){
-        System.err.println("MODELS: " +ConfigModelManager.getModels());
-    }
-}
diff --git a/validation/src/test/java/org/apache/tamaya/validation/internal/ConfigDocumentationBeanTest.java b/validation/src/test/java/org/apache/tamaya/validation/internal/ConfigDocumentationBeanTest.java
deleted file mode 100644
index b6a1203..0000000
--- a/validation/src/test/java/org/apache/tamaya/validation/internal/ConfigDocumentationBeanTest.java
+++ /dev/null
@@ -1,108 +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 createObject the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.tamaya.validation.internal;
-
-import org.apache.tamaya.validation.ModelTarget;
-import org.junit.Test;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Created by Anatole on 19.08.2015.
- */
-public class ConfigDocumentationBeanTest {
-
-    private final ConfigDocumentationBean mbean = new ConfigDocumentationBean();
-
-    @Test
-    public void testValidate_NoUnknowns() throws Exception {
-        String results = mbean.validate(false);
-        assertNotNull(results);
-        assertFalse(results.trim().isEmpty());
-        assertTrue(results.contains("\"target\":\"Parameter\""));
-        assertTrue(results.contains("\"result\":\"MISSING\""));
-        assertFalse(results.contains("\"description\":\"Undefined key: "));
-        assertFalse(results.contains(" \"result\":\"UNDEFINED\""));
-    }
-
-    @Test
-    public void testValidate_WithUnknowns() throws Exception {
-        String results = mbean.validate(true);
-        assertNotNull(results);
-        assertFalse(results.trim().isEmpty());
-        // test transitive excludes createObject default sys properties
-        assertFalse(results.contains("\"name\":\"java"));
-        assertFalse(results.contains("\"name\":\"sun."));
-        assertFalse(results.contains("\"name\":\"file."));
-        // test others
-        assertTrue(results.contains("\"target\":\"Parameter\""));
-        assertTrue(results.contains("\"target\":\"Section\""));
-        assertTrue(results.contains("\"result\":\"MISSING\""));
-        assertTrue(results.contains("\"description\":\"Undefined key: "));
-        assertTrue(results.contains(" \"result\":\"UNDEFINED\""));
-    }
-
-    @Test
-    public void testGetConfigurationModel() throws Exception {
-        String results = mbean.getConfigurationModel();
-        assertNotNull(results);
-        assertFalse(results.trim().isEmpty());
-        assertTrue(results.contains("\"target\":\"Parameter\""));
-        assertTrue(results.contains("\"name\":\"MyNumber\""));
-        assertTrue(results.contains("\"name\":\"a.b.c\""));
-        assertTrue(results.contains("\"required\":true"));
-    }
-
-    @Test
-    public void testGetConfigurationModel_WithSection() throws Exception {
-        String results = mbean.getConfigurationModel(ModelTarget.Parameter);
-        assertNotNull(results);
-        assertFalse(results.trim().isEmpty());
-        assertTrue(results.contains("\"target\":\"Parameter\""));
-        assertFalse(results.contains("\"target\":\"Section\""));
-        assertTrue(results.contains("\"required\":true"));
-    }
-
-    @Test
-    public void testFindConfigurationModels() throws Exception {
-        String results = mbean.findConfigurationModels("a");
-        assertNotNull(results);
-        assertFalse(results.trim().isEmpty());
-        assertFalse(results.contains("\"target\":\"Parameter\""));
-        assertTrue(results.contains("\"target\":\"Section\""));
-    }
-
-    @Test
-    public void testFindValidationModels() throws Exception {
-        String results = mbean.findValidationModels("a", ModelTarget.Section);
-        assertNotNull(results);
-        assertFalse(results.trim().isEmpty());
-        assertFalse(results.contains("\"target\":\"Parameter\""));
-        assertTrue(results.contains("\"target\":\"Section\""));
-        System.out.println(results);
-    }
-
-    @Test
-    public void testToString() throws Exception {
-        String toString = mbean.toString();
-        System.out.println(toString);
-    }
-}
\ No newline at end of file
diff --git a/validation/src/test/java/test/model/TestConfigAccessor.java b/validation/src/test/java/test/model/TestConfigAccessor.java
deleted file mode 100644
index 6ccc6fe..0000000
--- a/validation/src/test/java/test/model/TestConfigAccessor.java
+++ /dev/null
@@ -1,45 +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 createObject the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package test.model;
-
-import org.apache.tamaya.Configuration;
-import org.apache.tamaya.ConfigurationProvider;
-
-import java.util.Map;
-
-/**
- * Created by atsticks on 30.04.16.
- */
-public final class TestConfigAccessor {
-
-    private TestConfigAccessor(){}
-
-    public static Map<String,String> readAllProperties(){
-        return Configuration.current()
-                .getProperties();
-    }
-
-    public static Configuration readConfiguration(){
-        return Configuration.current();
-    }
-
-    public static String readProperty(Configuration config, String key){
-        return config.get(key);
-    }
-}