Added the ability to dynamically configure service dependency "required" and "filter" attributes from the Service's init method

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@953578 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
index 1d81cad..da38818 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
@@ -22,7 +22,6 @@
 import java.util.List;
 
 import org.apache.felix.dm.DependencyManager;
-import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.service.Service;
 import org.osgi.framework.Bundle;
 
@@ -41,24 +40,21 @@
     }
 
     @Override
-    public void buildService(MetaData serviceMetaData,
-        List<MetaData> serviceDependencies,
-        Bundle b, DependencyManager dm) throws Exception
+    public void buildService(MetaData srvMeta, List<MetaData> depsMeta, Bundle b, DependencyManager dm)
+        throws Exception
     {
-        Class<?> adapterImpl = b.loadClass(serviceMetaData.getString(Params.impl));
-        String[] adapterService = serviceMetaData.getStrings(Params.adapterService, null);
-        Dictionary<String, Object> adapterProperties = serviceMetaData.getDictionary(Params.adapterProperties, null);
-        Class<?> adapteeService = b.loadClass(serviceMetaData.getString(Params.adapteeService));
-        String adapteeFilter = serviceMetaData.getString(Params.adapteeFilter, null);     
+        Class<?> adapterImpl = b.loadClass(srvMeta.getString(Params.impl));
+        String[] adapterService = srvMeta.getStrings(Params.adapterService, null);
+        Dictionary<String, Object> adapterProperties = srvMeta.getDictionary(Params.adapterProperties, null);
+        Class<?> adapteeService = b.loadClass(srvMeta.getString(Params.adapteeService));
+        String adapteeFilter = srvMeta.getString(Params.adapteeFilter, null);     
         Service service = dm.createAdapterService(adapteeService, adapteeFilter)
                             .setInterface(adapterService, adapterProperties)
                             .setImplementation(adapterImpl);
-        setCommonServiceParams(service, serviceMetaData);
-        for (MetaData dependencyMetaData: serviceDependencies)
-        {
-            Dependency dp = new DependencyBuilder(dependencyMetaData).build(b, dm);
-            service.add(dp);
-        }
+        service.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(service, b, dm, srvMeta, depsMeta);
+        // The dependencies will be plugged by our lifecycle handler.
+        service.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         dm.add(service);
     }
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AspectServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AspectServiceBuilder.java
index fd316f1..8fbde27 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AspectServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AspectServiceBuilder.java
@@ -22,7 +22,6 @@
 import java.util.List;
 
 import org.apache.felix.dm.DependencyManager;
-import org.apache.felix.dm.dependencies.Dependency;
 import org.apache.felix.dm.service.Service;
 import org.osgi.framework.Bundle;
 import org.osgi.service.log.LogService;
@@ -38,29 +37,27 @@
     }
 
     @Override
-    public void buildService(MetaData serviceMetaData,
-        List<MetaData> serviceDependencies,
-        Bundle b, DependencyManager dm) throws Exception
+    public void buildService(MetaData srvMeta, List<MetaData> depsMeta, Bundle b, DependencyManager dm) 
+        throws Exception
     {
-        Log.instance().log(LogService.LOG_DEBUG, "building aspect service: service metadata=" + serviceMetaData
-            + ", dependencyMetaData=" + serviceDependencies);
+        Log.instance().log(LogService.LOG_INFO,
+                           "AspectServiceBuilder: building aspect service: %s with dependencies %s", 
+                           srvMeta, depsMeta);
 
-        Class<?> serviceInterface = b.loadClass(serviceMetaData.getString(Params.service));
-        String serviceFilter = serviceMetaData.getString(Params.filter, null);
-        Dictionary<String, Object> aspectProperties = serviceMetaData.getDictionary(Params.properties, null);
-        int ranking = serviceMetaData.getInt(Params.ranking, 1);
-        String implClass = serviceMetaData.getString(Params.impl);
+        Class<?> serviceInterface = b.loadClass(srvMeta.getString(Params.service));
+        String serviceFilter = srvMeta.getString(Params.filter, null);
+        Dictionary<String, Object> aspectProperties = srvMeta.getDictionary(Params.properties, null);
+        int ranking = srvMeta.getInt(Params.ranking, 1);
+        String implClass = srvMeta.getString(Params.impl);
         Object impl = b.loadClass(implClass);        
-        String field = serviceMetaData.getString(Params.field, null);        
+        String field = srvMeta.getString(Params.field, null);        
         Service service = dm.createAspectService(serviceInterface, serviceFilter, ranking, field)
                             .setImplementation(impl)
                             .setServiceProperties(aspectProperties);
-        setCommonServiceParams(service, serviceMetaData);
-        for (MetaData dependencyMetaData: serviceDependencies)
-        {
-            Dependency dp = new DependencyBuilder(dependencyMetaData).build(b, dm);
-            service.add(dp);
-        }
+        service.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(service, b, dm, srvMeta, depsMeta);
+        // The dependencies will be plugged by our lifecycle handler.
+        service.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         dm.add(service);
     }
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
index 249c65b..8d82336 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
@@ -37,25 +37,22 @@
     }
 
     @Override
-    public void buildService(MetaData serviceMetaData,
-        List<MetaData> serviceDependencies,
-        Bundle b, DependencyManager dm) throws Exception
+    public void buildService(MetaData srvMeta, List<MetaData> depsMeta, Bundle b, DependencyManager dm) 
+        throws Exception
     {
-        int stateMask = serviceMetaData.getInt(Params.stateMask, Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE);
-        String filter = serviceMetaData.getString(Params.filter, null);
-        Class<?> adapterImpl = b.loadClass(serviceMetaData.getString(Params.impl));
-        String[] service = serviceMetaData.getStrings(Params.service, null);
-        Dictionary<String, Object> properties = serviceMetaData.getDictionary(Params.properties, null);
-        boolean propagate = "true".equals(serviceMetaData.getString(Params.propagate, "false"));
+        int stateMask = srvMeta.getInt(Params.stateMask, Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE);
+        String filter = srvMeta.getString(Params.filter, null);
+        Class<?> adapterImpl = b.loadClass(srvMeta.getString(Params.impl));
+        String[] service = srvMeta.getStrings(Params.service, null);
+        Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
+        boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
         Service srv = dm.createBundleAdapterService(stateMask, filter, propagate)
-                        .setInterface(service, properties)
-                        .setImplementation(adapterImpl);
-        setCommonServiceParams(srv, serviceMetaData);
-        for (MetaData dependencyMetaData: serviceDependencies)
-        {
-            Dependency dp = new DependencyBuilder(dependencyMetaData).build(b, dm);
-            srv.add(dp);
-        }
+                            .setInterface(service, properties)
+                            .setImplementation(adapterImpl);
+        srv.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(srv, b, dm, srvMeta, depsMeta);
+        // The dependencies will be plugged by our lifecycle handler.
+        srv.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         dm.add(srv);
     }    
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DependencyBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DependencyBuilder.java
index 1b206c3..3fdaa71 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DependencyBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DependencyBuilder.java
@@ -86,6 +86,9 @@
             case ResourceDependency:
                 dp = createResourceDependency(dm, instanceBound);
                 break;
+            
+            default:
+                throw new IllegalArgumentException("Can't build service dependency: " + type);
         }
         return dp;
     }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DependencyManagerRuntime.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DependencyManagerRuntime.java
index 92b4b62..7887ae9 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DependencyManagerRuntime.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DependencyManagerRuntime.java
@@ -84,15 +84,13 @@
     @SuppressWarnings("unchecked")
     protected void stop()
     {
-        m_log.log(LogService.LOG_INFO, "DependencyManager Runtime stopping: removing services");
+        m_log.log(LogService.LOG_INFO, "Runtime: stopping services");
 
         for (DependencyManager dm: m_managers.values())
         {
             List<Service> services = new ArrayList<Service>(dm.getServices());
             for (Service service: services)
             {
-                m_log.log(LogService.LOG_INFO, "DependencyManager Runtime stopping: removing service: "
-                    + service);
                 dm.remove(service);
             }
         }
@@ -142,7 +140,7 @@
             URL descriptorURL = b.getEntry(descriptorPath);
             if (descriptorURL == null)
             {
-                m_log.log(LogService.LOG_ERROR,
+                m_log.log(LogService.LOG_ERROR, "Runtime: " +
                           "DependencyManager component descriptor not found: " + descriptorPath);
                 continue;
             }
@@ -157,16 +155,16 @@
     @SuppressWarnings("unchecked")
     private void bundleStopping(Bundle b)
     {
-        m_log.log(LogService.LOG_INFO, "Removing services from stopping bundle: " + b.getSymbolicName());
+        m_log.log(LogService.LOG_INFO, "Runtime: Removing services from stopping bundle: " + b.getSymbolicName());
         DependencyManager dm = m_managers.remove(b);
         if (dm != null)
         {
             List<Service> services = new ArrayList(dm.getServices());
-            for (Service service: services)
+            for (Service service : services)
             {
-                m_log.log(LogService.LOG_INFO, "Removing service service: " + service);
+                m_log.log(LogService.LOG_INFO, "Runtime: Removing service: " + service);
                 dm.remove(service);
-            }
+            }            
         }
     }
 
@@ -177,7 +175,7 @@
      */
     private void loadDescriptor(Bundle b, URL descriptorURL)
     {
-        m_log.log(LogService.LOG_DEBUG, "Parsing descriptor " + descriptorURL
+        m_log.log(LogService.LOG_DEBUG, "Runtime: ++++ Parsing descriptor " + descriptorURL
             + " from bundle " + b.getSymbolicName());
 
         BufferedReader in = null;
@@ -197,7 +195,7 @@
 
         catch (Throwable t)
         {
-            m_log.log(LogService.LOG_ERROR, "Error while parsing descriptor "
+            m_log.log(LogService.LOG_ERROR, "Runtime: Error while parsing descriptor "
                 + descriptorURL + " from bundle " + b.getSymbolicName(), t);
         }
 
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DescriptorParser.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DescriptorParser.java
index 81728f8..0da39e5 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DescriptorParser.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/DescriptorParser.java
@@ -31,7 +31,8 @@
 
 /**
  * This class parses files generated in OSGI-INF/*.dm by the DependencyManager bnd plugin.
- * Each descriptor contains a JSON definition of a Service, along with its corresponding service dependency or configuration dependencies.
+ * Each descriptor contains a JSON definition of a Service, along with its corresponding  
+ * dependencies.
  */
 public class DescriptorParser
 {
@@ -48,7 +49,7 @@
 
         // The first line is a Service Component (a Service, an Aspect Service, etc ...)
         line = reader.readLine();
-        Log.instance().log(LogService.LOG_DEBUG, "Parsing destriptor entry line: " + line);
+        Log.instance().log(LogService.LOG_DEBUG, "DescriptorParser: parsing service %s", line);
         JSONObject json = new JSONObject(line);
         JSONMetaData serviceMetaData = new JSONMetaData(json);
 
@@ -64,7 +65,7 @@
         List<MetaData> serviceDependencies = new ArrayList<MetaData>();
         while ((line = reader.readLine()) != null)
         {
-            Log.instance().log(LogService.LOG_DEBUG, "Parsing destriptor entry line: " + line);
+            Log.instance().log(LogService.LOG_DEBUG, "Parsing dependency Ms", line);
             JSONObject dep = new JSONObject(line);
             serviceDependencies.add(new JSONMetaData(dep));
         }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java
index b499dec..6994ffc 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java
@@ -37,25 +37,22 @@
     }
 
     @Override
-    public void buildService(MetaData serviceMetaData,
-        List<MetaData> serviceDependencies,
-        Bundle b, DependencyManager dm) throws Exception
+    public void buildService(MetaData srvMeta, List<MetaData> depsMeta, Bundle b, DependencyManager dm) 
+        throws Exception
     {
-        Class<?> impl = b.loadClass(serviceMetaData.getString(Params.impl));
-        String factoryPid = serviceMetaData.getString(Params.factoryPid);
-        String updated = serviceMetaData.getString(Params.updated);
-        String[] services = serviceMetaData.getStrings(Params.service, null);
-        Dictionary<String, Object> properties = serviceMetaData.getDictionary(Params.properties, null);
-        boolean propagate = "true".equals(serviceMetaData.getString(Params.propagate, "false"));
+        Class<?> impl = b.loadClass(srvMeta.getString(Params.impl));
+        String factoryPid = srvMeta.getString(Params.factoryPid);
+        String updated = srvMeta.getString(Params.updated);
+        String[] services = srvMeta.getStrings(Params.service, null);
+        Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
+        boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
         Service srv = dm.createFactoryConfigurationAdapterService(factoryPid, updated, propagate)
                         .setInterface(services, properties)
                         .setImplementation(impl);
-        setCommonServiceParams(srv, serviceMetaData);
-        for (MetaData dependencyMetaData: serviceDependencies)
-        {
-            Dependency dp = new DependencyBuilder(dependencyMetaData).build(b, dm);
-            srv.add(dp);
-        }
+        srv.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(srv, b, dm, srvMeta, depsMeta);
+        // The dependencies will be plugged by our lifecycle handler.
+        srv.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         dm.add(srv);
     }    
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Log.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Log.java
index 9739e1a..68999c5 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Log.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Log.java
@@ -18,10 +18,12 @@
  */
 package org.apache.felix.dm.runtime;
 
-import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
-public class Log implements LogService
+/**
+ * This class logs some formattable strings into the OSGi Log Service.
+ */
+public class Log
 {
     /** The log service */
     private LogService m_logService;
@@ -37,24 +39,14 @@
     public void setLogService(LogService logService) {
         m_logService = logService;
     }
+        
+    public void log(int level, String format, Object ... args) 
+    {
+        m_logService.log(level, String.format(format, args));
+    }
     
-    public void log(int level, String message, Throwable exception)
+    public void log(int level, String format, Throwable t, Object ... args) 
     {
-        m_logService.log(level, message, exception);
-    }
-
-    public void log(int level, String message)
-    {
-        m_logService.log(level, message);
-    }
-
-    public void log(ServiceReference sr, int level, String message, Throwable exception)
-    {
-        m_logService.log(sr, level, message, exception);
-    }
-
-    public void log(ServiceReference sr, int level, String message)
-    {
-        m_logService.log(sr, level, message);
+        m_logService.log(level, String.format(format, args), t);
     }
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/MetaData.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/MetaData.java
index 166a006..e87220d 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/MetaData.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/MetaData.java
@@ -84,4 +84,9 @@
      * Modifies a String[] value.
      */
     void setDictionary(Params key, Dictionary<String, Object> dictionary);
+    
+    /**
+     * Clone this MetaData object.
+     */
+    Object clone() throws CloneNotSupportedException;
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java
index f281b1e..6ae100a 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java
@@ -37,24 +37,21 @@
     }
 
     @Override
-    public void buildService(MetaData serviceMetaData,
-        List<MetaData> serviceDependencies,
-        Bundle b, DependencyManager dm) throws Exception
+    public void buildService(MetaData srvMeta, List<MetaData> depsMeta, Bundle b, DependencyManager dm) 
+        throws Exception
     {
-        String filter = serviceMetaData.getString(Params.filter, null);
-        Class<?> impl = b.loadClass(serviceMetaData.getString(Params.impl));
-        String[] service = serviceMetaData.getStrings(Params.service, null);
-        Dictionary<String, Object> properties = serviceMetaData.getDictionary(Params.properties, null);
-        boolean propagate = "true".equals(serviceMetaData.getString(Params.propagate, "false"));
+        String filter = srvMeta.getString(Params.filter, null);
+        Class<?> impl = b.loadClass(srvMeta.getString(Params.impl));
+        String[] service = srvMeta.getStrings(Params.service, null);
+        Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
+        boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
         Service srv = dm.createResourceAdapterService(filter, propagate)
                         .setInterface(service, properties)
                         .setImplementation(impl);
-        setCommonServiceParams(srv, serviceMetaData);
-        for (MetaData dependencyMetaData: serviceDependencies)
-        {
-            Dependency dp = new DependencyBuilder(dependencyMetaData).build(b, dm);
-            srv.add(dp);
-        }
+        srv.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(srv, b, dm, srvMeta, depsMeta);
+        // The dependencies will be plugged by our lifecycle handler.
+        srv.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         dm.add(srv);
     }    
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java
index 86d0039..a6d5245 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java
@@ -32,6 +32,7 @@
 public class ServiceBuilder extends ServiceComponentBuilder
 {
     private final static String TYPE = "Service";
+    private final static String DM_FACTORY_NAME = "dm.factory.name";
 
     @Override
     public String getType()
@@ -40,72 +41,44 @@
     }
 
     @Override
-    public void buildService(MetaData srvMeta, List<MetaData> srvDeps, Bundle b, DependencyManager dm)
+    public void buildService(MetaData srvMeta, List<MetaData> depsMeta, Bundle b, DependencyManager dm)
         throws Exception
     {
-        Log.instance().log(LogService.LOG_DEBUG, "building service: service metadata=" + srvMeta
-            + ", dependencyMetaData=" + srvDeps);
-
-        // Get service parameters (lifecycle callbacks, composition, factory, etc ...)
-
         Service service = dm.createService();
         String factory = srvMeta.getString(Params.factory, null);
-        String factoryConfigure = srvMeta.getString(Params.factoryConfigure, null);
-        String impl = srvMeta.getString(Params.impl);
-        String init = srvMeta.getString(Params.init, null);
-        String start = srvMeta.getString(Params.start, null);
-        String stop = srvMeta.getString(Params.stop, null);
-        String destroy = srvMeta.getString(Params.destroy, null);
-        String composition = srvMeta.getString(Params.composition, null);
-        Dictionary<String, Object> serviceProperties = srvMeta.getDictionary(Params.properties, null);
-        String[] provide = srvMeta.getStrings(Params.provide, null);
 
         // Check if we must provide a Set Factory.
         if (factory == null)
         {
-            // No: instantiate the service.
-            service.setImplementation(b.loadClass(impl));
-            if (composition != null)
-            {
-                service.setComposition(composition);
-            }
-            if (provide != null)
-            {
-                service.setInterface(provide, serviceProperties);
-            }
+            Log.instance().log(LogService.LOG_INFO, 
+                               "ServiceBuilder: building service %s with dependencies %s",
+                               srvMeta, depsMeta);
 
+            String impl = srvMeta.getString(Params.impl);
+            String composition = srvMeta.getString(Params.composition, null);
+            Dictionary<String, Object> serviceProperties = srvMeta.getDictionary(Params.properties, null);
+            String[] provide = srvMeta.getStrings(Params.provide, null);
+            service.setImplementation(b.loadClass(impl));
+            service.setComposition(composition);
+            service.setInterface(provide, serviceProperties);
             // Creates a ServiceHandler, which will filter all service lifecycle callbacks.
-            /*
-            ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(service, b, dm, srvMeta,
-                                                                               srvDeps);
+            ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(service, b, dm, srvMeta, depsMeta);
             service.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
-            String confDependency = DependencyBuilder.DependencyType.ConfigurationDependency.toString();
-            */
-            // TODO REMOVE
-            for (MetaData depMeta: srvDeps)
-            {
-                Dependency dp = new DependencyBuilder(depMeta).build(b, dm);
-                service.add(dp);
-            }
         }
         else
         {
+            Log.instance().log(LogService.LOG_INFO, 
+                               "ServiceBuilder: providing factory set for service %s with dependencies %s",
+                               srvMeta, depsMeta);
+
             // We don't instantiate the service, but instead we provide a Set in the registry.
             // This Set will act as a factory and another component may registers some
             // service configurations into it in order to fire some service instantiations.
-
-            ServiceFactory serviceFactory =  new ServiceFactory(b.loadClass(impl), init, start, stop, destroy, 
-                                                                composition, serviceProperties, provide, 
-                                                                factoryConfigure);
-            for (MetaData dependencyMetaData: srvDeps)
-            {
-                Dependency dp = new DependencyBuilder(dependencyMetaData).build(b, dm);
-                serviceFactory.addDependency(dp);
-            }
+            ServiceFactory serviceFactory =  new ServiceFactory(b, srvMeta, depsMeta);
             service.setImplementation(serviceFactory);
             service.setCallbacks(null, "start", "stop", null);
             Hashtable<String, String> props = new Hashtable<String, String>();
-            props.put("dm.factory.name", factory);
+            props.put(DM_FACTORY_NAME, factory);
             service.setInterface(Set.class.getName(), props);
         }
 
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
index b37c5c7..fdfa731 100644
--- 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
@@ -20,8 +20,6 @@
 
 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;
@@ -30,8 +28,9 @@
 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;
+import org.osgi.framework.Bundle;
+import org.osgi.service.log.LogService;
 
 /**
  * This class implements a <code>java.util.Set</code> which acts as a service factory.
@@ -50,41 +49,11 @@
     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;
@@ -102,7 +71,12 @@
     /**
      * The list of Dependencies which are applied in the Service.
      */
-    private final ArrayList<Dependency> m_dependencies = new ArrayList<Dependency>();
+    private MetaData m_srvMeta;
+
+    /**
+     * The list of Dependencies which are applied in the Service.
+     */
+    private List<MetaData> m_depsMeta;
 
     /**
      * The DependencyManager (injected by reflection), which is used to create Service instances.
@@ -122,6 +96,11 @@
     private volatile boolean m_active;
 
     /**
+     * The bundle containing the Service annotated with the factory attribute.
+     */
+    private Bundle m_bundle;
+    
+    /**
      * Flag used to check if a service is being created
      */
     private final static Object SERVICE_CREATING = new Object();
@@ -166,37 +145,20 @@
 
     /**
      * 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 b the bundle containing the Service annotated with the factory attribute
+     * @param impl The Service implementation class
      * @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)
+    public ServiceFactory(Bundle b, MetaData srvMeta, List<MetaData> depsMeta)
     {
-        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);
+        m_serviceProperties = srvMeta.getDictionary(Params.properties, null);;
+        m_provide = srvMeta.getStrings(Params.provide, null);
+        m_configure = srvMeta.getString(Params.factoryConfigure, null);
+        m_bundle = b;
+        m_srvMeta = srvMeta;
+        m_depsMeta = depsMeta;
     }
 
     /**
@@ -379,7 +341,8 @@
             {
                 // Create the Service / impl
                 Service s = m_dm.createService();
-                m_impl = createServiceImpl();
+                Class implClass = m_bundle.loadClass(m_srvMeta.getString(Params.impl));
+                m_impl = implClass.newInstance();
 
                 // Invoke "configure" callback
                 if (m_configure != null)
@@ -389,30 +352,28 @@
 
                 // 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());
+                
+                s.setComposition(m_srvMeta.getString(Params.composition, null));
+                ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(s, m_bundle, m_dm, m_srvMeta, m_depsMeta);
+                // The dependencies will be plugged by our lifecycle handler.
+                s.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
 
                 // Register the Service instance, and keep track of it.
+                Log.instance().log(LogService.LOG_INFO, "ServiceFactory: created service %s", m_srvMeta);
                 m_dm.add(s);
                 m_services.put(serviceKey, s);
             }
-            catch (RuntimeException e)
+            catch (Throwable t)
             {
                 // Make sure the SERVICE_CREATING flag is also removed
                 m_services.remove(serviceKey);
-                throw e;
+                Log.instance().log(LogService.LOG_ERROR, "ServiceFactory: could not instantiate service %s", t, m_srvMeta);
             }
         }
         else
@@ -420,6 +381,7 @@
             // Reconfigure an already existing Service.
             if (m_configure != null)
             {
+                Log.instance().log(LogService.LOG_INFO, "ServiceFactory: updating service %s", m_impl);
                 invokeConfigure(m_impl, m_configure, configuration);
             }
 
@@ -434,6 +396,7 @@
 
     private void doRemove(Dictionary configuraton)
     {
+        Log.instance().log(LogService.LOG_INFO, "ServiceFactory: removing service %s", m_srvMeta);
         ServiceKey serviceKey = new ServiceKey(configuraton);
         Object service = m_services.remove(serviceKey);
         if (service != null && service != SERVICE_CREATING)
@@ -480,7 +443,7 @@
                 Object key = keys.nextElement();
                 Object val = serviceProperties.get(key);
                 props.put(key, val);
-            }
+            }        
         }
 
         Enumeration keys = factoryConfiguration.keys();
@@ -498,30 +461,6 @@
     }
 
     /**
-     * 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
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
index e8cc435..7f79a26 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
@@ -21,20 +21,68 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.dependencies.BundleDependency;
+import org.apache.felix.dm.dependencies.ConfigurationDependency;
 import org.apache.felix.dm.dependencies.Dependency;
+import org.apache.felix.dm.dependencies.ResourceDependency;
+import org.apache.felix.dm.dependencies.ServiceDependency;
+import org.apache.felix.dm.dependencies.TemporalServiceDependency;
 import org.apache.felix.dm.service.Service;
 import org.osgi.framework.Bundle;
+import org.osgi.service.log.LogService;
 
 /**
- * This class acts as a service implementation lifecycle handler. If the actual service implementation
- * init method returns a Map, then this map will is inspected for dependency filters, which will be 
- * applied to the dependencies specified in the service.
+ * Allow Services to configure dynamically their dependency filters from their init() method.
+ * Basically, this class acts as a service implementation lifecycle handler. When we detect that the Service is
+ * called in its init() method, and if its init() method returns a Map, then the Map is assumed to contain
+ * dependency filters, which will be applied to all service dependencies. The Map optionally returned by
+ * Service's init method has to contains the following keys:
+ * <ul>
+ *   <li>name.filter: the value must be a valid OSGi filter. the "name" prefix must match a ServiceDependency 
+ *   name attribute</li>
+ *   <li>name.required: the value is a boolean ("true"|"false") and must the "name" prefix must match a 
+ *   ServiceDependency name attribute</li>
+ * </ul>
+ * 
+ * Example of a Service whose dependency filter is configured from ConfigAdmin:
+ * 
+ * <blockquote>
+ * 
+ * <pre>
+ *  &#47;**
+ *    * All Service whose service dependency filter/require attribute may be configured from ConfigAdmin
+ *    *&#47;
+ *  &#64;Service
+ *  class X {
+ *      private Dictionary m_config;
+ *      
+ *      @ConfigurationDependency(pid="MyPid")
+ *      void configure(Dictionary conf) {
+ *           // Initialize our service from config ...
+ *           
+ *           // And store the config for late usage (from our init method)
+ *           m_config = config;
+ *      }
+ * 
+ *      &#64;Init
+ *      Map init() {
+ *          return new HashMap() {{
+ *              put("dependency1.filter", m_config.get("filter"));
+ *              put("dependency1.required", m_config.get("required"));
+ *          }};
+ *      } 
+ *      
+ *      &#64;ServiceDependency(name="dependency1") 
+ *      void bindOtherService(OtherService other) {
+ *         // the filter and required flag will be configured from our init method.
+ *      }
+ *  }
  */
 public class ServiceLifecycleHandler
 {
@@ -42,86 +90,115 @@
     private String m_start;
     private String m_stop;
     private String m_destroy;
-    private List<MetaData> m_dependencies = new ArrayList<MetaData>();
-    private Map<String, MetaData> m_namedDependencies = new HashMap<String, MetaData>();
+    private MetaData m_srvMeta;
+    private List<MetaData> m_depsMeta;
+    private List<Dependency> m_deps = new ArrayList<Dependency>();
     private Bundle m_bundle;
 
     public ServiceLifecycleHandler(Service srv, Bundle srvBundle, DependencyManager dm,
-                                   MetaData srvMetaData, List<MetaData> srvDep)
+                                   MetaData srvMeta, List<MetaData> depMeta)
         throws Exception
     {
-        m_init = srvMetaData.getString(Params.init, null);
-        m_start = srvMetaData.getString(Params.start, null);
-        m_stop = srvMetaData.getString(Params.stop, null);
-        m_destroy = srvMetaData.getString(Params.destroy, null);
+        m_srvMeta = srvMeta;
+        m_init = srvMeta.getString(Params.init, null);
+        m_start = srvMeta.getString(Params.start, null);
+        m_stop = srvMeta.getString(Params.stop, null);
+        m_destroy = srvMeta.getString(Params.destroy, null);
         m_bundle = srvBundle;
 
+        // Plug configuration dependencies now, and remove them from the dependency list.
+        // (we want these dependencies to be injected before the init method).
+        
         String confDependency = DependencyBuilder.DependencyType.ConfigurationDependency.toString();
-        for (MetaData depMeta: srvDep)
+        Iterator<MetaData> dependencies = depMeta.iterator();
+        while (dependencies.hasNext()) 
         {
-            if (depMeta.getString(Params.type).equals(confDependency))
+            MetaData dependency = dependencies.next();
+            if (dependency.getString(Params.type).equals(confDependency))
             {
-                // Register Configuration dependencies now
-                Dependency dp = new DependencyBuilder(depMeta).build(m_bundle, dm);
+                // Register Configuration dependency now.
+                Dependency dp = new DependencyBuilder(dependency).build(m_bundle, dm);
                 srv.add(dp);
-            }
-            else
-            {
-                String name = depMeta.getString(Params.name, null);
-                if (name != null)
-                {
-                    m_namedDependencies.put(name, depMeta);
-                }
-                else
-                {
-                    m_dependencies.add(depMeta);
-                }
+                dependencies.remove();
             }
         }
-
+        
+        m_depsMeta = depMeta;
     }
 
     @SuppressWarnings("unchecked")
     public void init(Object serviceInstance, DependencyManager dm, Service service)
         throws Exception
     {
-        // Invoke the service instance actual init method.
-        Object o = invokeMethod(serviceInstance, m_init, dm, service);
-
-        // If the init method returned a Map, then apply all filters found from it into
-        // the service dependencies. Keys = Dependency name / values = Dependency filter
-        if (o != null && Map.class.isAssignableFrom(o.getClass()))
+        // Invoke the service instance init method, and check if it returns a dependency
+        // customization map. This map will be used to configure some dependency filters
+        // (or required flag).
+        Object o = invokeMethod(serviceInstance, m_init, dm, service);      
+        Map<String, String> customization = (o != null && Map.class.isAssignableFrom(o.getClass())) ?
+            (Map<String, String>) o : new HashMap<String, String>();
+       
+        Log.instance().log(LogService.LOG_DEBUG,
+                           "ServiceLifecycleHandler.init: invoked init method from service %s " +
+                           ", returned map: %s", serviceInstance, customization); 
+                                 
+        for (MetaData dependency : m_depsMeta) 
         {
-            Map<String, String> filters = (Map<String, String>) o;
-            for (Map.Entry<String, String> entry: filters.entrySet())
+            // Check if this dependency has a name, and if we find the name from the 
+            // customization map, then apply filters and required flag from the map into it.
+            
+            String name = dependency.getString(Params.name, null);
+            if (name != null)
             {
-                String name = entry.getKey();
-                String filter = entry.getValue();
-
-                MetaData dependency = m_namedDependencies.remove(name);
-                if (dependency != null)
-                {
-                    dependency.setString(Params.filter, filter);
-                    DependencyBuilder depBuilder = new DependencyBuilder(dependency);
-                    Dependency d = depBuilder.build(m_bundle, dm, true);
-                    service.add(d);
-                }
-                else
-                {
-                    throw new IllegalArgumentException("Invalid filter Map: the filter key " + name
-                        + " does not correspond " +
-                        " to a known Dependency.");
+                String filter = customization.get(name + ".filter");
+                String required = customization.get(name + ".required");
+                		
+                if (filter != null || required != null) {
+                    dependency = (MetaData) dependency.clone();
+                    if (filter != null) 
+                    {
+                        dependency.setString(Params.filter, filter);
+                    }
+                    if (required != null)
+                    {
+                        dependency.setString(Params.required, required);
+                    }
                 }
             }
+            DependencyBuilder depBuilder = new DependencyBuilder(dependency);
+            Log.instance().log(LogService.LOG_INFO, 
+                               "ServiceLifecycleHandler.init: adding dependency %s into service %s",
+                               dependency, m_srvMeta);
+            Dependency d = depBuilder.build(m_bundle, dm, true);
+            m_deps.add(d);
+            service.add(d);
         }
-
-        plugDependencies(m_namedDependencies.values(), dm, service);
-        plugDependencies(m_dependencies, dm, service);
     }
 
     public void start(Object serviceInstance, DependencyManager dm, Service service)
         throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
     {
+        // Remove "instance bound" flag from all dependencies, because we want to be deactivated
+        // once we lose one of the deps ...
+        Iterator it = m_deps.iterator();
+        while (it.hasNext())
+        {
+            Dependency d = (Dependency) it.next();
+            if (d instanceof ServiceDependency) {
+                ((ServiceDependency)d).setInstanceBound(false);
+            } else if (d instanceof BundleDependency)
+            {
+                ((BundleDependency)d).setInstanceBound(false);
+            } else  if (d instanceof ResourceDependency) 
+            {
+                ((ResourceDependency) d).setInstanceBound(false);
+            } else if (d instanceof ConfigurationDependency) 
+            {
+                ((ConfigurationDependency) d).setInstanceBound(false);
+            } else if (d instanceof TemporalServiceDependency) 
+            {
+                ((TemporalServiceDependency) d).setInstanceBound(false);
+            }
+        }
         invokeMethod(serviceInstance, m_start, dm, service);
     }
 
@@ -141,18 +218,18 @@
         throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
     {
         return invokeMethod(serviceInstance,
-            method,
-            new Class[][] {
-                            { Object.class, DependencyManager.class, Service.class },
-                            { DependencyManager.class, Service.class },
-                            { Object.class },
-                            {}
+                            method,
+                            new Class[][] {
+                                    { Object.class, DependencyManager.class, Service.class },
+                                    { DependencyManager.class, Service.class },
+                                    { Object.class },
+                                    {}
             },
-            new Object[][] {
-                            { serviceInstance, dm, service },
-                            { dm, service },
-                            { serviceInstance },
-                            {}
+                            new Object[][] {
+                                    { serviceInstance, dm, service },
+                                    { dm, service },
+                                    { serviceInstance },
+                                    {}
             });
     }
 
@@ -189,15 +266,4 @@
 
         return null;
     }
-
-    private void plugDependencies(Collection<MetaData> dependencies, DependencyManager dm, Service service)
-        throws Exception
-    {
-        for (MetaData dependency: dependencies)
-        {
-            DependencyBuilder depBuilder = new DependencyBuilder(dependency);
-            Dependency d = depBuilder.build(m_bundle, dm, true);
-            service.add(d);
-        }
-    }
 }