Added component factory feature in Service annotation - Reorganized annotation packages - Fixed javadoc - Removed static factory methods from annotations

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@942914 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/AspectService.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/AspectService.java
index 854faf5..ff74749 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/AspectService.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/AspectService.java
@@ -62,18 +62,4 @@
      * @return the ranking of this aspect
      */
     int ranking();
-    
-    /**
-     * Returns the Class of the class which acts as a factory for this Service. The default method
-     * factory name is "create". If you need to invoke another method, then you can use the 
-     * <code>factoryMethod</code> attribute.
-     * @return the factory Class name.
-     */
-    Class<?> factory() default Object.class;
-
-    /**
-     * Returns the method name of the factory class which will create our Service instance.
-     * @return the factory method name.
-     */
-    String factoryMethod() default "";
 }
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/PropertyMetaData.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/PropertyMetaData.java
index 0ece247..5c41695 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/PropertyMetaData.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/PropertyMetaData.java
@@ -23,8 +23,21 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.felix.dm.annotation.api.adapter.FactoryConfigurationAdapterService;
+import org.apache.felix.dm.annotation.api.dependency.ConfigurationDependency;
+
 /**
  * This annotation describes the data types of a configuration Property.
+ * It can be used by other annotations which require meta type support.
+ * For now, the following annotations are using <code>PropertyMeteData</code:
+ * <ul>
+ *   <li>{@link ConfigurationDependency}: This dependency allows to define a 
+ *   dependency over a <code>Configuration Admin</code> configuration dictionaries, whose 
+ *   metadata can be described using <code>PropertyMetaData</code> annotation.
+ *   <li>{@link FactoryConfigurationAdapterService}: This service adapter allows 
+ *   to dynamically create Services on behalf of <code>Factory Configuration Admin</code> 
+ *   configuration dictionaries, whose metadata can be described using this <code>PropertyMetaData</code> annotation.
+ * </ul>
  */
 @Retention(RetentionPolicy.CLASS)
 @Target(ElementType.ANNOTATION_TYPE)
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java
index 8c69541..01190d4 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java
@@ -24,7 +24,111 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotates an OSGi Service class.
+ * Annotates an OSGi Service class with its dependencies. 
+ * By default, all directly implemented interfaces are registered into the OSGi registry,
+ * and the Service is instantiated automatically, when the Service' bundle is started and 
+ * when the Service dependencies are available. If you need to take control of when and how 
+ * much Service instances are getting created, then you can use the <code>factory</code> 
+ * Service attribute.<p> 
+ * If a <code>factory</code> attribute is set, the Service is not started automatically 
+ * during bundle startup, and a <code>java.util.Set&lt;Dictionary&gt;</code> 
+ * object is registered into the OSGi registry on behalf of the Service. This Set will act 
+ * as a Factory API, and another component may use this Set and add some configuration 
+ * dictionaries in it, in order to fire some Service activations (there is one Service 
+ * instantiated per dictionary, which is passed to Service instances via a configurable 
+ * callback method).
+ *
+ * <h3>Usage Examples</h3>
+ * 
+ * <p> Here is a sample showing a X service, which depends on a configuration dependency:<p>
+ * <blockquote>
+ * 
+ * <pre>
+ * &#47;**
+ *   * This Service will be activated once the bundle is started and when all required dependencies
+ *   * are available.
+ *   *&#47;
+ * &#64;Service
+ * class X implements Z {
+ *     &#64;ConfigurationDependency(pid="MyPid")
+ *     void configure(Dictionary conf) {
+ *          // Configure or reconfigure our service. The conf is provided by the Configuration Admin Service,
+ *          // and all public properties (which don't start with a dot) are propagated with the
+ *          // Service properties specified in the properties's Service attribute.
+ *     }
+ *   
+ *     &#64;Start
+ *     void start() {
+ *         // Our Service is starting and is about to be registered in the OSGi registry as a Z service.
+ *   }
+ *   
+ *   public void doService() {
+ *         // ...
+ *   }   
+ * </pre>
+ * </blockquote>
+ * 
+ * Here is a sample showing how a Y service may dynamically instantiate several X Service instances, 
+ * using the {@link #factory()} attribute:<p>
+ * <blockquote>
+ * 
+ * <pre>
+ *  &#47;**
+ *    * All Service instances will be created/updated/removed by the "Y" Service
+ *    *&#47;
+ *  &#64;Service(factory="MyServiceFactory", factoryConfigure="configure")
+ *  class X implements Z {                 
+ *      void configure(Dictionary conf) {
+ *          // Configure or reconfigure our service. The conf is provided by the factory,
+ *          // and all public properties (which don't start with a dot) are propagated with the
+ *          // Service properties specified in the properties's Service attribute.
+ *      }
+ * 
+ *      &#64;ServiceDependency
+ *      void bindOtherService(OtherService other) {
+ *          // store this require dependency
+ *      }
+ *      
+ *      &#64;Start
+ *      void start() {
+ *          // Our Service is starting and is about to be registered in the OSGi registry as a Z service.
+ *      } 
+ *      
+ *      public void doService() {
+ *          // ...
+ *      }   
+ *  }
+ * 
+ *  &#47;**
+ *    * This class will instantiate some X Service instances
+ *    *&#47;
+ *  &#64;Service 
+ *  class Y {
+ *      &#64;ServiceDependency(filter="(dm.factory.name=MyServiceFactory))
+ *      Set&lt;Dictionary&gt; _XFactory; // This Set acts as a Factory API for creating X Service instances.
+ *    
+ *      &#64;Start
+ *      void start() {
+ *          // Instantiate a X Service instance
+ *          Dictionary x1 = new Hashtable() {{ put("foo", "bar1"); }};
+ *          _XFactory.add(x1);
+ *      
+ *          // Instantiate another X Service instance
+ *          Dictionary x2 = new Hashtable() {{ put("foo", "bar2"); }};
+ *          _XFactory.add(x2);
+ *      
+ *          // Update the first X Service instance
+ *          x1.put("foo", "bar1_modified");
+ *          _XFactory.add(x1);
+ *      
+ *          // Destroy X Services (Notice that invoking XFactory.clear() will destroy all X Service instances)
+ *          _XFactory.remove(x1);
+ *          _XFactory.remove(x2); 
+ *      }
+ *  }
+ * </pre>
+ * 
+ * </blockquote>
  */
 @Retention(RetentionPolicy.CLASS)
 @Target(ElementType.TYPE)
@@ -32,27 +136,37 @@
 {
     /**
      * Returns the list of provided interfaces. By default, the directly implemented interfaces are provided.
-     * @return The list of provided interfaces.
      */
-    Class<?>[] provide() default Object.class;
+    Class<?>[] provide() default {};
 
     /**
      * Returns the list of provided service properties.
-     * @return The list of provided service properties.
      */
     Property[] properties() default {};
-    
-    /**
-     * Returns the Class of the class which acts as a factory for this Service. The default method
-     * factory name is "create". If you need to invoke another method, then you can use the 
-     * <code>factoryMethod</code> attribute.
-     * @return the factory Class name.
-     */
-    Class<?> factory() default Object.class;
 
     /**
-     * Returns the method name of the factory class which will create our Service instance.
-     * @return the factory method name.
+     * Returns the <code>factory</code> name used to dynamically instantiate the Service annotated by this class.
+     * When you set this attribute, a <code>java.util.Set&lt;java.lang.Dictionary&gt;</code> Service will 
+     * be provided with a <code>dm.factory.name</code> service property matching your specified <code>factory</code> attribute.
+     * This Set will be provided once the Service's bundle is started, even if required dependencies are not available, and the
+     * Set will be unregistered from the OSGi registry once the Service's bundle is stopped or being updated.<p>
+     * So, basically, another component may then be injected with this set in order to dynamically instantiate some Service instances:
+     * <ul>
+     * <li> Each time a new Dictionary is added into the Set, then a new instance of the annotated service will be instantiated.</li>
+     * <li> Each time an existing Dictionary is updated from the Set, then the corresponding Service instance will be updated.</li>
+     * <li> Each time an existing Dictionary is removed from the Set, then the corresponding Service instance will be destroyed.</li>
+     * </ul>
+     * The dictionary registered in the Set will be provided to the created Service instance using a callback method that you can 
+     * optionally specify in the {@link Service#factoryConfigure()} attribute. Each public properties from that dictionary 
+     * (which don't start with a dot) will be propagated along with the annotated Service properties.
      */
-    String factoryMethod() default "";
+    String factory() default "";
+
+    /**
+     * Returns the "configure" callback method name to be called with the factory configuration. This attribute only makes sense if the 
+     * {@link #factory()} attribute is used. If specified, then this attribute references a Service callback method, which is called 
+     * for providing the configuration supplied by the factory that instantiated this Service. The current Service properties will be 
+     * also updated with all public properties (which don't start with a dot).
+     */
+    String factoryConfigure() default "";
 }
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/AdapterService.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/AdapterService.java
similarity index 95%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/AdapterService.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/AdapterService.java
index 28d94fd..eb05f03 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/AdapterService.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/AdapterService.java
@@ -16,13 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.adapter;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.felix.dm.annotation.api.Property;
+
 /**
  * Annotates an Adapater Service. The adapter will be applied to any service that
  * matches the implemented interface and filter. For each matching service
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleAdapterService.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/BundleAdapterService.java
similarity index 95%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleAdapterService.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/BundleAdapterService.java
index 56ae2da..1464566 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleAdapterService.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/BundleAdapterService.java
@@ -16,13 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.adapter;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.felix.dm.annotation.api.Property;
 import org.osgi.framework.Bundle;
 
 /**
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/FactoryConfigurationAdapterService.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/FactoryConfigurationAdapterService.java
similarity index 91%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/FactoryConfigurationAdapterService.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/FactoryConfigurationAdapterService.java
index 991e60d..2358a36 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/FactoryConfigurationAdapterService.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/FactoryConfigurationAdapterService.java
@@ -16,15 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.adapter;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.PropertyMetaData;
+
 /**
- * Annotates a class that acts as a Configuration Factory Adapter Service. For each new Config Admin factory configuration matching
+ * Annotates a class that acts as a Factory Configuration Adapter Service. For each new <code>Config Admin</code> factory configuration matching
  * the specified factoryPid, an instance of this service will be created.
  * The adapter will be registered with the specified interface, and with the specified adapter service properties.
  * Depending on the <code>propagate</code> parameter, every public factory configuration properties 
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ResourceAdapterService.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/ResourceAdapterService.java
similarity index 94%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ResourceAdapterService.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/ResourceAdapterService.java
index 28a1700..c3764bf 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ResourceAdapterService.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/adapter/ResourceAdapterService.java
@@ -16,13 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.adapter;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.felix.dm.annotation.api.Property;
+
 /**
  * Annotates a class as a Resource Adapter Service. The adapter will be applied to any resource 
  * that matches the specified filter condition. For each matching resource
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleDependency.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/BundleDependency.java
similarity index 96%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleDependency.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/BundleDependency.java
index 50eeada..9632f91 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleDependency.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/BundleDependency.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.dependency;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ConfigurationDependency.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ConfigurationDependency.java
similarity index 95%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ConfigurationDependency.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ConfigurationDependency.java
index 63335d0..43d1f67 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ConfigurationDependency.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ConfigurationDependency.java
@@ -16,13 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.dependency;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.felix.dm.annotation.api.PropertyMetaData;
+
 /**
  * Annotates a method for injecting a Configuration Dependency.
  */
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ResourceDependency.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ResourceDependency.java
similarity index 94%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ResourceDependency.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ResourceDependency.java
index c4d2823..1dbac23 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ResourceDependency.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ResourceDependency.java
@@ -16,13 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.dependency;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * Annotates a method of field as a Resource Dependency.
+ */
 @Retention(RetentionPolicy.CLASS)
 @Target({ElementType.METHOD, ElementType.FIELD})
 public @interface ResourceDependency
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ServiceDependency.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ServiceDependency.java
similarity index 97%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ServiceDependency.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ServiceDependency.java
index c36c18b..adac069 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/ServiceDependency.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/ServiceDependency.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.dependency;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/TemporalServiceDependency.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/TemporalServiceDependency.java
similarity index 98%
rename from dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/TemporalServiceDependency.java
rename to dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/TemporalServiceDependency.java
index 0866d31..e445adb 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/TemporalServiceDependency.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/dependency/TemporalServiceDependency.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.dm.annotation.api;
+package org.apache.felix.dm.annotation.api.dependency;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
index 065b756..105e7c9 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
@@ -29,22 +29,22 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.felix.dm.annotation.api.AdapterService;
 import org.apache.felix.dm.annotation.api.AspectService;
-import org.apache.felix.dm.annotation.api.BundleAdapterService;
-import org.apache.felix.dm.annotation.api.BundleDependency;
 import org.apache.felix.dm.annotation.api.Composition;
-import org.apache.felix.dm.annotation.api.ConfigurationDependency;
 import org.apache.felix.dm.annotation.api.Destroy;
-import org.apache.felix.dm.annotation.api.FactoryConfigurationAdapterService;
 import org.apache.felix.dm.annotation.api.Init;
-import org.apache.felix.dm.annotation.api.ResourceAdapterService;
-import org.apache.felix.dm.annotation.api.ResourceDependency;
 import org.apache.felix.dm.annotation.api.Service;
-import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.annotation.api.Start;
 import org.apache.felix.dm.annotation.api.Stop;
-import org.apache.felix.dm.annotation.api.TemporalServiceDependency;
+import org.apache.felix.dm.annotation.api.adapter.AdapterService;
+import org.apache.felix.dm.annotation.api.adapter.BundleAdapterService;
+import org.apache.felix.dm.annotation.api.adapter.FactoryConfigurationAdapterService;
+import org.apache.felix.dm.annotation.api.adapter.ResourceAdapterService;
+import org.apache.felix.dm.annotation.api.dependency.BundleDependency;
+import org.apache.felix.dm.annotation.api.dependency.ConfigurationDependency;
+import org.apache.felix.dm.annotation.api.dependency.ResourceDependency;
+import org.apache.felix.dm.annotation.api.dependency.ServiceDependency;
+import org.apache.felix.dm.annotation.api.dependency.TemporalServiceDependency;
 import org.osgi.framework.Bundle;
 
 import aQute.lib.osgi.Annotation;
@@ -123,12 +123,12 @@
         AdapterService,
         BundleAdapterService,
         ResourceAdapterService,
+        FactoryConfigurationAdapterService,
         ServiceDependency, 
         TemporalServiceDependency, 
         ConfigurationDependency,
         BundleDependency,
         ResourceDependency,
-        FactoryConfigurationAdapterService
     };
 
     // List of component descriptor parameters
@@ -141,8 +141,6 @@
         impl, 
         provide, 
         properties, 
-        factory, 
-        factoryMethod, 
         composition, 
         service, 
         filter, 
@@ -162,7 +160,9 @@
         adapteeService,
         adapteeFilter,
         stateMask,
-        ranking
+        ranking,
+        factory,
+        factoryConfigure,
     };
 
     /**
@@ -460,12 +460,12 @@
 
         // provide attribute
         info.addClassParam(annotation, Params.provide, m_interfaces);
-
+        
         // factory attribute
-        info.addClassParam(annotation, Params.factory, null);
-
-        // factoryMethod attribute
-        info.addParam(annotation, Params.factoryMethod, null);
+        info.addParam(annotation, Params.factory, null);
+        
+        // factoryPropertiesCallback attribute
+        info.addParam(annotation, Params.factoryConfigure, null);
     }
 
     private void addCommonServiceParams(Info info)
@@ -590,13 +590,7 @@
 
         // Register previously parsed Init/Start/Stop/Destroy/Composition annotations
         addCommonServiceParams(info);
-        
-        // factory attribute
-        info.addClassParam(annotation, Params.factory, null);
-
-        // factoryMethod attribute
-        info.addParam(annotation, Params.factoryMethod, null);
-        
+                
         // Parse service filter
         String filter = annotation.get(Params.filter.toString());
         if (filter != null) {
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ComponentManager.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ComponentManager.java
index 3be1217..1b96e89 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ComponentManager.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ComponentManager.java
@@ -25,7 +25,9 @@
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.dependencies.BundleDependency;
@@ -51,6 +53,7 @@
     private HashMap<Bundle, List<Service>> m_services = new HashMap<Bundle, List<Service>>();
     private LogService m_logService; // Injected
     private BundleContext m_bctx; // Injected
+    private ServiceFactory m_serviceFactory;
 
     /**
      * Starts our Service (at this point, we have been injected with our bundle context, as well
@@ -131,6 +134,7 @@
      * @param b
      * @param descriptorURL
      */
+    @SuppressWarnings("null")
     private void loadDescriptor(Bundle b, URL descriptorURL)
     {
         m_logService.log(LogService.LOG_DEBUG, "Parsing descriptor " + descriptorURL
@@ -147,6 +151,7 @@
 
             while ((line = in.readLine()) != null)
             {
+                Dependency dp = null;
                 switch (parser.parse(line))
                 {
                     case Service:
@@ -174,32 +179,45 @@
                         break;
 
                     case ServiceDependency:
-                        checkServiceParsed(service);
-                        service.add(createServiceDependency(b, dm, parser, false));
+                        dp = createServiceDependency(b, dm, parser, false);
                         break;
 
                     case TemporalServiceDependency:
-                        checkServiceParsed(service);
-                        service.add(createServiceDependency(b, dm, parser, true));
+                        dp = createServiceDependency(b, dm, parser, true);
                         break;
 
                     case ConfigurationDependency:
-                        checkServiceParsed(service);
-                        service.add(createConfigurationDependency(b, dm, parser));
+                        dp = createConfigurationDependency(b, dm, parser);
                         break;
                         
                     case BundleDependency:
-                        checkServiceParsed(service);
-                        service.add(createBundleDependency(b, dm, parser));
+                        dp = createBundleDependency(b, dm, parser);
                         break;
                         
                     case ResourceDependency:
-                        checkServiceParsed(service);
-                        service.add(createResourceDependency(b, dm, parser));
+                        dp = createResourceDependency(b, dm, parser);
                         break;
                 }
+                
+                // If we parsed a dependency: add it in the current parsed service, unless the service is a factory service.
+                // In this case, the dependency is just buffered in the service factory, which will register it at 
+                // each instantiation time.
+                
+                if (dp != null)
+                {
+                    checkServiceParsed(service);
+                    if (m_serviceFactory != null)
+                    {
+                        // The dependency is buffered and will be used once this factory fires a service instantiation.
+                        m_serviceFactory.addDependency(dp);
+                    }
+                    else
+                    {
+                        service.add(dp);
+                    }
+                }
             }
-
+            
             List<Service> services = m_services.get(b);
             if (services == null)
             {
@@ -273,33 +291,39 @@
         throws ClassNotFoundException
     {
         Service service = dm.createService();
-        // Get factory parameters.
         String factory = parser.getString(DescriptorParam.factory, null);
-        String factoryMethod = parser.getString(DescriptorParam.factoryMethod, "create");
+        String factoryConfigure = parser.getString(DescriptorParam.factoryConfigure, null);
+        String impl = parser.getString(DescriptorParam.impl);
+        String init = parser.getString(DescriptorParam.init, null);
+        String start = parser.getString(DescriptorParam.start, null);
+        String stop = parser.getString(DescriptorParam.stop, null);
+        String destroy = parser.getString(DescriptorParam.destroy, null);
+        String composition = parser.getString(DescriptorParam.composition, null);
+        Dictionary<String, String> serviceProperties = parser.getDictionary(DescriptorParam.properties, null);
+        String[] provide = parser.getStrings(DescriptorParam.provide, null);
 
         if (factory == null)
         {
-            // Set service impl
-            String impl = parser.getString(DescriptorParam.impl);
             service.setImplementation(b.loadClass(impl));
+            service.setCallbacks(init, start, stop, destroy);
+            if (composition != null)
+            {
+                service.setComposition(composition);
+            }
+            if (provide != null)
+            {
+                service.setInterface(provide, serviceProperties);
+            }
         }
         else
         {
-            // Set service factory
-            Class<?> factoryClass = b.loadClass(factory);
-            service.setFactory(factoryClass, factoryMethod);
-        }
-
-        // Set service callbacks
-        setCommonServiceParams(service, parser);
-        
-        // Set service interface with associated service properties
-        Dictionary<String, String> serviceProperties = parser.getDictionary(
-            DescriptorParam.properties, null);
-        String[] provides = parser.getStrings(DescriptorParam.provide, null);
-        if (provides != null)
-        {
-            service.setInterface(provides, serviceProperties);
+            m_serviceFactory = new ServiceFactory(b.loadClass(impl), init, start, stop, destroy,
+                                                  composition, serviceProperties, provide, factoryConfigure);
+            service.setImplementation(m_serviceFactory);
+            service.setCallbacks(null, "start", "stop", null);
+            Hashtable<String, String> props = new Hashtable<String, String>();
+            props.put("dm.factory.name", factory);
+            service.setInterface(Set.class.getName(), props);
         }
 
         return service;
@@ -340,19 +364,9 @@
         String serviceFilter = parser.getString(DescriptorParam.filter, null);
         Dictionary<String, String> aspectProperties = parser.getDictionary(DescriptorParam.properties, null);
         int ranking = parser.getInt(DescriptorParam.ranking, 1);          
-        String factory = parser.getString(DescriptorParam.factory, null);
-        if (factory == null)
-        {
-            String implClass = parser.getString(DescriptorParam.impl);
-            Object impl = b.loadClass(implClass);
-            service = dm.createAspectService(serviceInterface, serviceFilter, ranking, impl, aspectProperties);
-        }
-        else
-        {
-            String factoryMethod = parser.getString(DescriptorParam.factoryMethod, "create");
-            Class<?> factoryClass = b.loadClass(factory);
-            service = dm.createAspectService(serviceInterface, serviceFilter, ranking, factoryClass, factoryMethod, aspectProperties);
-        }               
+        String implClass = parser.getString(DescriptorParam.impl);
+        Object impl = b.loadClass(implClass);
+        service = dm.createAspectService(serviceInterface, serviceFilter, ranking, impl, aspectProperties);
         setCommonServiceParams(service, parser);
         return service;
     }
@@ -371,8 +385,7 @@
         String[] adapterService = parser.getStrings(DescriptorParam.adapterService, null);
         Dictionary<String, String> adapterProperties = parser.getDictionary(DescriptorParam.adapterProperties, null);
         Class<?> adapteeService = b.loadClass(parser.getString(DescriptorParam.adapteeService));
-        String adapteeFilter = parser.getString(DescriptorParam.adapteeFilter, null);
-     
+        String adapteeFilter = parser.getString(DescriptorParam.adapteeFilter, null);     
         Service service = dm.createAdapterService(adapteeService, adapteeFilter, adapterService, adapterImpl, adapterProperties);
         setCommonServiceParams(service, parser);
         return service;
@@ -443,62 +456,56 @@
 
     /**
      * Creates a ServiceDependency that we parsed from a component descriptor "ServiceDependency" entry.
-     * @param b
-     * @param dm
-     * @param parser
-     * @param temporal true if this dependency is a temporal one, false if not.
-     * @return
-     * @throws ClassNotFoundException
      */
-    private ServiceDependency createServiceDependency(Bundle b, DependencyManager dm,
-        DescriptorParser parser, boolean temporal) throws ClassNotFoundException
+    private Dependency createServiceDependency(Bundle b, DependencyManager dm, DescriptorParser parser, boolean temporal) 
+        throws ClassNotFoundException
     {
-        ServiceDependency sd = temporal ? dm.createTemporalServiceDependency()
-            : dm.createServiceDependency();
-
-        // Set service with eventual service filter
         String service = parser.getString(DescriptorParam.service);
-        Class serviceClass = b.loadClass(service);
+        Class<?> serviceClass = b.loadClass(service);
         String serviceFilter = parser.getString(DescriptorParam.filter, null);
-        sd.setService(serviceClass, serviceFilter);
-
-        // Set default service impl
         String defaultServiceImpl = parser.getString(DescriptorParam.defaultImpl, null);
-        if (defaultServiceImpl != null)
-        {
-            Class defaultServiceImplClass = b.loadClass(defaultServiceImpl);
-            sd.setDefaultImplementation(defaultServiceImplClass);
-        }
-
-        // Set bind/unbind/rebind
+        Class<?> defaultServiceImplClass = (defaultServiceImpl != null) ? b.loadClass(defaultServiceImpl) : null;
         String added = parser.getString(DescriptorParam.added, null);
         String changed = temporal ? null : parser.getString(DescriptorParam.changed, null);
         String removed = temporal ? null : parser.getString(DescriptorParam.removed, null);
-        sd.setCallbacks(added, changed, removed);
-
-        // Set AutoConfig
         String autoConfigField = parser.getString(DescriptorParam.autoConfig, null);
+        boolean required = "true".equals(parser.getString(DescriptorParam.required, "true"));
+        String timeout = parser.getString(DescriptorParam.timeout, null);
+
+        Dependency dp = createServiceDependency(dm, temporal, serviceClass, serviceFilter,
+                                                defaultServiceImplClass, added, changed, removed,
+                                                autoConfigField, timeout, required);
+        return dp;
+    }
+    
+    private Dependency createServiceDependency(DependencyManager dm, boolean temporal, Class<?> serviceClass,
+        String serviceFilter, Class<?> defaultServiceImplClass, String added, String changed, String removed,
+        String autoConfigField, String timeout, boolean required) 
+    {
+        ServiceDependency sd = temporal ? dm.createTemporalServiceDependency()
+            : dm.createServiceDependency();
+        sd.setService(serviceClass, serviceFilter);
+        if (defaultServiceImplClass != null)
+        {
+            sd.setDefaultImplementation(defaultServiceImplClass);
+        }
+        sd.setCallbacks(added, changed, removed);
         if (autoConfigField != null)
         {
             sd.setAutoConfig(autoConfigField);
         }
-
-        // Do specific parsing for temporal service dependency
         if (temporal)
         {
             // Set the timeout value for a temporal service dependency
-            String timeout = parser.getString(DescriptorParam.timeout, null);
             if (timeout != null)
             {
                 ((TemporalServiceDependency) sd).setTimeout(Long.parseLong(timeout));
             }
-            
             // Set required flag (always true for a temporal dependency)
             sd.setRequired(true);
         } else {
             // for ServiceDependency, get required flag.
-            String required = parser.getString(DescriptorParam.required, "true");
-            sd.setRequired("true".equals(required));
+            sd.setRequired(required);
         }
         return sd;
     }
@@ -513,20 +520,23 @@
     private Dependency createConfigurationDependency(Bundle b, DependencyManager dm,
         DescriptorParser parser)
     {
-        ConfigurationDependency cd = dm.createConfigurationDependency();
         String pid = parser.getString(DescriptorParam.pid);
+        boolean propagate = "true".equals(parser.getString(DescriptorParam.propagate, "false"));
+        String callback = parser.getString(DescriptorParam.updated, "updated");
+        Dependency dp = createConfigurationDependency(dm, pid, callback, propagate);
+        return dp;
+    }
+    
+    private Dependency createConfigurationDependency(DependencyManager dm, String pid, String callback, boolean propagate) {
         if (pid == null)
         {
             throw new IllegalArgumentException(
                 "pid attribute not provided in ConfigurationDependency declaration");
         }
+        ConfigurationDependency cd = dm.createConfigurationDependency();
         cd.setPid(pid);
-
-        String propagate = parser.getString(DescriptorParam.propagate, "false");
-        cd.setPropagate("true".equals(propagate));
-
-        String callback = parser.getString(DescriptorParam.updated, "updated");
         cd.setCallback(callback);
+        cd.setPropagate(propagate);
         return cd;
     }
     
@@ -540,59 +550,60 @@
     private Dependency createBundleDependency(Bundle b, DependencyManager dm,
         DescriptorParser parser)
     {
-        BundleDependency bd = dm.createBundleDependency();
-
-        // Set add/changed/removed
         String added = parser.getString(DescriptorParam.added, null);
         String changed = parser.getString(DescriptorParam.changed, null);
         String removed = parser.getString(DescriptorParam.removed, null);
-        bd.setCallbacks(added, changed, removed);
-
-        // required
-        bd.setRequired("true".equals(parser.getString(DescriptorParam.required, "true")));
-        
-        // filter
+        boolean required = "true".equals(parser.getString(DescriptorParam.required, "true"));
         String filter = parser.getString(DescriptorParam.filter, null);
+        int stateMask = parser.getInt(DescriptorParam.stateMask, -1);
+        boolean propagate = "true".equals(parser.getString(DescriptorParam.propagate, "false"));
+        
+        Dependency dp = createBundleDependency(dm, added, changed, removed, required, propagate, filter, stateMask);
+        return dp;
+    }
+    
+    private Dependency createBundleDependency(DependencyManager dm, String added, String changed, String removed, 
+        boolean required, boolean propagate, String filter, int stateMask)
+    {
+        BundleDependency bd = dm.createBundleDependency();
+        bd.setCallbacks(added, changed, removed);
+        bd.setRequired(required);
+        bd.setPropagate(propagate);
         if (filter != null) 
         {
             bd.setFilter(filter);
         }
-        
-        // stateMask
-        int stateMask = parser.getInt(DescriptorParam.stateMask, -1);
         if (stateMask != -1) 
         {
             bd.setStateMask(stateMask);
         }
-
-        // propagate
-        bd.setPropagate("true".equals(parser.getString(DescriptorParam.propagate, "false")));
-        return bd;
+        return bd;        
     }
 
-    private Dependency createResourceDependency(Bundle b, DependencyManager dm,
+    private Dependency createResourceDependency(@SuppressWarnings("unused") Bundle b, DependencyManager dm,
         DescriptorParser parser)
     {
-        ResourceDependency rd = dm.createResourceDependency();
-
-        // Set add/changed/removed
         String added = parser.getString(DescriptorParam.added, null);
         String changed = parser.getString(DescriptorParam.changed, null);
         String removed = parser.getString(DescriptorParam.removed, null);
-        rd.setCallbacks(added, changed, removed);
-
-        // required
-        rd.setRequired("true".equals(parser.getString(DescriptorParam.required, "true")));
-        
-        // filter
         String filter = parser.getString(DescriptorParam.filter, null);
+        boolean required = "true".equals(parser.getString(DescriptorParam.required, "true"));
+        boolean propagate = "true".equals(parser.getString(DescriptorParam.propagate, "false"));
+
+        Dependency dp = createResourceDependency(dm, added, changed, removed, required, filter, propagate);
+        return dp;
+    }
+    
+    private Dependency createResourceDependency(DependencyManager dm, String added, String changed, String removed, boolean required, String filter, boolean propagate)
+    {
+        ResourceDependency rd = dm.createResourceDependency();
+        rd.setCallbacks(added, changed, removed);
+        rd.setRequired(required);
         if (filter != null) 
         {
             rd.setFilter(filter);
         }
-        
-        // propagate
-        rd.setPropagate("true".equals(parser.getString(DescriptorParam.propagate, "false")));
+        rd.setPropagate(propagate);
         return rd;
     }
 }
\ No newline at end of file
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DescriptorParam.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DescriptorParam.java
index f1e7e66..c208a9a 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DescriptorParam.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DescriptorParam.java
@@ -47,12 +47,6 @@
     /* Service attribute for the provided service properties (the parsed value is a Hashtable) */
     properties,
 
-    /* Service attribute for the factory class name (the parsed value is a String) */
-    factory,
-
-    /* Service attribute for the factory method name (the parsed value is a String) */
-    factoryMethod,
-
     /* Service attribute for the composition method name (the parsed value is a String) */
     composition,
 
@@ -111,56 +105,11 @@
     ranking,
     
     /* The factory pid of an FactoryConfigurationAdapterService annotation (the parsed value is a string) */
-    factoryPid;
+    factoryPid,    
     
-    /**
-     * Indicates if a given attribute is a Service attribute.
-     * @param attr a Descriptor attribute
-     * @return true if the descriptor is a Service attribute, false if not
-     */
-    public static boolean isServiceAttribute(DescriptorParam attr) {
-        return serviceAttribute.contains(attr);
-    }
+    /* the factory attribute for the Service annotation (the parsed value is a string) */
+    factory,
     
-    /**
-     * Indicates if a given attribute is a ServiceDependency attribute.
-     * @param attr a Descriptor attribute
-     * @return true if the descriptor is a Service attribute, false if not
-     */
-    public static boolean isServiceDepependencyAttribute(DescriptorParam attr) {
-        return serviceDependencyAttribute.contains(attr);
-    }
-
-    /**
-     * Indicates if a given attribute is a TemporalServiceDependency attribute.
-     * @param attr a Descriptor attribute
-     * @return true if the descriptor is a Temporal Service attribute, false if not
-     */
-    public static boolean isTemporalServiceDepependencyAttribute(DescriptorParam attr) {
-        return serviceDependencyAttribute.contains(attr) || attr == timeout;
-    }
-
-    /**
-     * Indicates if a given attribute is a ServiceDependency attribute.
-     * @param attr a Descriptor attribute
-     * @return true if the descriptor is a Service attribute, false if not
-     */
-    public static boolean isConfigurationDepependencyAttribute(DescriptorParam attr) {
-        return configurationDependencyAttribute.contains(attr);
-    }
-
-    /**
-     * List of Service attributes
-     */
-    private final static EnumSet serviceAttribute = EnumSet.range(init, factoryMethod);
-
-    /**
-     * List of ServiceDependency attributes
-     */
-    private final static EnumSet serviceDependencyAttribute = EnumSet.range(service, autoConfig);
-
-    /**
-     * List of ConfigurationDependency attributes
-     */
-    private final static EnumSet configurationDependencyAttribute = EnumSet.range(pid, updated);
+    /* the factoryConfigure attribute for the Service annotation (the parsed value is a string) */
+    factoryConfigure
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceFactory.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceFactory.java
new file mode 100644
index 0000000..b37c5c7
--- /dev/null
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceFactory.java
@@ -0,0 +1,552 @@
+/*
+ * 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.felix.dm.runtime;
+
+import java.lang.reflect.Method;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.dependencies.Dependency;
+import org.apache.felix.dm.service.Service;
+
+/**
+ * This class implements a <code>java.util.Set</code> which acts as a service factory.
+ * When a <code>Service</annotation> contains a <code>factory</code> attribute, this class is provided
+ * into the OSGi registry with a <code>dm.factory.name</code> service property. So, another factory component
+ * may be injected with this Set. And each time a Dictionary configuration is registered in the Set,
+ * then a new Service instance will be instantiated, and will be provided with the Dictionary passed to the
+ * Service instance.
+ */
+@SuppressWarnings( { "unchecked" })
+public class ServiceFactory extends AbstractSet<Dictionary>
+{
+    /**
+     * The actual Service instance that is allocated for each dictionaries added in this Set.
+     */
+    private Object m_impl;
+
+    /**
+     * The Service class used to instantiate Service instances
+     */
+    private final Class<?> m_implClass;
+
+    /**
+     * The Service init lifecycle callback.
+     */
+    private final String m_init;
+
+    /**
+     * The Service start lifecycle callback.
+     */
+    private final String m_start;
+
+    /**
+     * The Service stop lifecycle callback.
+     */
+    private final String m_stop;
+
+    /**
+     * The Service destroy lifecycle callback.
+     */
+    private final String m_destroy;
+
+    /**
+     * The getComposition Service callback.
+     */
+    private final String m_composition;
+
+    /**
+     * The Service provided in the OSGi registry.
+     */
+    private final String[] m_provide;
+
+    /**factoryConfigure
+     * The properties to be provided by the Service.
+     */
+    private final Dictionary m_serviceProperties;
+
+    /**
+     * The configure Service callback used to pass configuration added in this Set.
+     */
+    private final String m_configure;
+
+    /**
+     * The map between our Dictionaries and corresponding Service instances.
+     */
+    private final ConcurrentHashMap<ServiceKey, Object> m_services = new ConcurrentHashMap<ServiceKey, Object>();
+
+    /**
+     * The list of Dependencies which are applied in the Service.
+     */
+    private final ArrayList<Dependency> m_dependencies = new ArrayList<Dependency>();
+
+    /**
+     * The DependencyManager (injected by reflection), which is used to create Service instances.
+     */
+    private DependencyManager m_dm; // Injected
+
+    /**
+     * This class is used to serialize concurrent method calls, and allow to leave our methods unsynchronized.
+     * This is required because some of our methods may invoke some Service callbacks, which must be called outside 
+     * synchronized block (in order to avoid potential dead locks).
+     */
+    private SerialExecutor m_serialExecutor = new SerialExecutor();
+
+    /**
+     * Flag used to check if our service is Active.
+     */
+    private volatile boolean m_active;
+
+    /**
+     * Flag used to check if a service is being created
+     */
+    private final static Object SERVICE_CREATING = new Object();
+
+    /**
+     * This class wraps <tt>Dictionary</tt>, allowing to store the dictionary into a Map, using
+     * reference-equality in place of object-equality when getting the Dictionary from the Map.
+     */
+    private static class ServiceKey
+    {
+        private Dictionary m_dictionary;
+
+        public ServiceKey(Dictionary dictionary)
+        {
+            m_dictionary = dictionary;
+        }
+
+        Dictionary getDictionary()
+        {
+            return m_dictionary;
+        }
+
+        @Override
+        public boolean equals(Object that)
+        {
+            return that instanceof ServiceKey ? (((ServiceKey) that).getDictionary() == m_dictionary)
+                : false;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            return System.identityHashCode(m_dictionary);
+        }
+
+        @Override
+        public String toString()
+        {
+            return Dictionary.class.getName() + "@" + System.identityHashCode(m_dictionary);
+        }
+    }
+
+    /**
+     * Sole constructor.
+     * @param impl The Service impl class
+     * @param init The init lifecyle callback
+     * @param start The start lifecyle callback
+     * @param stop The stop lifecyle callback
+     * @param destroy The destroy lifecyle callback
+     * @param composition The getComposition Service method.
+     * @param serviceProperties The Service properties
+     * @param provide The Services provided by this Service
+     * @param factoryConfigure The configure callback invoked in order to pass configurations added in this Set.
+     */
+    public ServiceFactory(Class<?> impl, String init, String start, String stop, String destroy, String composition, Dictionary serviceProperties, String[] provide, String factoryConfigure)
+    {
+        m_implClass = impl;
+        m_init = init;
+        m_start = start;
+        m_stop = stop;
+        m_destroy = destroy;
+        m_composition = composition;
+        m_serviceProperties = serviceProperties;
+        m_provide = Arrays.copyOf(provide, provide.length);
+        m_configure = factoryConfigure;
+    }
+
+    /**
+     * Method called in order to track all Dependencies added in our Service. 
+     * The ComponentManager will forward all Service Dependencies in this method and we'll attach them
+     * to all concrete Service instances (when we will create them).
+     */
+    public void addDependency(Dependency dp)
+    {
+        m_dependencies.add(dp);
+    }
+
+    /**
+     * Our Service is starting. 
+     */
+    public void start()
+    {
+        m_active = true;
+    }
+
+    /**
+     * Our Service is stopping: we have to remove all Service instances that we have created.
+     */
+    public void stop()
+    {
+        try
+        {
+            clear();
+        }
+        finally
+        {
+            m_active = false;
+        }
+    }
+
+    /**
+     * Create or Update a Service.
+     */
+    @Override
+    public boolean add(final Dictionary configuration)
+    {
+        // Check parameter validity
+        if (configuration == null)
+        {
+            throw new NullPointerException("configuration parameter can't be null");
+        }
+
+        // Check if our service is running.
+        checkServiceAvailable();
+
+        // Check if service is being created
+        ServiceKey serviceKey = new ServiceKey(configuration);
+        boolean creating = false;
+        synchronized (this)
+        {
+            if (!m_services.containsKey(serviceKey))
+            {
+                m_services.put(serviceKey, SERVICE_CREATING);
+                creating = true;
+            }
+            // Create or Update the Service.
+            m_serialExecutor.enqueue(new Runnable()
+            {
+                public void run()
+                {
+                    doAdd(configuration);
+                }
+            });
+        }
+
+        m_serialExecutor.execute();
+        return creating;
+    }
+
+    /**
+     * Another Service wants to remove an existing Service.
+     * This method is not synchronized but uses a SerialExecutor for serializing concurrent method call.
+     * (This avoid potential dead locks, especially when Service callback methods are invoked).
+     */
+    @Override
+    public boolean remove(final Object configuration)
+    {
+        // Check parameter validity.
+        if (configuration == null)
+        {
+            throw new NullPointerException("configuration parameter can't be null");
+        }
+        if (!(configuration instanceof Dictionary))
+        {
+            throw new IllegalArgumentException("configuration must be an instance of a Dictionary");
+        }
+
+        // Check if our service is active.
+        checkServiceAvailable();
+
+        // Check if service is created (or creating)
+        boolean found = m_services.containsKey(new ServiceKey((Dictionary) configuration));
+        if (found)
+        {
+            // Create or Update the Service.
+            m_serialExecutor.enqueue(new Runnable()
+            {
+                public void run()
+                {
+                    doRemove((Dictionary) configuration);
+                }
+            });
+            m_serialExecutor.execute();
+        }
+        return found;
+    }
+
+    /**
+     * Another Service wants to remove all existing Services.
+     * This method is not synchronized but uses a SerialExecutor for serializing concurrent method call.
+     * (This avoid potential dead locks, especially when Service callback methods are invoked).
+     */
+    @Override
+    public void clear()
+    {
+        if (!m_active)
+        {
+            return;
+        }
+
+        // Create or Update the Service.
+        m_serialExecutor.enqueue(new Runnable()
+        {
+            public void run()
+            {
+                doClear();
+            }
+        });
+        m_serialExecutor.execute();
+    }
+
+    /**
+     * returns the list of active Service instances configurations.
+     */
+    @Override
+    public Iterator<Dictionary> iterator()
+    {
+        throw new UnsupportedOperationException(
+            "iterator method is not supported by DependencyManager Set's service factories");
+    }
+
+    @Override
+    public String toString()
+    {
+        return ServiceFactory.class.getName() + "(" + m_services.size() + " active instances)";
+    }
+
+    /**
+     * Returns the number of active Service instances.
+     */
+    @Override
+    public int size()
+    {
+        if (!m_active)
+        {
+            return 0;
+        }
+        return m_services.size();
+    }
+
+    /**
+     * Checks if our Service is available (we are not stopped").
+     */
+    private void checkServiceAvailable()
+    {
+        if (!m_active)
+        {
+            throw new IllegalStateException("Service not available");
+        }
+    }
+
+    /**
+     * Add or create a new Service instance, given its configuration. This method is invoked by the
+     * SerialExecutor, hence it's thread safe and we'll invoke Service's callbacks without being
+     * synchronized (hence this will avoid potential dead locks).
+     */
+    private void doAdd(Dictionary configuration)
+    {
+        // Check if the service exists.
+        ServiceKey serviceKey = new ServiceKey(configuration);
+        Object service = m_services.get(serviceKey);
+        if (service == null || service == SERVICE_CREATING)
+        {
+            try
+            {
+                // Create the Service / impl
+                Service s = m_dm.createService();
+                m_impl = createServiceImpl();
+
+                // Invoke "configure" callback
+                if (m_configure != null)
+                {
+                    invokeConfigure(m_impl, m_configure, configuration);
+                }
+
+                // Create Service
+                s.setImplementation(m_impl);
+                s.setCallbacks(m_init, m_start, m_stop, m_destroy);
+                if (m_composition != null)
+                {
+                    s.setComposition(m_composition);
+                }
+                if (m_provide != null)
+                {
+                    // Merge service properties with the configuration provided by the factory.
+                    Dictionary serviceProperties = mergeSettings(m_serviceProperties, configuration);
+                    s.setInterface(m_provide, serviceProperties);
+                }
+
+                // Plug original dependencies
+                s.add((List<Dependency>) m_dependencies.clone());
+
+                // Register the Service instance, and keep track of it.
+                m_dm.add(s);
+                m_services.put(serviceKey, s);
+            }
+            catch (RuntimeException e)
+            {
+                // Make sure the SERVICE_CREATING flag is also removed
+                m_services.remove(serviceKey);
+                throw e;
+            }
+        }
+        else
+        {
+            // Reconfigure an already existing Service.
+            if (m_configure != null)
+            {
+                invokeConfigure(m_impl, m_configure, configuration);
+            }
+
+            // Update service properties
+            if (m_provide != null)
+            {
+                Dictionary settings = mergeSettings(m_serviceProperties, configuration);
+                ((Service) service).setServiceProperties(settings);
+            }
+        }
+    }
+
+    private void doRemove(Dictionary configuraton)
+    {
+        ServiceKey serviceKey = new ServiceKey(configuraton);
+        Object service = m_services.remove(serviceKey);
+        if (service != null && service != SERVICE_CREATING)
+        {
+            m_dm.remove((Service) service);
+        }
+    }
+
+    private void doClear()
+    {
+        try
+        {
+            for (Object service : m_services.values())
+            {
+                if (service instanceof Service)
+                {
+                    m_dm.remove((Service) service);
+                }
+            }
+        }
+        finally
+        {
+            m_services.clear();
+        }
+    }
+
+    /**
+     * Merge factory configuration settings with the service properties. The private factory configuration 
+     * settings are ignored. A factory configuration property is private if its name starts with a dot (".").
+     * 
+     * @param serviceProperties
+     * @param factoryConfiguration
+     * @return
+     */
+    private Dictionary mergeSettings(Dictionary serviceProperties, Dictionary factoryConfiguration)
+    {
+        Dictionary props = new Hashtable();
+
+        if (serviceProperties != null)
+        {
+            Enumeration keys = serviceProperties.keys();
+            while (keys.hasMoreElements())
+            {
+                Object key = keys.nextElement();
+                Object val = serviceProperties.get(key);
+                props.put(key, val);
+            }
+        }
+
+        Enumeration keys = factoryConfiguration.keys();
+        while (keys.hasMoreElements())
+        {
+            Object key = keys.nextElement();
+            if (!key.toString().startsWith("."))
+            {
+                // public properties are propagated
+                Object val = factoryConfiguration.get(key);
+                props.put(key, val);
+            }
+        }
+        return props;
+    }
+
+    /**
+     * Create a Service impl instance
+     */
+    private Object createServiceImpl()
+    {
+        try
+        {
+            m_impl = m_implClass.newInstance();
+            return m_impl;
+        }
+        catch (Throwable t)
+        {
+            if (t instanceof RuntimeException)
+            {
+                throw (RuntimeException) t;
+            }
+            else
+            {
+                throw new RuntimeException("Could not create Service instance for class "
+                    + m_implClass, t);
+            }
+        }
+    }
+
+    /**
+     * Invokes the configure callback method on the service instance implemenatation.
+     * @param impl
+     * @param factoryConfige
+     * @param config
+     */
+    private void invokeConfigure(Object impl, String factoryConfige, Dictionary config)
+    {
+        try
+        {
+            Method m = impl.getClass().getMethod(factoryConfige, Dictionary.class);
+            m.setAccessible(true);
+            m.invoke(impl, new Object[] { config });
+        }
+
+        catch (Throwable t)
+        {
+            if (t instanceof RuntimeException)
+            {
+                throw (RuntimeException) t;
+            }
+            else
+            {
+                throw new RuntimeException("Could not invoke method " + factoryConfige
+                    + " on object " + impl);
+            }
+        }
+    }
+}