Index: conf/testConfigurationProvider.xml
===================================================================
--- conf/testConfigurationProvider.xml	(revision 0)
+++ conf/testConfigurationProvider.xml	(revision 0)
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!-- Test configuration definition file that demonstrates complex initialization -->
+<configuration>
+  <header>
+    <result delimiterParsingDisabled="true">
+      <nodeCombiner config-class="org.apache.commons.configuration.tree.OverrideCombiner"/>
+      <expressionEngine config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
+    </result>
+    <providers>
+      <provider config-tag="test"
+                config-class="org.apache.commons.configuration.DefaultConfigurationBuilder$FileConfigurationProvider"/>
+    </providers>
+    <combiner>
+      <override>
+        <list-nodes>
+          <node>table</node>
+          <node>list</node>
+        </list-nodes>
+      </override>
+    </combiner>
+  </header>
+  <system/>
+  <properties fileName="test.properties" throwExceptionOnMissing="true"
+    config-name="properties">
+    <reloadingStrategy config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"
+      refreshDelay="10000"/>
+  </properties>
+  <!-- Fetch the file name from a variable -->
+  <xml fileName="${test_file_xml}" config-name="xml">
+    <expressionEngine config-class="org.apache.commons.configuration.tree.DefaultExpressionEngine"
+      propertyDelimiter="/" indexStart="[" indexEnd="]"/>
+  </xml>
+  <additional>
+    <xml config-name="combiner1" fileName="${test_file_combine}"/>  -->
+    <xml config-name="combiner2" fileName="testcombine2.xml"/>
+  </additional>
+</configuration>
\ No newline at end of file
Index: conf/testExtendedClass.xml
===================================================================
--- conf/testExtendedClass.xml	(revision 0)
+++ conf/testExtendedClass.xml	(revision 0)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!-- Test configuration definition file that demonstrates complex initialization -->
+<configuration>
+  <header>
+    <result delimiterParsingDisabled="true"
+            config-class="org.apache.commons.configuration.TestDefaultConfigurationBuilder$ExtendedCombinedConfiguration">
+      <nodeCombiner config-class="org.apache.commons.configuration.tree.OverrideCombiner"/>
+      <expressionEngine config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
+    </result>
+    <combiner>
+      <override>
+        <list-nodes>
+          <node>table</node>
+          <node>list</node>
+        </list-nodes>
+      </override>
+    </combiner>
+  </header>
+  <system/>
+  <properties fileName="test.properties" throwExceptionOnMissing="true"
+    config-name="properties">
+    <reloadingStrategy config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"
+      refreshDelay="10000"/>
+  </properties>
+  <!-- Fetch the file name from a variable -->
+  <xml fileName="${test_file_xml}" config-name="xml">
+    <expressionEngine config-class="org.apache.commons.configuration.tree.DefaultExpressionEngine"
+      propertyDelimiter="/" indexStart="[" indexEnd="]"/>
+  </xml>
+  <additional>
+    <xml config-name="combiner1" fileName="${test_file_combine}"/>  -->
+    <xml config-name="combiner2" fileName="testcombine2.xml"/>
+  </additional>
+</configuration>
\ No newline at end of file
Index: src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java
===================================================================
--- src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java	(revision 695569)
+++ src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java	(working copy)
@@ -32,7 +32,7 @@
  * Test class for DefaultConfigurationBuilder.
  *
  * @author Oliver Heger
- * @version $Id$
+ * @version $Id: TestDefaultConfigurationBuilder.java 578455 2007-09-22 15:12:16Z oheger $
  */
 public class TestDefaultConfigurationBuilder extends TestCase
 {
@@ -55,6 +55,12 @@
     private static final File INIT_FILE = new File(
             "conf/testComplexInitialization.xml");
 
+    private static final File CLASS_FILE = new File(
+            "conf/testExtendedClass.xml");
+
+    private static final File PROVIDER_FILE = new File(
+            "conf/testConfigurationProvider.xml");
+
     /** Constant for the name of an optional configuration.*/
     private static final String OPTIONAL_NAME = "optionalConfig";
 
@@ -743,4 +749,33 @@
         testSavedXML.delete();
         testSavedFactory.delete();
     }
+
+    public void testExtendedClass() throws ConfigurationException, IOException
+    {
+        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+        builder.setFile(CLASS_FILE);
+        CombinedConfiguration cc = builder.getConfiguration(true);
+        assertEquals("Extended", cc.getProperty("test"));
+    }
+
+    public void testConfigurationProvider() throws ConfigurationException, IOException
+    {
+        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+        builder.setFile(PROVIDER_FILE);
+        CombinedConfiguration cc = builder.getConfiguration(true);
+        DefaultConfigurationBuilder.ConfigurationProvider provider = builder.providerForTag("test");
+        assertNotNull("Provider 'test' not registered", provider);
+    }
+    
+    public static class ExtendedCombinedConfiguration extends CombinedConfiguration
+    {
+        public Object getProperty(String key)
+        {
+            if (key.equals("test"))
+            {
+                return "Extended";
+            }
+            return super.getProperty(key);
+        }
+    }
 }
Index: src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java
===================================================================
--- src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java	(revision 701606)
+++ src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java	(working copy)
@@ -137,7 +137,7 @@
  * the resulting configuration.
  * </p>
  * <p>
- * The configuration object returned by this builder is an instance of the
+ * The default configuration object returned by this builder is an instance of the
  * <code>{@link CombinedConfiguration}</code> class. The return value of the
  * <code>getConfiguration()</code> method can be casted to this type, and the
  * <code>getConfiguration(boolean)</code> method directly declares
@@ -146,9 +146,20 @@
  * configuration (e.g. for updates of single configuration objects). It has also
  * the advantage that the properties stored in all declared configuration
  * objects are collected and transformed into a single hierarchical structure,
- * which can be accessed using different expression engines.
+ * which can be accessed using different expression engines. The actual CombinedConfiguration
+ * implementation can be overridden by specifying the class in the <em>config-class</em>
+ * attribute of the result element.
  * </p>
  * <p>
+ * Additional ConfigurationProviders can be added by configuring them in the <em>header</em>
+ * section.
+ * <pre>
+ * &lt;providers&gt;
+ *   &lt;provider config-tag="tag name" config-class="provider fully qualifed class name"/&gt;
+ * &lt;/providers&gt;
+ * </pre>
+ * </p>
+ * <p>
  * All declared override configurations are directly added to the resulting
  * combined configuration. If they are given names (using the
  * <code>config-name</code> attribute), they can directly be accessed using
@@ -268,6 +279,11 @@
     static final String KEY_ADDITIONAL_LIST = SEC_HEADER
             + ".combiner.additional.list-nodes.node";
 
+    static final String KEY_CONFIGURATION_PROVIDERS = SEC_HEADER
+            + ".providers.provider";
+
+    static final String KEY_PROVIDER_KEY = XMLBeanDeclaration.ATTR_PREFIX + "tag]";
+
     /**
      * Constant for the key of the result declaration. This key can point to a
      * bean declaration, which defines properties of the resulting combined
@@ -493,6 +509,8 @@
             load();
         }
 
+        registerConfiguredProviders();
+
         CombinedConfiguration result = createResultConfiguration();
         constructedConfiguration = result;
 
@@ -528,8 +546,23 @@
             throws ConfigurationException
     {
         XMLBeanDeclaration decl = new XMLBeanDeclaration(this, KEY_RESULT, true);
-        CombinedConfiguration result = (CombinedConfiguration) BeanHelper
-                .createBean(decl, CombinedConfiguration.class);
+        Class clazz;
+        if  (decl.getBeanClassName() != null)
+        {
+            try
+            {
+                clazz = Class.forName(decl.getBeanClassName()) ;
+            }
+            catch (ClassNotFoundException cnfe)
+            {
+                throw new ConfigurationException("Unable to locate class " + decl.getBeanClassName(), cnfe);
+            }
+        }
+        else
+        {
+            clazz = CombinedConfiguration.class;
+        }
+        CombinedConfiguration result = (CombinedConfiguration) BeanHelper.createBean(decl, clazz);
 
         if (getMaxIndex(KEY_COMBINER) < 0)
         {
@@ -589,6 +622,33 @@
     }
 
     /**
+     * Registers providers defined in the configuration.
+     * @throws ConfigurationException if an error occurs
+     */
+    protected void registerConfiguredProviders() throws ConfigurationException
+    {
+        List nodes = configurationsAt(KEY_CONFIGURATION_PROVIDERS);
+        for (Iterator it = nodes.iterator(); it.hasNext();)
+        {
+            HierarchicalConfiguration config = (HierarchicalConfiguration)it.next();
+            XMLBeanDeclaration decl = new XMLBeanDeclaration(config);
+            String key = config.getString(KEY_PROVIDER_KEY);
+            String className = decl.getBeanClassName();
+            ConfigurationProvider provider;
+            try
+            {
+                Class providerClass = Class.forName(className) ;
+                provider = (ConfigurationProvider) BeanHelper.createBean(decl, providerClass);
+            }
+            catch (Exception cnfe)
+            {
+                throw new ConfigurationException("Unable to create configuration provider " + className, cnfe);
+            }
+            addConfigurationProvider(key, provider);
+        }
+    }
+
+    /**
      * Performs interpolation. This method will not only take this configuration
      * instance into account (which is the one that loaded the configuration
      * definition file), but also the so far constructed combined configuration.
