Index: src/test/java/org/codehaus/cargo/generic/FactoryRegistryTest.java
===================================================================
--- src/test/java/org/codehaus/cargo/generic/FactoryRegistryTest.java	(revision 0)
+++ src/test/java/org/codehaus/cargo/generic/FactoryRegistryTest.java	(revision 0)
@@ -0,0 +1,52 @@
+/*
+ * ========================================================================
+ *
+ * Copyright 2006-2008 Vincent Massol.
+ *
+ * Licensed 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.codehaus.cargo.generic;
+
+import junit.framework.TestCase;
+import org.codehaus.cargo.container.ContainerType;
+import org.codehaus.cargo.container.configuration.ConfigurationCapability;
+import org.codehaus.cargo.container.configuration.ConfigurationType;
+import org.codehaus.cargo.container.deployable.Deployable;
+import org.codehaus.cargo.container.deployable.DeployableType;
+import org.codehaus.cargo.generic.configuration.ConfigurationCapabilityFactory;
+import org.codehaus.cargo.generic.configuration.DefaultConfigurationCapabilityFactory;
+import org.codehaus.cargo.generic.deployable.DefaultDeployableFactory;
+
+/**
+ * Tests the discovery behavior.
+ *
+ * The class name can't be {@code AbstractFactoryRegistryTest} or else the test will be skipped.
+ *
+ * @version $Id: $
+ */
+public class FactoryRegistryTest extends TestCase
+{
+    public void test1() {
+        DefaultDeployableFactory f = new DefaultDeployableFactory(getClass().getClassLoader());
+        Deployable war = f.createDeployable("super-container", ".", DeployableType.WAR);
+        assertTrue(war instanceof SuperContainerWar);
+    }
+
+    public void test2() {
+        ConfigurationCapabilityFactory f = new DefaultConfigurationCapabilityFactory(getClass().getClassLoader());
+        ConfigurationCapability cc = f.createConfigurationCapability("super-container", ContainerType.INSTALLED, ConfigurationType.STANDALONE);
+        assertTrue(cc instanceof SuperConfigurationCapability);
+    }
+}
Index: src/test/java/org/codehaus/cargo/generic/TestFactoryRegistry.java
===================================================================
--- src/test/java/org/codehaus/cargo/generic/TestFactoryRegistry.java	(revision 0)
+++ src/test/java/org/codehaus/cargo/generic/TestFactoryRegistry.java	(revision 0)
@@ -0,0 +1,63 @@
+/*
+ * ========================================================================
+ *
+ * Copyright 2006-2008 Vincent Massol.
+ *
+ * Licensed 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.codehaus.cargo.generic;
+
+import org.codehaus.cargo.generic.deployable.DeployableFactory;
+import org.codehaus.cargo.generic.configuration.ConfigurationCapabilityFactory;
+import org.codehaus.cargo.generic.configuration.ConfigurationFactory;
+import org.codehaus.cargo.generic.deployer.DeployerFactory;
+import org.codehaus.cargo.generic.packager.PackagerFactory;
+import org.codehaus.cargo.container.deployable.DeployableType;
+import org.codehaus.cargo.container.ContainerType;
+import org.codehaus.cargo.container.configuration.ConfigurationType;
+
+/**
+ * To be discovered by {@link AbstractFactoryRegistry}.
+ * 
+ * @version $Id: $
+ */
+public class TestFactoryRegistry extends AbstractFactoryRegistry
+{
+    protected void register(DeployableFactory factory)
+    {
+        factory.registerDeployable("super-container", DeployableType.WAR, SuperContainerWar.class);
+    }
+
+    protected void register(ConfigurationCapabilityFactory factory)
+    {
+        factory.registerConfigurationCapability("super-container", ContainerType.INSTALLED,
+            ConfigurationType.STANDALONE, SuperConfigurationCapability.class);
+    }
+
+    protected void register(ConfigurationFactory factory) {
+    }
+
+    protected void register(DeployerFactory factory) {
+    }
+
+    protected void register(PackagerFactory factory) {
+    }
+
+    protected void register(ContainerFactory factory) {
+    }
+
+    protected void register(ContainerCapabilityFactory factory) {
+    }
+}
Index: src/test/java/org/codehaus/cargo/generic/SuperConfigurationCapability.java
===================================================================
--- src/test/java/org/codehaus/cargo/generic/SuperConfigurationCapability.java	(revision 0)
+++ src/test/java/org/codehaus/cargo/generic/SuperConfigurationCapability.java	(revision 0)
@@ -0,0 +1,43 @@
+/*
+ * ========================================================================
+ *
+ * Copyright 2006-2008 Vincent Massol.
+ *
+ * Licensed 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.codehaus.cargo.generic;
+
+import org.codehaus.cargo.container.configuration.ConfigurationCapability;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Used by {@link TestFactoryRegistry} to see if the discovery succeeds.
+ *
+ * @version $Id: $
+ */
+public class SuperConfigurationCapability implements ConfigurationCapability
+{
+    public boolean supportsProperty(String propertyName)
+    {
+        return true;
+    }
+
+    public Map getProperties()
+    {
+        return new HashMap();
+    }
+}
Index: src/test/java/org/codehaus/cargo/generic/SuperContainerWar.java
===================================================================
--- src/test/java/org/codehaus/cargo/generic/SuperContainerWar.java	(revision 0)
+++ src/test/java/org/codehaus/cargo/generic/SuperContainerWar.java	(revision 0)
@@ -0,0 +1,35 @@
+/*
+ * ========================================================================
+ *
+ * Copyright 2006-2008 Vincent Massol.
+ *
+ * Licensed 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.codehaus.cargo.generic;
+
+import org.codehaus.cargo.container.deployable.WAR;
+
+/**
+ * Used by {@link TestFactoryRegistry} to see if the discovery succeeds.
+ *
+ * @version $Id: $
+ */
+public class SuperContainerWar extends WAR
+{
+    public SuperContainerWar(String war)
+    {
+        super(war);
+    }
+}
Index: src/test/resources/META-INF/services/org.codehaus.cargo.generic.AbstractFactoryRegistry
===================================================================
--- src/test/resources/META-INF/services/org.codehaus.cargo.generic.AbstractFactoryRegistry	(revision 0)
+++ src/test/resources/META-INF/services/org.codehaus.cargo.generic.AbstractFactoryRegistry	(revision 0)
@@ -0,0 +1,2 @@
+# test for ABstractFactoryRegistry
+org.codehaus.cargo.generic.TestFactoryRegistry
\ No newline at end of file
Index: src/main/java/org/codehaus/cargo/generic/DefaultContainerFactory.java
===================================================================
--- src/main/java/org/codehaus/cargo/generic/DefaultContainerFactory.java	(revision 1677)
+++ src/main/java/org/codehaus/cargo/generic/DefaultContainerFactory.java	(working copy)
@@ -60,6 +60,19 @@
      */
     public DefaultContainerFactory()
     {
+        this(null);
+    }
+
+    /**
+     * Register packager name mappings.
+     *
+     * @param classLoader
+     *      ClassLoader to discover implementations from. See
+     *      {@link AbstractFactoryRegistry#register(ClassLoader, ContainerFactory)}
+     *      for the details of what this value means.
+     */
+    public DefaultContainerFactory(ClassLoader classLoader)
+    {
         super();
 
         // Note: We register containers using introspection so that we don't have to depend on
@@ -140,6 +153,8 @@
             "org.codehaus.cargo.container.weblogic.WebLogic8xInstalledLocalContainer");
         registerContainer("weblogic9x", ContainerType.INSTALLED,
             "org.codehaus.cargo.container.weblogic.WebLogic9xInstalledLocalContainer");
+
+        AbstractFactoryRegistry.register(classLoader, this);
     }
 
     /**
Index: src/main/java/org/codehaus/cargo/generic/deployable/DefaultDeployableFactory.java
===================================================================
--- src/main/java/org/codehaus/cargo/generic/deployable/DefaultDeployableFactory.java	(revision 1677)
+++ src/main/java/org/codehaus/cargo/generic/deployable/DefaultDeployableFactory.java	(working copy)
@@ -30,6 +30,7 @@
 import org.codehaus.cargo.generic.spi.AbstractIntrospectionGenericHintFactory;
 import org.codehaus.cargo.generic.internal.util.RegistrationKey;
 import org.codehaus.cargo.generic.internal.util.SimpleContainerIdentity;
+import org.codehaus.cargo.generic.AbstractFactoryRegistry;
 
 import java.lang.reflect.Constructor;
 
@@ -66,6 +67,19 @@
      */
     public DefaultDeployableFactory()
     {
+        this(null);
+    }
+
+    /**
+     * Register deployable classes mappings.
+     *
+     * @param classLoader
+     *      ClassLoader to discover implementations from. See
+     *      {@link AbstractFactoryRegistry#register(ClassLoader, DeployableFactory)}
+     *      for the details of what this value means.
+     */
+    public DefaultDeployableFactory(ClassLoader classLoader)
+    {
         // The WAR, EJB and EAR deployables are registered by default against all containers.
         // In order not to have to individually register against each container id we
         // create a fictitious default container id.
@@ -91,6 +105,8 @@
             "org.codehaus.cargo.container.geronimo.deployable.GeronimoEAR");
 
         // TODO: Register JBossWAR here when we add JBoss support
+
+        AbstractFactoryRegistry.register(classLoader, this);
     }
 
     /**
Index: src/main/java/org/codehaus/cargo/generic/DefaultContainerCapabilityFactory.java
===================================================================
--- src/main/java/org/codehaus/cargo/generic/DefaultContainerCapabilityFactory.java	(revision 1677)
+++ src/main/java/org/codehaus/cargo/generic/DefaultContainerCapabilityFactory.java	(working copy)
@@ -22,6 +22,7 @@
 import org.codehaus.cargo.generic.spi.AbstractIntrospectionGenericHintFactory;
 import org.codehaus.cargo.generic.internal.util.RegistrationKey;
 import org.codehaus.cargo.generic.internal.util.SimpleContainerIdentity;
+import org.codehaus.cargo.generic.packager.PackagerFactory;
 import org.codehaus.cargo.container.ContainerCapability;
 
 import java.lang.reflect.Constructor;
@@ -40,6 +41,19 @@
      */
     public DefaultContainerCapabilityFactory()
     {
+        this(null);
+    }
+
+    /**
+     * Register container capability name mappings.
+     *
+     * @param classLoader
+     *      ClassLoader to discover implementations from. See
+     *      {@link AbstractFactoryRegistry#register(ClassLoader, ContainerCapabilityFactory)}
+     *      for the details of what this value means.
+     */
+    public DefaultContainerCapabilityFactory(ClassLoader classLoader)
+    {
         super();
 
         // Note: We register container capabilities using introspection so that we don't have to
@@ -100,6 +114,8 @@
             "org.codehaus.cargo.container.internal.J2EEContainerCapability");
         registerContainerCapability("weblogic9x",
             "org.codehaus.cargo.container.internal.J2EEContainerCapability");
+
+        AbstractFactoryRegistry.register(classLoader, this);
     }
 
     /**
Index: src/main/java/org/codehaus/cargo/generic/deployer/DefaultDeployerFactory.java
===================================================================
--- src/main/java/org/codehaus/cargo/generic/deployer/DefaultDeployerFactory.java	(revision 1677)
+++ src/main/java/org/codehaus/cargo/generic/deployer/DefaultDeployerFactory.java	(working copy)
@@ -29,6 +29,7 @@
 import org.codehaus.cargo.generic.spi.AbstractIntrospectionGenericHintFactory;
 import org.codehaus.cargo.generic.internal.util.RegistrationKey;
 import org.codehaus.cargo.generic.internal.util.SimpleContainerIdentity;
+import org.codehaus.cargo.generic.AbstractFactoryRegistry;
 
 import java.lang.reflect.Constructor;
 
@@ -59,6 +60,19 @@
      */
     public DefaultDeployerFactory()
     {
+        this(null);
+    }
+
+    /**
+     * Register deployer name mappings.
+     *
+     * @param classLoader
+     *      ClassLoader to discover implementations from. See
+     *      {@link AbstractFactoryRegistry#register(ClassLoader, DeployerFactory)}
+     *      for the details of what this value means.
+     */
+    public DefaultDeployerFactory(ClassLoader classLoader)
+    {
         super();
 
         // Note: Sorted by container id alphabetical order
@@ -116,6 +130,7 @@
         registerDeployer("tomcat6x", DeployerType.REMOTE,
             "org.codehaus.cargo.container.tomcat.Tomcat6xRemoteDeployer");
 
+        AbstractFactoryRegistry.register(classLoader, this);
     }
 
     /**
Index: src/main/java/org/codehaus/cargo/generic/AbstractFactoryRegistry.java
===================================================================
--- src/main/java/org/codehaus/cargo/generic/AbstractFactoryRegistry.java	(revision 0)
+++ src/main/java/org/codehaus/cargo/generic/AbstractFactoryRegistry.java	(revision 0)
@@ -0,0 +1,289 @@
+/*
+ * ========================================================================
+ *
+ * Copyright 2006-2008 Vincent Massol.
+ *
+ * Licensed 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.codehaus.cargo.generic;
+
+import org.apache.commons.discovery.jdk.JDKHooks;
+import org.apache.commons.discovery.resource.ClassLoaders;
+import org.apache.commons.discovery.tools.SPInterface;
+import org.apache.commons.discovery.tools.Service;
+import org.codehaus.cargo.generic.deployable.DeployableFactory;
+import org.codehaus.cargo.generic.configuration.ConfigurationFactory;
+import org.codehaus.cargo.generic.configuration.ConfigurationCapabilityFactory;
+import org.codehaus.cargo.generic.deployer.DeployerFactory;
+import org.codehaus.cargo.generic.packager.PackagerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * SPI to be implemented by container implementation to register implementations
+ * to their factories.
+ *
+ * <p>
+ * This class also provides static methods (to be used primarily within Cargo
+ * but can be also called directly by client apps) to discover all the implementations
+ * and register them to factories.
+ *
+ * <p>
+ * Client apps should normally use {@code DefaultXXXFactory} classes,
+ * like {@link org.codehaus.cargo.generic.deployable.DefaultDeployableFactory},
+ * which internally uses the discovery mechanism
+ *
+ * <p>
+ * Container implementors should override the 1-arg {@code register} methods to register
+ * its implementations to the given factory.
+ *
+ * @version $Id: $
+ */
+public abstract class AbstractFactoryRegistry
+{
+    /**
+     * Discovers all the {@link org.codehaus.cargo.container.deployable.Deployable}s and
+     * adds them to the given {@link DeployableFactory}.
+     *
+     * <p>
+     * The discovery is done by
+     * <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html">the standard service loader
+     * mechanism</a>, by looking for
+     * <tt>/META-INF/services/org.codehaus.cargo.generic.AbstractFactoryRegistry</tt> files.
+     *
+     * @param classLoader
+     *      The class loader to be used to search service provide configuration files.
+     *      If null, the value defaults to the thread context classloader. If that's also null,
+     *      the value defaults to the class loader that loaded {@link AbstractFactoryRegistry}.
+     *      In the rare circumstance of that also being null (which means Cargo is loaded in the
+     *      bootstrap classloader), the value defaults to the system class loader.
+     * @param factory
+     *      The factory whose {@code register} method is invoked to receive
+     *      {@link org.codehaus.cargo.container.deployable.Deployable}s that
+     *      are discovered.
+     */
+    public static void register(ClassLoader classLoader, DeployableFactory factory)
+    {
+        for (Iterator itr = list(classLoader).iterator(); itr.hasNext();)
+        {
+            ((AbstractFactoryRegistry) itr.next()).register(factory);
+        }
+    }
+
+    /**
+     * See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     *
+     * @param classLoader
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     * @param factory
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     */
+    public static void register(ClassLoader classLoader, ConfigurationFactory factory)
+    {
+        for (Iterator itr = list(classLoader).iterator(); itr.hasNext();)
+        {
+            ((AbstractFactoryRegistry) itr.next()).register(factory);
+        }
+    }
+
+    /**
+     * See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     *
+     * @param classLoader
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     * @param factory
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     */
+    public static void register(ClassLoader classLoader, ConfigurationCapabilityFactory factory)
+    {
+        for (Iterator itr = list(classLoader).iterator(); itr.hasNext();)
+        {
+            ((AbstractFactoryRegistry) itr.next()).register(factory);
+        }
+    }
+
+    /**
+     * See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     *
+     * @param classLoader
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     * @param factory
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     */
+    public static void register(ClassLoader classLoader, DeployerFactory factory)
+    {
+        for (Iterator itr = list(classLoader).iterator(); itr.hasNext();)
+        {
+            ((AbstractFactoryRegistry) itr.next()).register(factory);
+        }
+    }
+
+    /**
+     * See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     *
+     * @param classLoader
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     * @param factory
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     */
+    public static void register(ClassLoader classLoader, PackagerFactory factory)
+    {
+        for (Iterator itr = list(classLoader).iterator(); itr.hasNext();)
+        {
+            ((AbstractFactoryRegistry) itr.next()).register(factory);
+        }
+    }
+
+    /**
+     * See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     *
+     * @param classLoader
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     * @param factory
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     */
+    public static void register(ClassLoader classLoader, ContainerFactory factory)
+    {
+        for (Iterator itr = list(classLoader).iterator(); itr.hasNext();)
+        {
+            ((AbstractFactoryRegistry) itr.next()).register(factory);
+        }
+    }
+
+    /**
+     * See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     *
+     * @param classLoader
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     * @param factory
+     *      See {@link #register(ClassLoader, DeployableFactory)} for the semantics.
+     */
+    public static void register(ClassLoader classLoader, ContainerCapabilityFactory factory)
+    {
+        for (Iterator itr = list(classLoader).iterator(); itr.hasNext();)
+        {
+            ((AbstractFactoryRegistry) itr.next()).register(factory);
+        }
+    }
+
+
+
+    /**
+     * Registers {@link org.codehaus.cargo.container.deployable.Deployable} implementations
+     * to the given {@link DeployableFactory}.
+     *
+     * @param factory
+     *      See {@link #register(ClassLoader, DeployableFactory)} 
+     */
+    protected abstract void register(DeployableFactory factory);
+
+    /**
+     * See {@link #register(DeployableFactory)} for the semantics.
+     *
+     * @param factory
+     *      See {@link #register(DeployableFactory)}
+     */
+    protected abstract void register(ConfigurationCapabilityFactory factory);
+
+    /**
+     * See {@link #register(DeployableFactory)} for the semantics.
+     *
+     * @param factory
+     *      See {@link #register(DeployableFactory)}
+     */
+    protected abstract void register(ConfigurationFactory factory);
+
+    /**
+     * See {@link #register(DeployableFactory)} for the semantics.
+     *
+     * @param factory
+     *      See {@link #register(DeployableFactory)}
+     */
+    protected abstract void register(DeployerFactory factory);
+
+    /**
+     * See {@link #register(DeployableFactory)} for the semantics.
+     *
+     * @param factory
+     *      See {@link #register(DeployableFactory)}
+     */
+    protected abstract void register(PackagerFactory factory);
+
+    /**
+     * See {@link #register(DeployableFactory)} for the semantics.
+     *
+     * @param factory
+     *      See {@link #register(DeployableFactory)}
+     */
+    protected abstract void register(ContainerFactory factory);
+
+    /**
+     * See {@link #register(DeployableFactory)} for the semantics.
+     *
+     * @param factory
+     *      See {@link #register(DeployableFactory)}
+     */
+    protected abstract void register(ContainerCapabilityFactory factory);
+
+    /**
+     * Lists up {@link AbstractFactoryRegistry}s that are discovered.
+     *
+     * @param classLoader
+     *      See {@link #register(ClassLoader, DeployableFactory)} for more details.
+     * @return always non-null but can be empty.
+     */
+    private static List list(ClassLoader classLoader)
+    {
+        ClassLoader cl = classLoader;
+        if (cl == null)
+        {
+            cl = Thread.currentThread().getContextClassLoader();
+        }
+        if (cl == null)
+        {
+            cl = AbstractFactoryRegistry.class.getClassLoader();
+        }
+        if (cl == null)
+        {
+            cl = JDKHooks.getJDKHooks().getSystemClassLoader();
+        }
+        if (cl == null)
+        {
+            // this is not our day. bail out.
+            return Collections.EMPTY_LIST;
+        }
+
+        ClassLoaders loaders = new ClassLoaders();
+        loaders.put(cl);
+
+        List registries = new ArrayList();
+        Enumeration providers = Service.providers(
+                new SPInterface(AbstractFactoryRegistry.class), loaders);
+        while (providers.hasMoreElements())
+        {
+            Object provider = providers.nextElement();
+            if (provider instanceof AbstractFactoryRegistry)
+            {
+                registries.add(provider);
+            }
+        }
+
+        return registries;
+    }
+}
Index: src/main/java/org/codehaus/cargo/generic/configuration/DefaultConfigurationFactory.java
===================================================================
--- src/main/java/org/codehaus/cargo/generic/configuration/DefaultConfigurationFactory.java	(revision 1677)
+++ src/main/java/org/codehaus/cargo/generic/configuration/DefaultConfigurationFactory.java	(working copy)
@@ -26,6 +26,7 @@
 import org.codehaus.cargo.generic.spi.AbstractIntrospectionGenericHintFactory;
 import org.codehaus.cargo.generic.internal.util.RegistrationKey;
 import org.codehaus.cargo.generic.internal.util.FullContainerIdentity;
+import org.codehaus.cargo.generic.AbstractFactoryRegistry;
 import org.codehaus.cargo.util.FileHandler;
 import org.codehaus.cargo.util.DefaultFileHandler;
 
@@ -62,6 +63,19 @@
      */
     public DefaultConfigurationFactory()
     {
+        this(null);
+    }
+
+    /**
+     * Register configuration name mappings.
+     *
+     * @param classLoader
+     *      ClassLoader to discover implementations from. See
+     *      {@link AbstractFactoryRegistry#register(ClassLoader, ConfigurationFactory)}
+     *      for the details of what this value means.
+     */
+    public DefaultConfigurationFactory(ClassLoader classLoader)
+    {
         super();
 
         // Note: Sorted by container id alphabetical order
@@ -161,6 +175,8 @@
             "org.codehaus.cargo.container.weblogic.WebLogicStandaloneLocalConfiguration");
         registerConfiguration("weblogic9x", ContainerType.INSTALLED, ConfigurationType.EXISTING,
             "org.codehaus.cargo.container.weblogic.WebLogicExistingLocalConfiguration");
+
+        AbstractFactoryRegistry.register(classLoader, this);
     }
 
     /**
Index: src/main/java/org/codehaus/cargo/generic/configuration/DefaultConfigurationCapabilityFactory.java
===================================================================
--- src/main/java/org/codehaus/cargo/generic/configuration/DefaultConfigurationCapabilityFactory.java	(revision 1677)
+++ src/main/java/org/codehaus/cargo/generic/configuration/DefaultConfigurationCapabilityFactory.java	(working copy)
@@ -22,6 +22,7 @@
 import org.codehaus.cargo.generic.spi.AbstractIntrospectionGenericHintFactory;
 import org.codehaus.cargo.generic.internal.util.RegistrationKey;
 import org.codehaus.cargo.generic.internal.util.FullContainerIdentity;
+import org.codehaus.cargo.generic.AbstractFactoryRegistry;
 import org.codehaus.cargo.container.configuration.ConfigurationType;
 import org.codehaus.cargo.container.configuration.ConfigurationCapability;
 import org.codehaus.cargo.container.ContainerType;
@@ -42,6 +43,19 @@
      */
     public DefaultConfigurationCapabilityFactory()
     {
+        this(null);
+    }
+
+    /**
+     * Register configuration capability name mappings.
+     *
+     * @param classLoader
+     *      ClassLoader to discover implementations from. See
+     *      {@link AbstractFactoryRegistry#register(ClassLoader, ConfigurationCapabilityFactory)}
+     *      for the details of what this value means.
+     */
+    public DefaultConfigurationCapabilityFactory(ClassLoader classLoader)
+    {
         super();
         // Note: We register configuration capabilities using introspection so that we don't have to
         // depend on those classes at build time nor at runtime. More specifically this allows a
@@ -189,6 +203,8 @@
         registerConfigurationCapability("weblogic9x", ContainerType.INSTALLED,
             ConfigurationType.EXISTING, "org.codehaus.cargo.container.weblogic.internal."
                 + "WebLogicExistingLocalConfigurationCapability");
+
+        AbstractFactoryRegistry.register(classLoader, this);
     }
 
     /**
Index: src/main/java/org/codehaus/cargo/generic/packager/DefaultPackagerFactory.java
===================================================================
--- src/main/java/org/codehaus/cargo/generic/packager/DefaultPackagerFactory.java	(revision 1677)
+++ src/main/java/org/codehaus/cargo/generic/packager/DefaultPackagerFactory.java	(working copy)
@@ -22,6 +22,7 @@
 import org.codehaus.cargo.generic.spi.AbstractIntrospectionGenericHintFactory;
 import org.codehaus.cargo.generic.internal.util.RegistrationKey;
 import org.codehaus.cargo.generic.internal.util.SimpleContainerIdentity;
+import org.codehaus.cargo.generic.AbstractFactoryRegistry;
 import org.codehaus.cargo.container.ContainerException;
 import org.codehaus.cargo.container.packager.PackagerType;
 import org.codehaus.cargo.container.packager.Packager;
@@ -55,6 +56,19 @@
      */
     public DefaultPackagerFactory()
     {
+        this(null);
+    }
+
+    /**
+     * Register packager name mappings.
+     *
+     * @param classLoader
+     *      ClassLoader to discover implementations from. See
+     *      {@link AbstractFactoryRegistry#register(ClassLoader, PackagerFactory)}
+     *      for the details of what this value means.
+     */
+    public DefaultPackagerFactory(ClassLoader classLoader)
+    {
         super();
 
         // Note: Sorted by container id alphabetical order
@@ -68,6 +82,7 @@
         registerPackager("tomcat6x", PackagerType.DIRECTORY,
             "org.codehaus.cargo.container.tomcat.TomcatDirectoryPackager");
 
+        AbstractFactoryRegistry.register(classLoader, this);
     }
 
     /**
Index: pom.xml
===================================================================
--- pom.xml	(revision 1677)
+++ pom.xml	(working copy)
@@ -35,6 +35,11 @@
       <scope>compile</scope>
     </dependency>
     <dependency>
+      <groupId>commons-discovery</groupId>
+      <artifactId>commons-discovery</artifactId>
+      <version>0.4</version>
+    </dependency>
+    <dependency>
       <groupId>org.codehaus.cargo</groupId>
       <artifactId>cargo-core-api-container</artifactId>
       <version>${version}</version>

