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

[05/10] incubator-tamaya-sandbox git commit: TAMAYA-182: Adapted modules to new builder patter changes, including tests. Fixed compile errors, or excluded modules from compilation (see root pom).

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
----------------------------------------------------------------------
diff --git a/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java b/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
deleted file mode 100644
index 23e73c0..0000000
--- a/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/ServiceContainer.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tamaya.clsupport;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.ref.WeakReference;
-import java.net.URL;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceConfigurationError;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Classloader managed ServiceContainer.
- */
-class ServiceContainer {
-
-    private static final Logger LOG = Logger.getLogger(ServiceContainer.class.getName());
-
-    private static final String PREFIX = "META-INF/services/";
-
-    // The access control context taken when the ServiceLoader is created
-    private final AccessControlContext acc;
-
-    private final WeakReference<ClassLoader> classLoaderRef;
-
-    /**
-     * List current services loaded using this classloader, per class.
-     */
-    private final Map<Class<?>, Map<String, Object>> servicesLoaded = new ConcurrentHashMap<>();
-    /**
-     * The cached singletons for the given classloader.
-     */
-    private final Map<Class, Object> singletons = new ConcurrentHashMap<>();
-
-    /**
-     * List current services loaded using this classloader, per class.
-     */
-    private final Map<Class, List<URL>> configsLoaded = new ConcurrentHashMap<>();
-
-    ServiceContainer(ClassLoader classLoader) {
-        acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
-        this.classLoaderRef = new WeakReference<>(classLoader);
-    }
-
-    public ClassLoader getClassLoader() {
-        ClassLoader cl = classLoaderRef.get();
-        if (cl == null) {
-            throw new IllegalStateException("Classloader reference removed, not active anynire.");
-        }
-        return cl;
-    }
-
-
-    public <T> void loadServices(Class<?> type,
-                                 Collection<ServiceContainer> preceedingContainers) {
-        Map<String, Object> services = this.servicesLoaded.get(type);
-        if (services == null) {
-            services = new LinkedHashMap<>();
-            this.servicesLoaded.put(type, services);
-        }
-        loop:
-        for (URL config : getConfigs(type)) {
-            for (ServiceContainer cont : preceedingContainers) {
-                if (cont.getConfigs(type).contains(config)) {
-                    LOG.finer("Ignoring already loaded config: " + config);
-                    continue loop;
-                }
-            }
-            Collection<String> serviceNames = parse(type, config);
-            for (String s : serviceNames) {
-                for (ServiceContainer cont : preceedingContainers) {
-                    if (cont.containsService(type, s)) {
-                        LOG.finest("Ignoring duplicate service: " + s);
-                    }
-                }
-                LOG.info("Loading component: " + s);
-                services.put(s, create(type, s));
-            }
-        }
-    }
-
-    private Collection<URL> getConfigs(Class<?> type) {
-        List<URL> result = this.configsLoaded.get(type);
-        if (result == null) {
-            ClassLoader cl = this.classLoaderRef.get();
-            if (cl == null) {
-                throw new IllegalStateException("CLassLoader dereferenced already.");
-            }
-            result = new ArrayList<>();
-            try {
-                Enumeration<URL> resources = cl.getResources(PREFIX + type.getName());
-                while (resources.hasMoreElements()) {
-                    result.add(resources.nextElement());
-                }
-            } catch (Exception e) {
-                LOG.log(Level.WARNING, "Failed to read service config for " + type.getName() + " from " + cl, e);
-            }
-            this.configsLoaded.put(type, result);
-            LOG.log(Level.FINE, "Found service config for " + type.getName() + ": " + result);
-        }
-        return result;
-    }
-
-    private boolean containsService(Class<?> type, String serviceClassName) {
-        Map<String, Object> services = servicesLoaded.get(type);
-        return services != null && services.containsKey(serviceClassName);
-    }
-
-
-    private <S> S create(Class<S> serviceType, String className) {
-        Class<?> c = null;
-        ClassLoader classLoader = getClassLoader();
-        try {
-            c = Class.forName(className, false, classLoader);
-        } catch (ClassNotFoundException x) {
-            fail(serviceType,
-                    "Provider " + className + " not found");
-        }
-        if (!serviceType.isAssignableFrom(c)) {
-            fail(serviceType,
-                    "Provider " + className + " not a subtype");
-        }
-        try {
-            return serviceType.cast(c.newInstance());
-        } catch (Throwable x) {
-            fail(serviceType,
-                    "Provider " + className + " could not be instantiated",
-                    x);
-        }
-        throw new Error();          // This cannot happen
-    }
-
-    public <T> Collection<T> getServices(Class<T> serviceType) {
-        Map<String, Object> services = this.servicesLoaded.get(serviceType);
-        if (services != null) {
-            return (Collection<T>) services.values();
-        }
-        return Collections.emptySet();
-    }
-
-    public boolean isTypeLoaded(Class<?> serviceType) {
-        return this.servicesLoaded.containsKey(serviceType);
-    }
-
-    public Collection<URL> load(Class<?> serviceType) {
-        return load(serviceType, Collection.class.cast(Collections.emptySet()));
-    }
-
-    public Collection<URL> load(Class<?> serviceType, Collection<URL> configsLoaded) {
-        List<URL> result = new ArrayList<>();
-        try {
-            Enumeration<URL> resources = getClassLoader().getResources(PREFIX + serviceType.getName());
-            while (resources.hasMoreElements()) {
-                URL res = resources.nextElement();
-                if (!configsLoaded.contains(res)) {
-                    result.add(res);
-                }
-            }
-            return result;
-        } catch (Exception e) {
-            fail(serviceType, "Failed to load service config: " + PREFIX + serviceType.getName(), e);
-        }
-        return result;
-    }
-
-
-    // Parse a single line from the given configuration file, adding the name
-    // on the line to the names list.
-    //
-    private int parseLine(Class<?> serviceType, URL u, BufferedReader r, int lc,
-                          List<String> names)
-            throws IOException, ServiceConfigurationError {
-        String ln = r.readLine();
-        if (ln == null) {
-            return -1;
-        }
-        int ci = ln.indexOf('#');
-        if (ci >= 0) {
-            ln = ln.substring(0, ci);
-        }
-        ln = ln.trim();
-        int n = ln.length();
-        if (n != 0) {
-            if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
-                fail(serviceType, u, lc, "Illegal configuration-file syntax");
-            }
-            int cp = ln.codePointAt(0);
-            if (!Character.isJavaIdentifierStart(cp)) {
-                fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
-            }
-            for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
-                cp = ln.codePointAt(i);
-                if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
-                    fail(serviceType, u, lc, "Illegal provider-class name: " + ln);
-                }
-            }
-            Map<String, Object> services = this.servicesLoaded.get(serviceType);
-            if (services == null || !services.containsKey(ln) && !names.contains(ln)) {
-                names.add(ln);
-            }
-        }
-        return lc + 1;
-    }
-
-
-    // Parse the content of the given URL as a provider-configuration file.
-    //
-    // @param  service
-    //         The service type for which providers are being sought;
-    //         used to construct error detail strings
-    //
-    // @param  u
-    //         The URL naming the configuration file to be parsed
-    //
-    // @return A (possibly empty) iterator that will yield the provider-class
-    //         names in the given configuration file that are not yet members
-    //         of the returned set
-    //
-    // @throws ServiceConfigurationError
-    //         If an I/O error occurs while reading from the given URL, or
-    //         if a configuration-file format error is detected
-    //
-    private Collection<String> parse(Class<?> service, URL u)
-            throws ServiceConfigurationError {
-        InputStream in = null;
-        BufferedReader r = null;
-        ArrayList<String> names = new ArrayList<>();
-        try {
-            in = u.openStream();
-            r = new BufferedReader(new InputStreamReader(in, "utf-8"));
-            int lc = 1;
-            while ((lc = parseLine(service, u, r, lc, names)) >= 0) {
-                // go ahead
-            }
-        } catch (IOException x) {
-            fail(service, "Error reading configuration file", x);
-        } finally {
-            try {
-                if (r != null) {
-                    r.close();
-                }
-                if (in != null) {
-                    in.close();
-                }
-            } catch (IOException y) {
-                fail(service, "Error closing configuration file", y);
-            }
-        }
-        return names;
-    }
-
-
-    private static void fail(Class<?> service, String msg, Throwable cause)
-            throws ServiceConfigurationError {
-        LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg, cause);
-    }
-
-    private static void fail(Class<?> service, String msg)
-            throws ServiceConfigurationError {
-        LOG.log(Level.SEVERE, "Failed to load: " + service.getName() + ": " + msg);
-    }
-
-    private static void fail(Class<?> service, URL u, int line, String msg)
-            throws ServiceConfigurationError {
-        fail(service, u + ":" + line + ": " + msg);
-    }
-
-    public <T> T getSingleton(Class<T> serviceType) {
-        return (T) this.singletons.get(serviceType);
-    }
-
-    <T> void setSingleton(Class<T> type, T instance) {
-        LOG.info("Caching singleton for " + type.getName() + " and classloader: " +
-                getClassLoader().toString() + ": " + instance);
-        this.singletons.put(type, instance);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/package-info.java
----------------------------------------------------------------------
diff --git a/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/package-info.java b/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/package-info.java
deleted file mode 100644
index d8e3953..0000000
--- a/tamaya-classloader-support/src/main/java/org/apache/tamaya/clsupport/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * Programmatic API of the classloader support.
- */
-package org.apache.tamaya.clsupport;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/tamaya-classloader-support/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/tamaya-classloader-support/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
deleted file mode 100644
index 7016afb..0000000
--- a/tamaya-classloader-support/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy current the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-org.apache.tamaya.clsupport.CLAwareServiceContext

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
----------------------------------------------------------------------
diff --git a/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi b/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
deleted file mode 100644
index 7f71c15..0000000
--- a/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextProviderSpi
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy current the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-org.apache.tamaya.environment.internal.ClassLoaderDependentAppEnvironmentProvider
-org.apache.tamaya.environment.internal.ClassLoaderDependentEarEnvironmentProvider
-org.apache.tamaya.environment.internal.InitialEnvironmentProviderSpi
-org.apache.tamaya.environment.internal.SystemClassLoaderEnvironmentProviderSpi
-org.apache.tamaya.metamodel.environment.TestEnvironmentProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
----------------------------------------------------------------------
diff --git a/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi b/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
deleted file mode 100644
index 166dd67..0000000
--- a/tamaya-classloader-support/src/test/resources/META-INF/services/org.apache.tamaya.environment.spi.ContextSpi
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy current the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-org.apache.tamaya.environment.internal.SingleEnvironmentManager

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/ui/base/pom.xml
----------------------------------------------------------------------
diff --git a/ui/base/pom.xml b/ui/base/pom.xml
index 588e8b9..075ebb5 100644
--- a/ui/base/pom.xml
+++ b/ui/base/pom.xml
@@ -23,7 +23,7 @@ under the License.
 
     <parent>
         <groupId>org.apache.tamaya.ext</groupId>
-        <artifactId>tamaya-ui</artifactId>
+        <artifactId>tamaya-ui-parent</artifactId>
         <version>0.3-incubating-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/ui/mutableconfig/pom.xml
----------------------------------------------------------------------
diff --git a/ui/mutableconfig/pom.xml b/ui/mutableconfig/pom.xml
index 8a94150..e05359f 100644
--- a/ui/mutableconfig/pom.xml
+++ b/ui/mutableconfig/pom.xml
@@ -23,7 +23,7 @@ under the License.
 
     <parent>
         <groupId>org.apache.tamaya.ext</groupId>
-        <artifactId>tamaya-ui</artifactId>
+        <artifactId>tamaya-ui-parent</artifactId>
         <version>0.3-incubating-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/pom.xml
----------------------------------------------------------------------
diff --git a/usagetracker/pom.xml b/usagetracker/pom.xml
new file mode 100644
index 0000000..371990c
--- /dev/null
+++ b/usagetracker/pom.xml
@@ -0,0 +1,113 @@
+<!-- 
+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.3-incubating-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <artifactId>tamaya-usagetracker</artifactId>
+    <name>Apache Tamaya Modules - Usage tracker</name>
+    <description>This extension module provides functionality to measure configuration
+        usage during runtime.
+    </description>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <jdkVersion>1.7</jdkVersion>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-core</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-injection-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-events</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-json</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.johnzon</groupId>
+            <artifactId>johnzon-core</artifactId>
+            <version>0.9-incubating</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>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.apache.tamaya.model,
+                            org.apache.tamaya.model.spi
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.tamaya.model.internal
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/ConfigUsage.java
----------------------------------------------------------------------
diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/ConfigUsage.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/ConfigUsage.java
new file mode 100644
index 0000000..3d10e80
--- /dev/null
+++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/ConfigUsage.java
@@ -0,0 +1,129 @@
+/*
+ * 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.usagetracker;
+
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.usagetracker.spi.ConfigUsageSpi;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * Validator accessor to validate the current configuration.
+ */
+public final class ConfigUsage {
+
+    /** The logger used. */
+    private static final Logger LOG = Logger.getLogger(ConfigUsage.class.getName());
+    private static final String NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE = "No UsageTrackerSpi component available.";
+
+    /** The loaded usage tracking SPI. */
+    private static ConfigUsageSpi usageTracker = ServiceContextManager
+            .getServiceContext().getService(ConfigUsageSpi.class);
+
+    /**
+     * Singleton constructor.
+     */
+    private ConfigUsage() {
+    }
+
+    /**
+     * Returns a set of package names that are to be ignored when collecting usage data.
+     * @return the ignored package names, not null.
+     */
+    public static Set<String> getIgnoredUsagePackages(){
+        return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE)
+                .getIgnoredPackages();
+    }
+
+    /**
+     * Adds the given packageNames to the list of packages to be ignored when collecting usage data.
+     * @param packageName the package names to be added, not null.
+     */
+    public static void addIgnoredUsagePackages(String... packageName){
+        Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE)
+                .addIgnoredUsagePackages(packageName);
+    }
+
+    /**
+     * Enables/disables usage tracking.
+     * @param enabled set to true to enable usage tracking.
+     */
+    public static void enableUsageTracking(boolean enabled){
+        Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE)
+                .enableUsageTracking(enabled);
+    }
+
+    /**
+     * Access the usage statistics for a given key. If usage stats collection is not
+     * activated (default), this method returns null.
+     * @param key the fully qualified configuration key, not null.
+     * @return the stats collected, or null.
+     */
+    public static UsageStat getUsage(String key){
+        return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE)
+                .getUsage(key);
+    }
+
+    /**
+     * Get the recorded usage references of configuration.
+     * @return the recorded usge references, never null.
+     */
+    public static Collection<UsageStat> getUsages() {
+        return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE).getUsages();
+    }
+
+    /**
+     * Clears all collected usage statistics.
+     */
+    public static void clearUsageStats() {
+        Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE)
+                .clearUsageStats();
+    }
+
+    /**
+     * Access the usage statistics for accessing {@link org.apache.tamaya.Configuration#getProperties()}.
+     * If usage stats collection is not activated (default), this method returns null.
+     * @return the stats collected, or null.
+     */
+    public static UsageStat getUsageAllProperties(){
+        return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE)
+                .getUsageAllProperties();
+    }
+
+    /**
+     * Allows to check if usage tracking is enabled (should be disbled by default).
+     * @return true, if usage tracking is enabled.
+     */
+    public static boolean isUsageTrackingEnabled(){
+        return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE)
+                .isUsageTrackingEnabled();
+    }
+
+    /**
+     * Access the usage statistics for the recorded uses of configuration.
+     * @return usage info or default message.
+     */
+    public static String getUsageInfo(){
+        return Objects.requireNonNull(usageTracker, NO_USAGE_TRACKER_SPI_COMPONENT_MESSAGE).getUsageInfo();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java
----------------------------------------------------------------------
diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java
new file mode 100644
index 0000000..6161644
--- /dev/null
+++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/UsageStat.java
@@ -0,0 +1,312 @@
+/*
+ * 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.usagetracker;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.logging.Logger;
+
+/**
+ * Metrics container containing access statistics for a given configuration key.
+ */
+public final class UsageStat {
+    private static final Logger LOG = Logger.getLogger(UsageStat.class.getName());
+    private static final String[] EMPTY_TRACE = new String[0];
+    /**
+     * the config section.
+     */
+    private final String key;
+
+    /**
+     * Maps with usage references, key is the fully qualified package name.
+     */
+    private final Map<String,AccessDetail> accessDetails = new ConcurrentHashMap<>();
+    /**
+     * The maximal length of the stacktrace stored.
+     */
+    private static int maxTrace = 10;
+
+    /**
+     * Creates a usage metric container for a given key.
+     * @param key the parameter (fully qualified).
+     */
+    public UsageStat(String key) {
+        this.key = Objects.requireNonNull(key);
+    }
+
+    /**
+     * Get the maximal length of the stack traces recorded, default is 10.
+     * @return the maximal length of the stack traces recorded
+     */
+    public static int getMaxTraceLength(){
+        return UsageStat.maxTrace;
+    }
+
+    /**
+     * Sets the maximal length of the stacktraces stored when tracking configuration
+     * usage. Setting it to a negative value, disabled stacktrace logging.
+     * @param maxTrace the maximal recorded stack length.
+     */
+    public static void setMaxTraceLength(int maxTrace){
+        UsageStat.maxTrace =maxTrace;
+    }
+
+    /**
+     * Get the configModel section.
+     *
+     * @return the section, never null.
+     */
+    public String getKey() {
+        return key;
+    }
+
+    /**
+     * Clears all collected usage metrics for this key.
+     */
+    public void clearMetrics(){
+        this.accessDetails.clear();
+    }
+
+    /**
+     * Get the detail message.
+     *
+     * @return the detail message, or null.
+     */
+    public int getReferenceCount() {
+        return accessDetails.size();
+    }
+
+    /**
+     * Get the detail message.
+     *
+     * @return the detail message, or null.
+     */
+    public int getUsageCount() {
+        int count = 0;
+        for(AccessDetail ref: accessDetails.values()){
+            count += ref.getAccessCount();
+        }
+        return count;
+    }
+
+    /**
+     * Access a usage reference for a given class.
+     * @param type class to get usage references for, not null.
+     * @return the usage ref, if present, or null.
+     */
+    public Collection<AccessDetail> getAccessDetails(Class type){
+        return getAccessDetails(type.getName() +"\\..*");
+    }
+
+    /**
+     * Access a usage reference for a given package.
+     * @param pack package to get usage references for, not null.
+     * @return the usage ref, if present, or null.
+     */
+    public Collection<AccessDetail> getAccessDetails(Package pack){
+        return getAccessDetails(pack.getName() +"\\..*");
+    }
+
+    /**
+     * Find usages of this key for the given expression (regex). Hereby the expression is
+     * matched with the tracked reference identifier, which has the form
+     * {@code f.q.n.ClassName#methodName(line: 123)}.
+     * @param lookupExpression the target lookup expression, not null.
+     * @return the matching references, not null.
+     */
+    public Collection<AccessDetail> getAccessDetails(String lookupExpression){
+        List<AccessDetail> result = new ArrayList<>();
+        for(AccessDetail ref:this.accessDetails.values()){
+            if(ref.getAccessPoint().matches(lookupExpression)){
+                result.add(ref);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Usage Count: " + key + " -> " + getUsageCount() + '\n';
+    }
+
+    /**
+     * Get the access details (stacktrace etc) for this reference.
+     * @return return the access details, not null.
+     */
+    public Collection<AccessDetail> getAccessDetails(){
+        return Collections.unmodifiableCollection(accessDetails.values());
+    }
+
+    /**
+     * Evaluates the current access point from the current stacktrace and adds an according
+     * usage reference object (or updates any existing one) for the given key. The
+     * stacktrace is shortened to a maximal size of 20 items.
+     * @param value the value returned, not null.
+     */
+    public void trackUsage(String value){
+        trackUsage(value, maxTrace);
+    }
+
+    /**
+     * Evaluates the current access point from the current stacktrace and adds an according
+     * usage reference object (or updates any existing one) for the given key.
+     * @param value the value returned, not null.
+     * @param maxTraceLength the maximal length of the stored stacktrace.
+     */
+    public void trackUsage(String value, int maxTraceLength){
+        String accessPoint = null;
+        if(maxTraceLength>0) {
+            Exception e = new Exception();
+            List<String> trace = new ArrayList<>();
+            stack:
+            for (StackTraceElement ste : e.getStackTrace()) {
+                for (String ignored : ConfigUsage.getIgnoredUsagePackages()) {
+                    if (ste.getClassName().startsWith(ignored)) {
+                        continue stack;
+                    }
+                }
+                String ref = ste.getClassName() + '#' + ste.getMethodName() + "(line:" + ste.getLineNumber() + ')';
+                trace.add(ref);
+                if (accessPoint == null) {
+                    accessPoint = ref;
+                }
+                if (trace.size() >= maxTraceLength) {
+                    break;
+                }
+            }
+            if (accessPoint == null) {
+                // all ignored, take first one, with different package
+                accessPoint = "<unknown/filtered/internal>";
+            }
+            AccessDetail details = getAccessDetails(accessPoint, trace.toArray(new String[trace.size()]));
+            details.trackAccess(value);
+        }else{
+            accessPoint = "<disabled>";
+            AccessDetail details = getAccessDetails(accessPoint, EMPTY_TRACE);
+            details.trackAccess(value);
+        }
+    }
+
+    private AccessDetail getAccessDetails(String accessPoint, String[] trace) {
+        AccessDetail details = accessDetails.get(accessPoint);
+        if(details==null){
+            details = new AccessDetail(key, accessPoint, trace);
+            accessDetails.put(accessPoint, details);
+        }
+        return details;
+    }
+
+    /**
+     * Class modelling the access details tracked per detailed item, e.g. per class in the owning package.
+     */
+    public static final class AccessDetail {
+        private String key;
+        private AtomicLong accessCount = new AtomicLong();
+        private long lastAccessTS;
+        private long firstAccessTS;
+        private String[] stackTrace;
+        private String accessPoint;
+        private Map<Long, String> trackedValues;
+
+        public AccessDetail(String key, String accessPoint, String[] stackTrace){
+            this.key = Objects.requireNonNull(key);
+            this.accessPoint = Objects.requireNonNull(accessPoint);
+            this.stackTrace = stackTrace.clone();
+        }
+
+        public void clearStats(){
+            lastAccessTS = 0;
+            firstAccessTS = 0;
+            accessCount.set(0);
+        }
+
+        public long trackAccess(String value){
+            long count = accessCount.incrementAndGet();
+            lastAccessTS = System.currentTimeMillis();
+            if(firstAccessTS==0){
+                firstAccessTS = lastAccessTS;
+            }
+            if(value!=null){
+                synchronized (this) {
+                    if(trackedValues==null){
+                        trackedValues = new HashMap<>();
+                    }
+                    trackedValues.put(lastAccessTS, value);
+                }
+            }
+            return count;
+        }
+
+        public String getKey(){
+            return key;
+        }
+
+        public long getAccessCount() {
+            return accessCount.get();
+        }
+
+        public String getAccessPoint() {
+            return accessPoint;
+        }
+
+        public long getFirstAccessTS() {
+            return firstAccessTS;
+        }
+
+        public long getLastAccessTS() {
+            return lastAccessTS;
+        }
+
+        public String[] getStackTrace() {
+            return stackTrace.clone();
+        }
+
+        public Map<Long, String> getTrackedValues(){
+            synchronized (this) {
+                if (trackedValues == null) {
+                    return Collections.emptyMap();
+                } else {
+                    return new HashMap<>(trackedValues);
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "AccessDetails{" +
+                    "key=" + key +
+                    ", accessCount=" + accessCount +
+                    ", lastAccessTS=" + lastAccessTS +
+                    ", firstAccessTS=" + firstAccessTS +
+                    ", stackTrace=" + Arrays.toString(stackTrace) +
+                    ", accessPoint='" + accessPoint + '\'' +
+                    ", trackedValues=" + trackedValues +
+                    '}';
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/DefaultConfigUsage.java
----------------------------------------------------------------------
diff --git a/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/DefaultConfigUsage.java b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/DefaultConfigUsage.java
new file mode 100644
index 0000000..f268cc7
--- /dev/null
+++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/DefaultConfigUsage.java
@@ -0,0 +1,176 @@
+/*
+ * 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.usagetracker.internal;
+
+import org.apache.tamaya.usagetracker.UsageStat;
+import org.apache.tamaya.usagetracker.spi.ConfigUsageSpi;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by atsticks on 29.04.16.
+ */
+public class DefaultConfigUsage implements ConfigUsageSpi {
+
+    private Set<String> ignoredPackages = new HashSet<>();
+
+    private Map<String, UsageStat> usages = new ConcurrentHashMap<>();
+
+    /** By default usage tracking is not enabled. */
+    private boolean usageTrackingEnabled = initEnabled();
+
+    /**
+     * Method that checks the 'tamaya.usage-report' system property for
+     * enabling tamaya usage reporting initially.
+     * @return {@code true} iff property is set to {@code true}
+     */
+    private boolean initEnabled() {
+        String val = System.getProperty("tamaya.usage-report");
+        if(Boolean.parseBoolean(val)){
+            return true;
+        }
+        return false;
+    }
+
+    public DefaultConfigUsage(){
+        ignoredPackages.add("com.intellij");
+        ignoredPackages.add("java");
+        ignoredPackages.add("org.junit");
+        ignoredPackages.add("junit");
+        ignoredPackages.add("javax");
+        ignoredPackages.add("sun");
+        ignoredPackages.add("oracle");
+        ignoredPackages.add("com.sun");
+        ignoredPackages.add("com.oracle");
+        ignoredPackages.add("org.apache.tamaya");
+    }
+
+    @Override
+    public void enableUsageTracking(boolean enabled){
+        this.usageTrackingEnabled = enabled;
+    }
+
+    @Override
+    public boolean isUsageTrackingEnabled(){
+        return usageTrackingEnabled;
+    }
+
+    @Override
+    public Set<String> getIgnoredPackages() {
+        return Collections.unmodifiableSet(ignoredPackages);
+    }
+
+    @Override
+    public void addIgnoredUsagePackages(String... packageName) {
+
+    }
+
+    @Override
+    public UsageStat getUsage(String key) {
+        return this.usages.get(key);
+    }
+
+    @Override
+    public UsageStat getUsageAllProperties() {
+        return this.usages.get("<<all>>");
+    }
+
+    /**
+     * Get the recorded usage references of configuration.
+     * @return the recorded usge references, never null.
+     */
+    @Override
+    public Collection<UsageStat> getUsages() {
+        return usages.values();
+    }
+
+    @Override
+    public void trackAllPropertiesAccess(){
+        trackSingleKeyAccess("<<all>>", "<not stored>");
+    }
+
+    @Override
+    public void trackSingleKeyAccess(String key, String value){
+        // Ignore meta-entries
+        if(!isUsageTrackingEnabled() || key.startsWith("_")){
+            return;
+        }
+        UsageStat usage = this.usages.get(key);
+        if(usage==null){
+            usage = new UsageStat(key);
+            this.usages.put(key, usage);
+        }
+        usage.trackUsage(value);
+    }
+
+
+    /**
+     * Access the usage statistics for the recorded uses of configuration.
+     */
+    @Override
+    public String getUsageInfo(){
+        StringBuilder b = new StringBuilder();
+        b.append("Apache Tamaya Configuration Usage Metrics\n");
+        b.append("=========================================\n");
+        b.append("DATE: ").append(new Date()).append("\n\n");
+        List<UsageStat> usages = new ArrayList<>(getUsages());
+        Collections.sort(usages, new Comparator<UsageStat>() {
+            @Override
+            public int compare(UsageStat k1, UsageStat k2) {
+                return k2.getUsageCount() - k1.getUsageCount();
+            }
+        });
+        for(UsageStat usage:usages){
+            String usageCount = String.valueOf(usage.getUsageCount());
+            b.append(usageCount);
+            b.append("       ".substring(0, 7-usageCount.length()));
+            b.append(usage.getKey()).append(":\n");
+            for(UsageStat.AccessDetail details: usage.getAccessDetails()) {
+                String accessCount = String.valueOf(details.getAccessCount());
+                    b.append("  - ").append(accessCount);
+                    b.append("      ".substring(0, 6-usageCount.length()));
+                    b.append(details.getAccessPoint());
+                    int endIndex = 50-details.getAccessPoint().length();
+                    if(endIndex<0){
+                        endIndex = 0;
+                    }
+                    b.append("                                                  ".substring(0, endIndex));
+                    b.append(",");b.append(" first=").append(new Date(details.getFirstAccessTS()))
+                            .append(",");b.append(" last=").append(new Date(details.getLastAccessTS()))
+                            .append('\n');
+            }
+        }
+        return b.toString();
+    }
+
+    @Override
+    public void clearUsageStats() {
+        this.usages.clear();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..30a643d
--- /dev/null
+++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/internal/UsageTrackerFilter.java
@@ -0,0 +1,46 @@
+/*
+ * 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.usagetracker.internal;
+
+import org.apache.tamaya.spi.FilterContext;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.ServiceContextManager;
+import org.apache.tamaya.usagetracker.spi.ConfigUsageSpi;
+
+import javax.annotation.Priority;
+
+/**
+ * Configuration filter to be applied at the end of the filter chain. This filter
+ * actually does not change the current filter value, but use the filter process
+ * to track configuration usage.
+ */
+@Priority(Integer.MAX_VALUE)
+public class UsageTrackerFilter implements PropertyFilter{
+
+    @Override
+    public String filterProperty(String value, FilterContext context) {
+            ConfigUsageSpi tracker = ServiceContextManager.getServiceContext().getService(ConfigUsageSpi.class);
+        if (context.isSinglePropertyScoped()) {
+            tracker.trackSingleKeyAccess(context.getKey(), value);
+        } else {
+            tracker.trackAllPropertiesAccess();
+        }
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..f76586c
--- /dev/null
+++ b/usagetracker/src/main/java/org/apache/tamaya/usagetracker/spi/ConfigUsageSpi.java
@@ -0,0 +1,101 @@
+/*
+ * 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.usagetracker.spi;
+
+import org.apache.tamaya.usagetracker.UsageStat;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * SPI to be implemented by the component responsible for usage tracking of
+ * configuration.
+ */
+public interface ConfigUsageSpi {
+
+    /**
+     * Enables/disables usage tracking.
+     * @param enable set to true to enable usage tracking.
+     */
+    void enableUsageTracking(boolean enable);
+
+    /**
+     * Allows to check if usage tracking is enabled (should be disbled by default).
+     * @return true, if usage tracking is enabled.
+     */
+    boolean isUsageTrackingEnabled();
+
+    /**
+     * Get the list of packages, which are not evaluated for tracking configuration access and usage statistics.
+     * @return the set of ignored package names.
+     */
+    Set<String> getIgnoredPackages();
+
+    /**
+     * Adds the given packageNames to the list of packages to be ignored when collecting usage data.
+     * @param packageName the package names to be added, not null.
+     */
+    void addIgnoredUsagePackages(String... packageName);
+
+    /**
+     * Access the usage statistics for a given key. If usage stats collection is not
+     * activated (default), this method returns null.
+     * @param key the fully qualified configuration key, not null.
+     * @return the stats collected, or null.
+     */
+    UsageStat getUsage(String key);
+
+    /**
+     * Access the usage statistics for accessing {@link org.apache.tamaya.Configuration#getProperties()}.
+     * If usage stats collection is not activated (default), this method returns null.
+     * @return the stats collected, or null.
+     */
+    UsageStat getUsageAllProperties();
+
+    /**
+     * Get the recorded usage references of configuration.
+     * @return the recorded usge references, never null.
+     */
+    Collection<UsageStat> getUsages();
+
+    /**
+     * Track the access of {@code Configuration#getProperties()} for
+     * usage statistics.
+     */
+    void trackAllPropertiesAccess();
+
+    /**
+     * Track the access of {@code Configuration#get(String)} for
+     * usage statistics.
+     * @param key key to track for
+     * @param value value to track for
+     */
+    void trackSingleKeyAccess(String key, String value);
+
+    /**
+     * Access the usage statistics for the recorded uses of configuration.
+     * @return usage statistics info
+     */
+    String getUsageInfo();
+
+    /**
+     * Clears all collected usage statistics.
+     */
+    void clearUsageStats();
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/configmodel.properties
----------------------------------------------------------------------
diff --git a/usagetracker/src/main/resources/META-INF/configmodel.properties b/usagetracker/src/main/resources/META-INF/configmodel.properties
new file mode 100644
index 0000000..3381a09
--- /dev/null
+++ b/usagetracker/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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
----------------------------------------------------------------------
diff --git a/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
new file mode 100644
index 0000000..8075703
--- /dev/null
+++ b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.events.ConfigEventListener
@@ -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.internal.ConfiguredTypeEventsModelPopulator

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
----------------------------------------------------------------------
diff --git a/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
new file mode 100644
index 0000000..b394c17
--- /dev/null
+++ b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.model.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.model.internal.ConfiguredPropertiesModelProviderSpi
+org.apache.tamaya.model.internal.ConfiguredInlineModelProviderSpi
+org.apache.tamaya.model.internal.ConfiguredResourcesModelProviderSpi
+org.apache.tamaya.model.internal.ConfiguredTypeEventsModelProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter
----------------------------------------------------------------------
diff --git a/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter
new file mode 100644
index 0000000..dee62d6
--- /dev/null
+++ b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertyFilter
@@ -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.usagetracker.internal.UsageTrackerFilter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.usagetracker.spi.ConfigUsageSpi
----------------------------------------------------------------------
diff --git a/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.usagetracker.spi.ConfigUsageSpi b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.usagetracker.spi.ConfigUsageSpi
new file mode 100644
index 0000000..2ba5789
--- /dev/null
+++ b/usagetracker/src/main/resources/META-INF/services/org.apache.tamaya.usagetracker.spi.ConfigUsageSpi
@@ -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.usagetracker.internal.DefaultConfigUsage
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/java/org/apache/tamaya/model/ConfigUsageStatsTest.java
----------------------------------------------------------------------
diff --git a/usagetracker/src/test/java/org/apache/tamaya/model/ConfigUsageStatsTest.java b/usagetracker/src/test/java/org/apache/tamaya/model/ConfigUsageStatsTest.java
new file mode 100644
index 0000000..a16a62e
--- /dev/null
+++ b/usagetracker/src/test/java/org/apache/tamaya/model/ConfigUsageStatsTest.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.model;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.usagetracker.ConfigUsage;
+import org.junit.Test;
+import test.model.TestConfigAccessor;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by Anatole on 09.08.2015.
+ */
+public class ConfigUsageStatsTest {
+
+    @Test
+    public void testUsageWhenEnabled(){
+        ConfigUsage.enableUsageTracking(true);
+        TestConfigAccessor.readConfiguration();
+        Configuration config = ConfigurationProvider.getConfiguration();
+        String info = ConfigUsage.getUsageInfo();
+        assertFalse(info.contains("java.version"));
+        assertNotNull(info);
+        config = TestConfigAccessor.readConfiguration();
+        config.getProperties();
+        TestConfigAccessor.readProperty(config, "java.locale");
+        TestConfigAccessor.readProperty(config, "java.version");
+        TestConfigAccessor.readProperty(config, "java.version");
+        config.get("java.version");
+        info = ConfigUsage.getUsageInfo();
+        System.out.println(info);
+        assertTrue(info.contains("java.version"));
+        assertNotNull(info);
+        ConfigUsage.enableUsageTracking(false);
+    }
+
+    @Test
+    public void testUsageWhenDisabled(){
+        ConfigUsage.enableUsageTracking(false);
+        ConfigUsage.clearUsageStats();
+        TestConfigAccessor.readConfiguration();
+        Configuration config = ConfigurationProvider.getConfiguration();
+        String info = ConfigUsage.getUsageInfo();
+        assertNotNull(info);
+        assertFalse(info.contains("java.version"));
+        config = TestConfigAccessor.readConfiguration();
+        config.getProperties();
+        TestConfigAccessor.readProperty(config, "java.locale");
+        TestConfigAccessor.readProperty(config, "java.version");
+        TestConfigAccessor.readProperty(config, "java.version");
+        config.get("java.version");
+        info = ConfigUsage.getUsageInfo();
+        assertFalse(info.contains("java.version"));
+        assertNotNull(info);
+        ConfigUsage.enableUsageTracking(false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/java/test/model/TestConfigAccessor.java
----------------------------------------------------------------------
diff --git a/usagetracker/src/test/java/test/model/TestConfigAccessor.java b/usagetracker/src/test/java/test/model/TestConfigAccessor.java
new file mode 100644
index 0000000..498d2b6
--- /dev/null
+++ b/usagetracker/src/test/java/test/model/TestConfigAccessor.java
@@ -0,0 +1,45 @@
+/*
+ * 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 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 ConfigurationProvider.getConfiguration()
+                .getProperties();
+    }
+
+    public static Configuration readConfiguration(){
+        return ConfigurationProvider.getConfiguration();
+    }
+
+    public static String readProperty(Configuration config, String key){
+        return config.get(key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/META-INF/configmodel.properties
----------------------------------------------------------------------
diff --git a/usagetracker/src/test/resources/META-INF/configmodel.properties b/usagetracker/src/test/resources/META-INF/configmodel.properties
new file mode 100644
index 0000000..a7956dc
--- /dev/null
+++ b/usagetracker/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 of 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 of 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
+
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/META-INF/javaconfiguration.properties
----------------------------------------------------------------------
diff --git a/usagetracker/src/test/resources/META-INF/javaconfiguration.properties b/usagetracker/src/test/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..b0b8c22
--- /dev/null
+++ b/usagetracker/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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
----------------------------------------------------------------------
diff --git a/usagetracker/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi b/usagetracker/src/test/resources/META-INF/services/org.apache.tamaya.model.spi.ModelProviderSpi
new file mode 100644
index 0000000..9b29fda
--- /dev/null
+++ b/usagetracker/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

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/examples/configmodel.ini
----------------------------------------------------------------------
diff --git a/usagetracker/src/test/resources/examples/configmodel.ini b/usagetracker/src/test/resources/examples/configmodel.ini
new file mode 100644
index 0000000..0e10cc1
--- /dev/null
+++ b/usagetracker/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
+
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/examples/configmodel.json
----------------------------------------------------------------------
diff --git a/usagetracker/src/test/resources/examples/configmodel.json b/usagetracker/src/test/resources/examples/configmodel.json
new file mode 100644
index 0000000..529f26e
--- /dev/null
+++ b/usagetracker/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 of a configuration metamodel expressed via YAML(tm).
+//  Structure is shown through indentation (one or more spaces).
+//  Sequence items are denoted by a dash,
+//  key value 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 of 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"
+    }
+  }
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/041f5998/usagetracker/src/test/resources/examples/configmodel.properties
----------------------------------------------------------------------
diff --git a/usagetracker/src/test/resources/examples/configmodel.properties b/usagetracker/src/test/resources/examples/configmodel.properties
new file mode 100644
index 0000000..b61695b
--- /dev/null
+++ b/usagetracker/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 of 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 of 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
+
+
+
+