diff --git a/common/source/java/ch/systemsx/cisd/common/utilities/ExtendedProperties.java b/common/source/java/ch/systemsx/cisd/common/utilities/ExtendedProperties.java
index cd112678b654f39d1d782113c3d2792f536ff7b4..d466dbb278398ac57a5b5b5be3ac695527531776 100644
--- a/common/source/java/ch/systemsx/cisd/common/utilities/ExtendedProperties.java
+++ b/common/source/java/ch/systemsx/cisd/common/utilities/ExtendedProperties.java
@@ -16,32 +16,53 @@
 package ch.systemsx.cisd.common.utilities;
 
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Properties;
+import java.util.Set;
+import java.util.Map.Entry;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.SystemUtils;
 
 /**
- * Another class of Properties that allows recursive references for property keys and values. For
- * example,
+ * An extension of {@link Properties}. The extension avoid duplicating properties by reusing. There
+ * are two ways to reuse properties:
+ * <ol>
+ * <li>Use properties in property values. For example,
  * 
  * <pre>
  * A=12345678
  * B=${A}90
  * C=${B} plus more
+ * </pre>
  * 
- * </code></pre>
+ * will result in <code>getProperty("C")</code> returning the value "1234567890 plus more". Cyclic
+ * references are handled by removing the current key before resolving it, i.e. when setting A=${B}
+ * and B=${A} and then asking for A, you will get ${A}.
+ * <li>Inherit properties. For example,
  * 
- * will result in <code>getProperty("C")</code> returning the value "1234567890 plus more". The
- * keys will be rewritten when queried (dynamically), thus the order of adding properties is
- * unimportant. Cyclic references are handled by removing the current key before resolving it, i.e.
- * when setting A=${B} and B=${A} and then asking for A, you will get ${A}.
+ * <pre>
+ * type.code = ALPHA
+ * type.label = Alpha
+ * validator.order = 1
+ * validator.type. = type.
+ * my.validator. = validator.
+ * my.validator.type.label = A L P H A
+ * </pre>
+ * will result in <code>getProperty("my.validator.type.code")</code> returning the value "ALPHA".
+ * All keys ending with a dot '.' should refer to a key prefix. All properties starting with 
+ * this prefix are also properties of the subtree starting with the key with the dot at the end.
+ * Inherit properties can be overridden.
+ * </ol>
  * 
  * @author Christian Ribeaud
+ * @author Franz-Josef Elmer
  */
 public final class ExtendedProperties extends Properties
 {
 
+    private static final String PATH_DELIMITER = ".";
+
     private static final long serialVersionUID = 1L;
 
     /** Usual (or default) property separator in the super class. */
@@ -74,6 +95,7 @@ public final class ExtendedProperties extends Properties
 
     /**
      * Returns a subset of given <code>Properties</code> based on given property key prefix.
+     * The subset contains also inherited properties.
      * 
      * @param prefix string, each property key should start with.
      * @param dropPrefix If <code>true</code> the prefix will be removed from the key.
@@ -88,19 +110,45 @@ public final class ExtendedProperties extends Properties
     {
         assert prefix != null : "Missing prefix";
 
+        return gs(prefix, dropPrefix, new HashSet<String>());
+    }
+
+    private ExtendedProperties gs(final String prefix, final boolean dropPrefix, Set<String> keys)
+    {
         final ExtendedProperties result = new ExtendedProperties();
         final int prefixLength = prefix.length();
         for (final Enumeration<?> enumeration = propertyNames(); enumeration.hasMoreElements(); )
         {
             final String key = enumeration.nextElement().toString();
-            if (key.startsWith(prefix))
+            if (key.startsWith(prefix) && key.endsWith(PATH_DELIMITER))
+            {
+                assertNoCyclicDependency(keys, key);
+                keys.add(key);
+                String inheritTree = super.getProperty(key);
+                for (Entry<Object, Object> entry : gs(inheritTree, true, keys).entrySet())
+                {
+                    String newKey = key.substring(0, key.length()) + entry.getKey();
+                    result.put(createKey(newKey, dropPrefix, prefixLength), entry.getValue());
+                }
+                keys.remove(key);
+            }
+        }
+        for (final Enumeration<?> enumeration = propertyNames(); enumeration.hasMoreElements(); )
+        {
+            final String key = enumeration.nextElement().toString();
+            if (key.startsWith(prefix) && key.endsWith(PATH_DELIMITER) == false)
             {
-                result.put(dropPrefix ? key.substring(prefixLength) : key, getProperty(key));
+                result.put(createKey(key, dropPrefix, prefixLength), getProperty(key));
             }
         }
         return result;
     }
 
+    private String createKey(final String key, final boolean dropPrefix, final int prefixLength)
+    {
+        return dropPrefix ? key.substring(prefixLength) : key;
+    }
+
     /**
      * Removes all properties with names starting with given prefix
      */
@@ -116,7 +164,7 @@ public final class ExtendedProperties extends Properties
         }
     }
 
-    private final String expandValue(final String key, final String value)
+    private final String expandValue(final String key, final String value, Set<String> keys)
     {
         if (value == null || value.length() < MIN_LENGTH)
         {
@@ -131,11 +179,13 @@ public final class ExtendedProperties extends Properties
         while (startName >= 0 && endName > startName)
         {
             final String paramName = result.substring(startName + prefixLen, endName);
-            // recurse into this variable, prevent cyclic references by removing the current key
-            // before asking for the property and the setting it again afterwards.
-            remove(key);
-            final String paramValue = getProperty(paramName);
-            super.setProperty(key, value);
+            String paramValue = null;
+            if (keys.contains(paramName) == false)
+            {
+                keys.add(key);
+                paramValue = getProperty(paramName, keys);
+                keys.remove(key);
+            }
             if (paramValue != null)
             {
                 result.replace(startName, endName + suffixLen, paramValue);
@@ -167,6 +217,35 @@ public final class ExtendedProperties extends Properties
     //
 
     /**
+     * Returns the value of specified property or <code>null</code> if undefined. This method 
+     * behaves differently then the same method of the superclass: 
+     * <ul>
+     * <li>
+     * If nothing found for the specified key other keys are tried as follows:
+     * For all dot characters '.' in the key (starting from the right most) it looks recursively for
+     * a replacement of the left part of the key (including the dot) among all properties.
+     * <p>
+     * Example:
+     * <pre>
+     * type.code = ALPHA
+     * type.label = Alpha
+     * validator.order = 1
+     * validator.type. = type.
+     * my.validator. = validator.
+     * my.validator.type.label = A L P H A
+     * </pre>
+     * The following table shows the returned value of <code>getProperty()</code> for various keys:
+     * <table border=1 cellspacing=1 cellpadding=5>
+     * <tr><th>Key</th><th>Value</th></tr>
+     * <tr><td>validator.order</td><td>1</td></tr>
+     * <tr><td>validator.type.code</td><td>ALPHA</td></tr>
+     * <tr><td>validator.type.label</td><td>Alpha</td></tr>
+     * <tr><td>my.validator.order</td><td>1</td></tr>
+     * <tr><td>my.validator.type.code</td><td>ALPHA</td></tr>
+     * <tr><td>my.validator.type.label</td><td>A L P H A</td></tr>
+     * </table>  
+     * This mechanism allows to inherit property values from complete subtrees of properties.
+     * <li>
      * Any parameter like <code>${propertyName}</code> in property value will be replaced with the
      * value of property with name <code>propertyName</code>.
      * <p>
@@ -183,7 +262,7 @@ public final class ExtendedProperties extends Properties
      * <pre>
      * Alphabet starts with: abcdefgh
      * </pre>
-     * 
+     * </ul>
      * </p>
      * 
      * @see java.util.Properties#getProperty(java.lang.String)
@@ -191,10 +270,46 @@ public final class ExtendedProperties extends Properties
     @Override
     public final String getProperty(final String key)
     {
-        final String result = super.getProperty(key);
-        return result == null ? null : expandValue(key, result);
+        return getProperty(key, new HashSet<String>());
+    }
+
+    private String getProperty(final String key, Set<String> keys)
+    {
+        String result = super.getProperty(key);
+        if (result == null)
+        {
+            int index = key.length();
+            while (index > 0)
+            {
+                int lastIndexOfPathDelimiter = key.lastIndexOf(PATH_DELIMITER, index);
+                if (lastIndexOfPathDelimiter >= 0)
+                {
+                    String newPath =
+                            super.getProperty(key.substring(0, lastIndexOfPathDelimiter + 1));
+                    if (newPath != null)
+                    {
+                        assertNoCyclicDependency(keys, key);
+                        keys.add(key);
+                        String newKey = newPath + key.substring(lastIndexOfPathDelimiter + 1);
+                        result = getProperty(newKey, keys);
+                        keys.remove(key);
+                        break;
+                    }
+                }
+                index = lastIndexOfPathDelimiter - 1;
+            }
+        }
+        return result == null ? null : expandValue(key, result, keys);
     }
 
+    private void assertNoCyclicDependency(Set<String> keys, final String key)
+    {
+        if (keys.contains(key))
+        {
+            throw new IllegalArgumentException("Cyclic definition of property '" + key + "'.");
+        }
+    }
+    
     /**
      * @see java.util.Properties#getProperty(java.lang.String, java.lang.String)
      */
@@ -202,7 +317,7 @@ public final class ExtendedProperties extends Properties
     public final String getProperty(final String key, final String defaultValue)
     {
         final String result = getProperty(key);
-        return result == null ? expandValue(key, defaultValue) : result;
+        return result == null ? defaultValue : result;
     }
 
     @Override
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ExtendedPropertiesTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ExtendedPropertiesTest.java
index 117fb2865ca56ab97d0a9373a0ec383f706bbc21..a2d925185a7e3d0b6e03630a4712f60e0faab28d 100644
--- a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ExtendedPropertiesTest.java
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ExtendedPropertiesTest.java
@@ -16,8 +16,9 @@
 
 package ch.systemsx.cisd.common.utilities;
 
-import static org.testng.AssertJUnit.assertEquals;
+import java.util.Properties;
 
+import org.testng.AssertJUnit;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -26,7 +27,7 @@ import org.testng.annotations.Test;
  * 
  * @author Christian Ribeaud
  */
-public final class ExtendedPropertiesTest
+public final class ExtendedPropertiesTest extends AssertJUnit
 {
     private ExtendedProperties extendedProperties;
 
@@ -38,7 +39,7 @@ public final class ExtendedPropertiesTest
         props.setProperty("un", "${one}");
         props.setProperty("two", "zwei");
         props.setProperty("three", "drei");
-        props.setProperty("four", "${one}${three}");
+        props.setProperty("four", "${un}${three}");
         extendedProperties = props;
     }
 
@@ -59,7 +60,7 @@ public final class ExtendedPropertiesTest
     {
         assertEquals("eins", extendedProperties.getProperty("one"));
         assertEquals("eins", extendedProperties.getProperty("un"));
-        assertEquals("einsdrei", extendedProperties.getProperty("four"));
+        assertEquals("einsdrei", extendedProperties.getProperty("four", "abc"));
     }
 
     @Test
@@ -116,7 +117,108 @@ public final class ExtendedPropertiesTest
     public final void testGetUnalteredProperty()
     {
         assertEquals("${one}", extendedProperties.getUnalteredProperty("un"));
-        System.out.println(extendedProperties);
+    }
+    
+    @Test
+    public final void testGetPropertyWithInheritTree()
+    {
+        Properties properties = new Properties();
+        properties.setProperty("default.code", "42");
+        properties.setProperty("type.code", "ABC-${default.code}");
+        properties.setProperty("type.label", "abc");
+        properties.setProperty("validator.order", "1");
+        properties.setProperty("validator.type.", "type.");
+        properties.setProperty("my.validator.", "validator.");
+        properties.setProperty("my.validator.order", "2");
+        properties.setProperty("my.validator.type.label", "a-b-c");
+        properties.setProperty("another.validator.", "my.validator.");
+        properties.setProperty("another.validator.type.code", "alpha-${default.code}");
+        Properties props = ExtendedProperties.createWith(properties);
+        
+        assertEquals("2", props.getProperty("my.validator.order"));
+        assertEquals("ABC-42", props.getProperty("my.validator.type.code"));
+        assertEquals("a-b-c", props.getProperty("my.validator.type.label"));
+        assertEquals("2", props.getProperty("another.validator.order"));
+        assertEquals("alpha-42", props.getProperty("another.validator.type.code"));
+        assertEquals("a-b-c", props.getProperty("another.validator.type.label"));
+    }
+    
+    @Test
+    public final void testGetPropertyWithCyclicInheritance()
+    {
+        Properties properties = new Properties();
+        properties.setProperty("a.", "b.");
+        properties.setProperty("b.", "a.");
+        properties.setProperty("my.", "b.");
+        Properties props = ExtendedProperties.createWith(properties);
+
+        try
+        {
+            props.getProperty("my.code");
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex)
+        {
+            assertEquals("Cyclic definition of property 'b.code'.", ex.getMessage());
+        }
+    }
+
+    @Test
+    public final void testGetSubsetDroppingPrefixWithInheritTree()
+    {
+        ExtendedProperties properties = new ExtendedProperties();
+        properties.setProperty("default.code", "42");
+        properties.setProperty("type.code", "ABC-${default.code}");
+        properties.setProperty("type.label", "abc");
+        properties.setProperty("validator.order", "1");
+        properties.setProperty("validator.type.", "type.");
+        properties.setProperty("my.validator.", "validator.");
+        properties.setProperty("my.validator.order", "2");
+        properties.setProperty("my.validator.type.label", "a-b-c");
+        Properties subset = properties.getSubset("my.validator.", true);
+        
+        assertEquals("2", subset.getProperty("order"));
+        assertEquals("ABC-42", subset.getProperty("type.code"));
+        assertEquals("a-b-c", subset.getProperty("type.label"));
+        assertEquals(3, subset.size());
+    }
+    
+    @Test
+    public final void testGetSubsetNotDroppingPrefixWithInheritTree()
+    {
+        ExtendedProperties properties = new ExtendedProperties();
+        properties.setProperty("default.code", "42");
+        properties.setProperty("type.code", "ABC-${default.code}");
+        properties.setProperty("type.label", "abc");
+        properties.setProperty("validator.order", "1");
+        properties.setProperty("validator.type.", "type.");
+        properties.setProperty("my.validator.", "validator.");
+        properties.setProperty("my.validator.order", "2");
+        properties.setProperty("my.validator.type.label", "a-b-c");
+        Properties subset = properties.getSubset("my.", false);
+
+        assertEquals("2", subset.getProperty("my.validator.order"));
+        assertEquals("ABC-42", subset.getProperty("my.validator.type.code"));
+        assertEquals("a-b-c", subset.getProperty("my.validator.type.label"));
+        assertEquals(3, subset.size());
     }
 
+    
+    @Test
+    public final void testGetSubsetWithCyclicInheritance()
+    {
+        Properties properties = new Properties();
+        properties.setProperty("a.", "b.");
+        properties.setProperty("b.", "a.");
+        properties.setProperty("my.", "b.");
+        ExtendedProperties props = ExtendedProperties.createWith(properties);
+        
+        try
+        {
+            props.getSubset("my.", true);
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+            assertEquals("Cyclic definition of property 'b.'.", ex.getMessage());
+        }
+    }
+    
 }