FELIX-4869: Fixed comments.
FELIX-4875 - Update DM integration test with latest ConfigAdmin.
FELIX-4876: DM Annotations bnd plugin compatible with Bndtools 2.4.1 / 3.0.0 versions.
FELIX-4877: DM Annotations should detect service type using all possible DM API bind signatures.
FELIX-4878: Support more signatures for Dependency callbacks.
FELIX-4879 ConfigurationDependency should always "need instance".
FELIX-4880: Missing support for callback instance for some adapters.

Also did sone cleanup in some sample codes. Fixed some README typos.
The DM API is now exported with 4.1.0 version.



git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1677674 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/cnf/localrepo/index.xml b/dependencymanager/cnf/localrepo/index.xml
index 51ad4f1..f1808d8 100644
--- a/dependencymanager/cnf/localrepo/index.xml
+++ b/dependencymanager/cnf/localrepo/index.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<repository increment="1430261259438" name="Local" xmlns="http://www.osgi.org/xmlns/repository/v1.0.0">
+<repository increment="1430498223597" name="Local" xmlns="http://www.osgi.org/xmlns/repository/v1.0.0">
   <resource>
     <capability namespace="osgi.identity">
       <attribute name="osgi.identity" value="de.twentyeleven.skysail.org.json-osgi"/>
@@ -31,40 +31,40 @@
     <capability namespace="osgi.identity">
       <attribute name="osgi.identity" value="org.apache.felix.configadmin"/>
       <attribute name="type" value="osgi.bundle"/>
-      <attribute name="version" type="Version" value="1.8.1.SNAPSHOT"/>
+      <attribute name="version" type="Version" value="1.8.4"/>
     </capability>
     <capability namespace="osgi.content">
-      <attribute name="osgi.content" value="a55e3603a99d81086996622e03ed3cac324b5de469db681acef99ebcb0ab89c7"/>
-      <attribute name="url" value="org.apache.felix.configadmin/org.apache.felix.configadmin-1.8.1.jar"/>
-      <attribute name="size" type="Long" value="120333"/>
+      <attribute name="osgi.content" value="31f1a7d770288b798234ad1b3f2a4a8fcbf3095a513d8927a47516b96a8d4cf4"/>
+      <attribute name="url" value="org.apache.felix.configadmin/org.apache.felix.configadmin-1.8.4.jar"/>
+      <attribute name="size" type="Long" value="128897"/>
       <attribute name="mime" value="application/vnd.osgi.bundle"/>
     </capability>
     <capability namespace="osgi.wiring.bundle">
       <attribute name="osgi.wiring.bundle" value="org.apache.felix.configadmin"/>
-      <attribute name="bundle-version" type="Version" value="1.8.1.SNAPSHOT"/>
+      <attribute name="bundle-version" type="Version" value="1.8.4"/>
     </capability>
     <capability namespace="osgi.wiring.host">
       <attribute name="osgi.wiring.host" value="org.apache.felix.configadmin"/>
-      <attribute name="bundle-version" type="Version" value="1.8.1.SNAPSHOT"/>
+      <attribute name="bundle-version" type="Version" value="1.8.4"/>
     </capability>
     <capability namespace="osgi.wiring.package">
       <attribute name="osgi.wiring.package" value="org.apache.felix.cm"/>
       <attribute name="version" type="Version" value="1.0.0"/>
       <attribute name="bundle-symbolic-name" value="org.apache.felix.configadmin"/>
-      <attribute name="bundle-version" type="Version" value="1.8.1.SNAPSHOT"/>
+      <attribute name="bundle-version" type="Version" value="1.8.4"/>
     </capability>
     <capability namespace="osgi.wiring.package">
       <attribute name="osgi.wiring.package" value="org.apache.felix.cm.file"/>
       <attribute name="version" type="Version" value="1.0.0"/>
       <attribute name="bundle-symbolic-name" value="org.apache.felix.configadmin"/>
-      <attribute name="bundle-version" type="Version" value="1.8.1.SNAPSHOT"/>
+      <attribute name="bundle-version" type="Version" value="1.8.4"/>
       <directive name="uses" value="org.apache.felix.cm,org.osgi.framework"/>
     </capability>
     <capability namespace="osgi.wiring.package">
       <attribute name="osgi.wiring.package" value="org.osgi.service.cm"/>
       <attribute name="version" type="Version" value="1.5.0"/>
       <attribute name="bundle-symbolic-name" value="org.apache.felix.configadmin"/>
-      <attribute name="bundle-version" type="Version" value="1.8.1.SNAPSHOT"/>
+      <attribute name="bundle-version" type="Version" value="1.8.4"/>
       <directive name="uses" value="org.osgi.framework"/>
     </capability>
     <capability namespace="osgi.service">
diff --git a/dependencymanager/cnf/localrepo/index.xml.sha b/dependencymanager/cnf/localrepo/index.xml.sha
index 6893479..097e638 100644
--- a/dependencymanager/cnf/localrepo/index.xml.sha
+++ b/dependencymanager/cnf/localrepo/index.xml.sha
@@ -1 +1 @@
-73c970e02d8128b75650acabf9ce24372794a93eff20efe95972bcc66de8ab4e
\ No newline at end of file
+74c7162246fd72477fa040b08a61ae95f31f6e78ff46c35b44a59cc9fc48f77c
\ No newline at end of file
diff --git a/dependencymanager/cnf/localrepo/org.apache.felix.configadmin/org.apache.felix.configadmin-1.8.1.jar b/dependencymanager/cnf/localrepo/org.apache.felix.configadmin/org.apache.felix.configadmin-1.8.1.jar
deleted file mode 100644
index 109463d..0000000
--- a/dependencymanager/cnf/localrepo/org.apache.felix.configadmin/org.apache.felix.configadmin-1.8.1.jar
+++ /dev/null
Binary files differ
diff --git a/dependencymanager/cnf/localrepo/org.apache.felix.configadmin/org.apache.felix.configadmin-1.8.4.jar b/dependencymanager/cnf/localrepo/org.apache.felix.configadmin/org.apache.felix.configadmin-1.8.4.jar
new file mode 100644
index 0000000..29123d1
--- /dev/null
+++ b/dependencymanager/cnf/localrepo/org.apache.felix.configadmin/org.apache.felix.configadmin-1.8.4.jar
Binary files differ
diff --git a/dependencymanager/cnf/releaserepo/index.xml b/dependencymanager/cnf/releaserepo/index.xml
index 1f230e0..5c6d06c 100644
--- a/dependencymanager/cnf/releaserepo/index.xml
+++ b/dependencymanager/cnf/releaserepo/index.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<repository increment="1430261259416" name="Release" xmlns="http://www.osgi.org/xmlns/repository/v1.0.0">
+<repository increment="1430498223569" name="Release" xmlns="http://www.osgi.org/xmlns/repository/v1.0.0">
   <resource>
     <capability namespace="osgi.identity">
       <attribute name="osgi.identity" value="org.apache.felix.dependencymanager.annotation"/>
diff --git a/dependencymanager/cnf/releaserepo/index.xml.sha b/dependencymanager/cnf/releaserepo/index.xml.sha
index 0c256e2..eae1964 100644
--- a/dependencymanager/cnf/releaserepo/index.xml.sha
+++ b/dependencymanager/cnf/releaserepo/index.xml.sha
@@ -1 +1 @@
-d03ee8fdf41b1cab1a9a035aeaa657cb8685d503d3eaeaa998ae91e90a63d3ff
\ No newline at end of file
+90709c8e86096357b04b1154a5df392a8a9adbd37e4efdc98266e4ff2dd15dc7
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
index 403a58e..b3f3758 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
@@ -327,7 +327,7 @@
     {
         return m_exportService;
     }
-
+    
     private void parseComponentAnnotation(Annotation annotation)
     {
         EntryWriter writer = new EntryWriter(EntryType.Component);
@@ -458,12 +458,8 @@
         m_writers.add(writer);
 
         // service attribute
-        String service = annotation.get(EntryParam.service.toString());
-        if (service != null)
-        {
-            service = Patterns.parseClass(service, Patterns.CLASS, 1);
-        }
-        else
+        String service = parseClassAttrValue(annotation.get(EntryParam.service.toString()));
+        if (service == null)
         {
             if (m_isField)
             {
@@ -471,7 +467,48 @@
             }
             else
             {
-                service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS, 2);
+            	// parse "bind(Component, ServiceReference, Service)" signature
+            	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS1, 3, false);            		
+            	
+            	if (service == null) {
+                	// parse "bind(Component, Service)" signature
+                	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS2, 2, false);            		
+            	}
+            	
+            	if (service == null) {
+            		// parse "bind(Component, Map, Service)" signature
+                	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS3, 3, false);            		
+            	}
+            	
+            	if (service == null) {
+            		// parse "bind(ServiceReference, Service)" signature
+                	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS4, 2, false);            		
+            	}
+
+            	if (service == null) {
+            		// parse "bind(Service)" signature
+                	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS5, 1, false);            		
+            	}
+
+            	if (service == null) {
+            		// parse "bind(Service, Map)" signature
+                	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS6, 1, false);            		
+            	}
+
+            	if (service == null) {
+            		// parse "bind(Map, Service)" signature
+                	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS7, 2, false);            		
+            	}
+
+            	if (service == null) {
+            		// parse "bind(Service, Dictionary)" signature
+                	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS8, 1, false);            		
+            	}
+
+            	if (service == null) {
+            		// parse "bind(Dictionary, Service)" signature
+                	service = Patterns.parseClass(m_descriptor, Patterns.BIND_CLASS9, 2, true);            		
+            	}
             }
         }
         writer.put(EntryParam.service, service);
@@ -494,7 +531,7 @@
         }
 
         // defaultImpl attribute
-        writer.putClass(annotation, EntryParam.defaultImpl, null);
+        writer.putClass(annotation, EntryParam.defaultImpl);
 
         // added callback
         writer.putString(annotation, EntryParam.added, (!m_isField) ? m_method : null);
@@ -522,6 +559,32 @@
         // propagate attribute
         writer.putString(annotation, EntryParam.propagate, null);
     }
+        
+    /**
+     * Parse the value of a given annotation attribute (which is of type 'class').
+     * This method is compatible with bndtools 2.4.1 (where the annotation.get() method returns a String of the form "Lfull/class/name;"),
+     * and with bndtools 3.x.x (where the annotation.get() method returns a TypeRef).
+     * 
+     * @param annot the annotation which contains the given attribute
+     * @param attr the attribute name (of 'class' type).
+     * @return the annotation class attribute value
+     */
+    public static String parseClassAttrValue(Object value) {
+    	if (value instanceof String)
+    	{
+            return Patterns.parseClass((String) value, Patterns.CLASS, 1);
+    	}
+    	else if (value instanceof TypeRef) 
+    	{
+    		return ((TypeRef) value).getFQN();
+    	} 
+    	else if (value == null) {
+    		return null;
+    	}
+    	else {
+    		throw new IllegalStateException("can't parse class attribute value from " + value);
+    	}
+    }
 
     /**
      * Parses a ConfigurationDependency annotation.
@@ -533,13 +596,9 @@
         m_writers.add(writer);
 
         // pid attribute (can be specified using the pid attribute, or using the classPid attribute)
-        String  pid = annotation.get(EntryParam.pidClass.toString());
-        if (pid != null)
-        {
-            pid = Patterns.parseClass(pid, Patterns.CLASS, 1);
-        } else {
-            pid = get(annotation, EntryParam.pid.toString(), m_className);
-        }
+        String pidFromClass = parseClassAttrValue(annotation.get(EntryParam.pidClass.toString()));
+        String pid = pidFromClass != null ? pidFromClass : get(annotation, EntryParam.pid.toString(), m_className);
+
         writer.put(EntryParam.pid, pid);
         
         // the method on which the annotation is applied
@@ -609,7 +668,7 @@
         }
         else
         {
-            writer.putClass(annotation, EntryParam.service, null);
+            writer.putClass(annotation, EntryParam.service);
         }
         
         // Parse factoryMethod attribute
@@ -665,7 +724,7 @@
         }
 
         // Parse the mandatory adapted service interface.
-        writer.putClass(annotation, EntryParam.adapteeService, null);
+        writer.putClass(annotation, EntryParam.adapteeService);
 
         // Parse Adapter properties.
         parseProperties(annotation, EntryParam.properties, writer);
@@ -785,13 +844,9 @@
         writer.put(EntryParam.impl, m_className);
 
         // factory pid attribute (can be specified using the factoryPid attribute, or using the factoryPidClass attribute)
-        String  factoryPid = annotation.get(EntryParam.factoryPidClass.toString());
-        if (factoryPid != null)
-        {
-            factoryPid = Patterns.parseClass(factoryPid, Patterns.CLASS, 1);
-        } else {
-            factoryPid = get(annotation, EntryParam.factoryPid.toString(), m_className);
-        }
+        String factoryPidClass = parseClassAttrValue(annotation.get(EntryParam.factoryPidClass.toString()));
+        String factoryPid = factoryPidClass != null ? factoryPidClass : get(annotation, EntryParam.factoryPid.toString(), m_className);
+        
         writer.put(EntryParam.factoryPid, factoryPid);
 
         // Parse updated callback
@@ -917,8 +972,7 @@
                 Annotation property = (Annotation) p;
                 String heading = property.get("heading");
                 String id = property.get("id");
-                String type = (String) property.get("type");
-                type = (type != null) ? Patterns.parseClass(type, Patterns.CLASS, 1) : null;
+                String type = parseClassAttrValue(property.get("type"));
                 Object[] defaults = (Object[]) property.get("defaults");
                 String description = property.get("description");
                 Integer cardinality = property.get("cardinality");
@@ -999,12 +1053,11 @@
                     Annotation a = (Annotation) p;
                     String name = (String) a.get("name");
 
-                    String type = a.get("type");
+                    String type = parseClassAttrValue(a.get("type"));
                     Class<?> classType;
                     try
                     {
-                        classType = (type == null) ? String.class : Class.forName(Patterns.parseClass(type,
-                            Patterns.CLASS, 1));
+                        classType = (type == null) ? String.class : Class.forName(type);
                     }
                     catch (ClassNotFoundException e)
                     {
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
index 047aedd..5b0da1d 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
@@ -169,42 +169,34 @@
     /**
      * Get a class attribute value from an annotation and write it into this descriptor entry.
      */
-    public void putClass(Annotation annotation, EntryParam param, Object def)
+    public void putClass(Annotation annotation, EntryParam param)
     {
         checkType(param.toString());
-
-        Pattern pattern = Patterns.CLASS;
-        Object value = annotation.get(param.toString());
-        if (value == null && def != null)
-        {
-            value = def;
-            pattern = null;
-        }
+        String value = AnnotationCollector.parseClassAttrValue(annotation.get(param.toString()));
         if (value != null)
         {
-            if (pattern != null)
-            {
-                value = Patterns.parseClass(value.toString(), pattern, 1);
-            }
-            put(param, value.toString());
+            put(param, value);
         }
     }
 
     /**
      * Get a class array attribute value from an annotation and write it into this descriptor entry.
-     * Also collect classes found from the array into a given Set.
+     *
+     * @param annotation the annotation containing an array of classes
+     * @param param the attribute name corresponding to an array of classes
+     * @param def the default array of classes (String[]), if the attribute is not defined in the annotation
      * @return the class array size.
      */
     public int putClassArray(Annotation annotation, EntryParam param, Object def, Set<String> collect)
     {
         checkType(param.toString());
 
-        Pattern pattern = Patterns.CLASS;
+        boolean usingDefault = false;
         Object value = annotation.get(param.toString());
         if (value == null && def != null)
         {
             value = def;
-            pattern = null;
+            usingDefault = true;
         }
         if (value != null)
         {
@@ -216,9 +208,10 @@
 
             for (Object v: ((Object[]) value))
             {
-                if (pattern != null)
+                if (! usingDefault)
                 {
-                    v = Patterns.parseClass(v.toString(), pattern, 1);
+                	// Parse the annotation attribute value.
+                    v = AnnotationCollector.parseClassAttrValue(v);
                 }
                 try
                 {
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java
index 4def6b9..5cc767d 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java
@@ -34,8 +34,32 @@
     // Pattern used to check if a method returns an array of Objects
     public final static Pattern COMPOSITION = Pattern.compile("\\(\\)\\[Ljava/lang/Object;");
 
-    // Pattern used to parse the class parameter from the bind methods ("bind(Type)" or "bind(Map, Type)" or "bind(BundleContext, Type)"
-    public final static Pattern BIND_CLASS = Pattern.compile("\\((L[^;]+;)?L([^;]+);\\)V");
+    // Pattern used to parse service type from "bind(Component, ServiceReference, Service)" signature
+    public final static Pattern BIND_CLASS1 = Pattern.compile("\\((Lorg/apache/felix/dm/Component;)(Lorg/osgi/framework/ServiceReference;)L([^;]+);\\)V");
+    
+    // Pattern used to parse service type from "bind(Component, Service)" signature
+    public final static Pattern BIND_CLASS2 = Pattern.compile("\\((Lorg/apache/felix/dm/Component;)L([^;]+);\\)V");
+
+    // Pattern used to parse service type from "bind(Component, Map, Service)" signature
+    public final static Pattern BIND_CLASS3 = Pattern.compile("\\((Lorg/apache/felix/dm/Component;)(Ljava/util/Map;)L([^;]+);\\)V");
+
+    // Pattern used to parse service type from "bind(ServiceReference, Service)" signature
+    public final static Pattern BIND_CLASS4 = Pattern.compile("\\((Lorg/osgi/framework/ServiceReference;)L([^;]+);\\)V");
+
+    // Pattern used to parse service type from "bind(Service)" signature
+    public final static Pattern BIND_CLASS5 = Pattern.compile("\\(L([^;]+);\\)V");
+
+    // Pattern used to parse service type from "bind(Service, Map)" signature
+    public final static Pattern BIND_CLASS6 = Pattern.compile("\\(L([^;]+);(Ljava/util/Map;)\\)V");
+
+    // Pattern used to parse service type from "bind(Map, Service)" signature
+    public final static Pattern BIND_CLASS7 = Pattern.compile("\\((Ljava/util/Map;)L([^;]+);\\)V");
+
+    // Pattern used to parse service type from "bind(Service, Dictionary)" signature
+    public final static Pattern BIND_CLASS8 = Pattern.compile("\\(L([^;]+);(Ljava/util/Dictionary;)\\)V");
+
+    // Pattern used to parse service type from "bind(Dictionary, Service)" signature
+    public final static Pattern BIND_CLASS9 = Pattern.compile("\\((Ljava/util/Dictionary;)L([^;]+);\\)V");
 
     // Pattern used to parse classes from class descriptors;
     public final static Pattern CLASS = Pattern.compile("L([^;]+);");
@@ -61,17 +85,32 @@
      */
     public static String parseClass(String clazz, Pattern pattern, int group)
     {
+    	return parseClass(clazz, pattern, group, true);
+    }
+    
+    /**
+     * Parses a class.
+     * @param clazz the class to be parsed (the package is "/" separated).
+     * @param pattern the pattern used to match the class.
+     * @param group the pattern group index where the class can be retrieved.
+     * @param throwException true if an Exception must be thrown in case the clazz does not match the pattern.
+     * @return the parsed class.
+     */
+    public static String parseClass(String clazz, Pattern pattern, int group, boolean throwException)
+    {
         Matcher matcher = pattern.matcher(clazz);
         if (matcher.matches())
         {
             return matcher.group(group).replace("/", ".");
         }
-        else
+        else if (throwException)
         {
             throw new IllegalArgumentException("Invalid class descriptor: " + clazz);
+        } else {
+        	return null;
         }
     }
-    
+
     /**
      * Checks if a method descriptor matches a given pattern. 
      * @param the method whose signature descriptor is checked
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd
index 4ffc8c7..3886bae 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd
@@ -18,7 +18,7 @@
 	org.apache.felix.metatype;version=1.0.4,\
 	org.apache.felix.gogo.runtime;version=0.10.0,\
 	org.apache.felix.log;version=1.0.1,\
-	org.apache.felix.configadmin;version=1.8.1.SNAPSHOT,\
+	org.apache.felix.configadmin;version=1.8.4,\
 	org.apache.felix.dependencymanager;version=latest,\
 	org.apache.felix.dependencymanager.shell;version=latest
 -runee: JavaSE-1.7
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/AutoConfigTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/AutoConfigTest.java
index 4ce6936..c79249b 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/AutoConfigTest.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/AutoConfigTest.java
@@ -20,6 +20,7 @@
 
 import java.util.ArrayList;
 import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
@@ -212,11 +213,13 @@
     
     public class ConsumerWithMapField {
         final Map<Provider, Dictionary> m_providers = new ConcurrentHashMap<>();
+        final Map m_notInjectMe = new HashMap<>();
         
         void start() {
             Assert.assertNotNull(m_providers);
             System.out.println("ConsumerMap.start: injected providers=" + m_providers);
             Assert.assertTrue(m_providers.size() == 2);
+            Assert.assertEquals(0, m_notInjectMe.size());
             for (Map.Entry<Provider, Dictionary> e : m_providers.entrySet()) {
                 Provider provider = e.getKey();
                 Dictionary props = e.getValue();
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/BundleAdapterTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/BundleAdapterTest.java
index 9cd074a..f35232e 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/BundleAdapterTest.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/BundleAdapterTest.java
@@ -54,6 +54,36 @@
         // remove the bundle adapter
         m.remove(adapter);
     }
+    
+    public void testBundleAdapterWithCallbackInstance() {
+        DependencyManager m = getDM();
+        // create a bundle adapter service (one is created for each bundle)
+        BundleAdapterWithCallback baWithCb = new BundleAdapterWithCallback();
+        BundleAdapterCallbackInstance cbInstance = new BundleAdapterCallbackInstance(baWithCb);
+        
+        Component adapter = m.createBundleAdapterService(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE, null, false,
+        												 cbInstance, "add", null, "remove")
+                             .setImplementation(baWithCb)
+                             .setInterface(BundleAdapter.class.getName(), null);
+
+        // create a service provider and consumer
+        Consumer c = new Consumer();
+        Component consumer = m.createComponent().setImplementation(c)
+            .add(m.createServiceDependency().setService(BundleAdapter.class).setCallbacks("add", "remove"));
+        
+        // add the bundle adapter
+        m.add(adapter);
+        // add the service consumer
+        m.add(consumer);
+        // check if at least one bundle was found
+        c.check();
+        // remove the consumer again
+        m.remove(consumer);
+        // check if all bundles were removed correctly
+        c.doubleCheck();
+        // remove the bundle adapter
+        m.remove(adapter);
+    }
         
     public static class BundleAdapter {
         volatile Bundle m_bundle;
@@ -63,6 +93,32 @@
         }
     }
     
+    public static class BundleAdapterWithCallback extends BundleAdapter {
+        void add(Bundle b) {
+        	m_bundle = b;        	
+        }
+        
+        void remove(Bundle b) {
+        	m_bundle = null;
+        }
+    }
+    
+    public static class BundleAdapterCallbackInstance {
+    	final BundleAdapterWithCallback m_ba;
+    	
+    	BundleAdapterCallbackInstance(BundleAdapterWithCallback ba) {
+    		m_ba = ba;
+    	}
+    	
+        void add(Bundle b) {
+        	m_ba.add(b);	
+        }
+        
+        void remove(Bundle b) {
+        	m_ba.remove(b);
+        }
+    }
+    
     static class Consumer {
         private volatile int m_count = 0;
 
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/BundleDependencyTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/BundleDependencyTest.java
index f59d9b0..36a2b6d 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/BundleDependencyTest.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/BundleDependencyTest.java
@@ -77,6 +77,26 @@
         e.waitForStep(2, 5000);
     }
     
+    public void testRequiredBundleDependencyWithComponentArgInCallbackMethod() {
+        DependencyManager m = getDM();
+        
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        Component consumerWithFilter = m.createComponent()
+            .setImplementation(new FilteredConsumerRequiredWithComponentArg(e))
+            .add(m.createBundleDependency()
+                .setRequired(true)
+                .setFilter("(Bundle-SymbolicName=" + BSN + ")")
+                .setCallbacks("add", "remove")
+                );
+        // add a consumer with a filter
+        m.add(consumerWithFilter);
+        e.waitForStep(1, 5000);
+        // remove the consumer again
+        m.remove(consumerWithFilter);
+        e.waitForStep(2, 5000);
+    }
+    
     static class Consumer {
         private volatile int m_count = 0;
 
@@ -138,4 +158,20 @@
             }
         }
     }
+
+    static class FilteredConsumerRequiredWithComponentArg extends FilteredConsumerRequired {
+        public FilteredConsumerRequiredWithComponentArg(Ensure e) {
+            super(e);
+        }
+        
+        public void add(Component component, Bundle b) {
+        	Assert.assertNotNull(component);
+        	super.add(b);
+        }
+        
+        public void remove(Component component, Bundle b) {
+        	Assert.assertNotNull(component);
+        	super.remove(b);
+        }
+    }
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java
index d3a6aba..99c3c7c 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java
@@ -61,15 +61,44 @@
         e.step(6);
     }
     
-    public void testComponentWithRequiredConfigurationAndCallbackInstanceAndServicePropertyPropagation() {
+    public void testComponentWithRequiredConfigurationWithComponentArgAndServicePropertyPropagation() {
         DependencyManager m = getDM();
         // helper class that ensures certain steps get executed in sequence
         Ensure e = new Ensure();
         // create a service provider and consumer
+        Component s1 = m.createComponent().setImplementation(new ConfigurationConsumerWithComponentArg(e)).setInterface(Runnable.class.getName(), null).add(m.createConfigurationDependency().setPid(PID).setPropagate(true));
+        Component s2 = m.createComponent().setImplementation(new ConfigurationCreator(e)).add(m.createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true));
+        Component s3 = m.createComponent().setImplementation(new ConfiguredServiceConsumer(e)).add(m.createServiceDependency().setService(Runnable.class, ("(testkey=testvalue)")).setRequired(true));
+        m.add(s1);
+        m.add(s2);
+        m.add(s3);
+        e.waitForStep(4, 50000000);
+        m.remove(s1);
+        m.remove(s2);
+        m.remove(s3);
+        // ensure we executed all steps inside the component instance
+        e.step(6);
+    }
+    
+    public void testComponentWithRequiredConfigurationAndCallbackInstanceAndServicePropertyPropagation() {
+        Ensure e = new Ensure();
         ConfigurationConsumerCallbackInstance callbackInstance = new ConfigurationConsumerCallbackInstance(e);
+        testComponentWithRequiredConfigurationAndCallbackInstanceAndServicePropertyPropagation(callbackInstance, "updateConfiguration", e);
+    }
+    
+    public void testComponentWithRequiredConfigurationAndCallbackInstanceWithComponentArgAndServicePropertyPropagation() {
+        Ensure e = new Ensure();
+        ConfigurationConsumerCallbackInstanceWithComponentArg callbackInstance = new ConfigurationConsumerCallbackInstanceWithComponentArg(e);
+        testComponentWithRequiredConfigurationAndCallbackInstanceAndServicePropertyPropagation(callbackInstance, "updateConfiguration", e);
+    }
+    
+    public void testComponentWithRequiredConfigurationAndCallbackInstanceAndServicePropertyPropagation
+    	(Object callbackInstance, String updateMethod, Ensure e) {
+        DependencyManager m = getDM();
+        // create a service provider and consumer
         Component s1 = m.createComponent().setImplementation(new ConfigurationConsumerWithCallbackInstance(e))
             .setInterface(Runnable.class.getName(), null)
-            .add(m.createConfigurationDependency().setPid(PID).setPropagate(true).setCallback(callbackInstance, "updateConfiguration"));
+            .add(m.createConfigurationDependency().setPid(PID).setPropagate(true).setCallback(callbackInstance, updateMethod));
         Component s2 = m.createComponent().setImplementation(new ConfigurationCreator(e))
             .add(m.createServiceDependency().setService(ConfigurationAdmin.class).setRequired(true));
         Component s3 = m.createComponent().setImplementation(new ConfiguredServiceConsumer(e))
@@ -164,6 +193,17 @@
         }
     }
     
+    static class ConfigurationConsumerWithComponentArg extends ConfigurationConsumer {
+        public ConfigurationConsumerWithComponentArg(Ensure e) {
+            super(e);
+        }
+
+        public void updatedWithComponentArg(Component component, Dictionary props) throws ConfigurationException {
+        	Assert.assertNotNull(component);
+        	super.updated(props);
+        }
+    }
+    
     static class ConfigurationConsumerCallbackInstance {
         private final Ensure m_ensure;
 
@@ -181,6 +221,18 @@
         }
     }
     
+    static class ConfigurationConsumerCallbackInstanceWithComponentArg extends ConfigurationConsumerCallbackInstance {
+    	
+        public ConfigurationConsumerCallbackInstanceWithComponentArg(Ensure e) {
+            super(e);
+        }
+        
+        public void updateConfigurationWithComponentArg(Component component, Dictionary props) throws Exception {
+        	Assert.assertNotNull(component);
+        	super.updateConfiguration(props);
+        }
+    }
+    
     static class ConfigurationConsumerWithCallbackInstance implements Runnable {
         private final Ensure m_ensure;
 
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX4614_FactoryWithComponentInCreateParam.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX4614_FactoryWithComponentInCreateParam.java
new file mode 100644
index 0000000..b4ab143
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX4614_FactoryWithComponentInCreateParam.java
@@ -0,0 +1,74 @@
+/*
+ * 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.itest.api;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.itest.util.Ensure;
+import org.apache.felix.dm.itest.util.TestBase;
+import org.junit.Assert;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FELIX4614_FactoryWithComponentInCreateParam extends TestBase {
+    private final static Ensure m_ensure = new Ensure();
+
+    public void testSimpleFactory() {
+        DependencyManager manager = getDM();
+        
+        Component service = manager.createComponent()
+            .setFactory(Factory.class, "create")
+            .setInterface(Service.class.getName(), null);
+        
+        Component client = manager.createComponent()            
+            .setImplementation(Client.class)
+            .add(manager.createServiceDependency().setService(Service.class).setRequired(true));
+        
+        manager.add(client);
+        manager.add(service);
+        m_ensure.waitForStep(3, 5000);        
+        manager.clear();        
+    }
+    
+    public static class Factory {        
+        public Object create(Component c) {
+            m_ensure.step(1);
+            Assert.assertNotNull(c);
+            m_ensure.step(2);
+            return new ServiceImpl();
+        }
+    }
+    
+    public static interface Service {        
+    }
+    
+    public static class ServiceImpl implements Service {        
+    }
+    
+    public static class Client {
+        volatile Service m_service;
+        
+        void start() {
+            Assert.assertNotNull(m_service);   
+            m_ensure.step(3);
+        }
+    }
+}
+
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX4869_CallbackNotCalled.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX4869_CallbackNotCalled.java
index ed79dca..c928520 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX4869_CallbackNotCalled.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX4869_CallbackNotCalled.java
@@ -1,3 +1,21 @@
+/*
+ * 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.itest.api;
 
 import org.apache.felix.dm.Component;
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FactoryConfigurationAdapterTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FactoryConfigurationAdapterTest.java
index 315b3b8..0f2b32a 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FactoryConfigurationAdapterTest.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FactoryConfigurationAdapterTest.java
@@ -40,6 +40,14 @@
     private static Ensure m_ensure;
     
     public void testFactoryConfigurationAdapter() {
+    	testFactoryConfigurationAdapter(Adapter.class, "updated");
+    }
+    
+    public void testFactoryConfigurationAdapterWithUpdatedCallbackThatTakesComponentAsParameter() {
+    	testFactoryConfigurationAdapter(AdapterWithUpdateMethodThatTakesComponentAsParameter.class, "updatedWithComponent");
+    }
+    
+    public void testFactoryConfigurationAdapter(Class<?> adapterImplClass, String adapterUpdate) {
         DependencyManager m = getDM();
         // helper class that ensures certain steps get executed in sequence
         m_ensure = new Ensure();
@@ -54,9 +62,9 @@
 
         // Create an Adapter that will be instantiated, once the configuration is created.
         // This Adapter provides an AdapterService, and depends on an AdapterExtraDependency service.
-        Component s2 = m.createFactoryConfigurationAdapterService("MyFactoryPid", "updated", true /* propagate CM settings */)
+        Component s2 = m.createFactoryConfigurationAdapterService("MyFactoryPid", adapterUpdate, true /* propagate CM settings */)
                       .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
-                      .setImplementation(Adapter.class);
+                      .setImplementation(adapterImplClass);
 
         s2.add(m.createServiceDependency()
             .setService(AdapterExtraDependency.class)
@@ -186,6 +194,14 @@
             m_ensure.step(16);
         }
     }
+    
+    public static class AdapterWithUpdateMethodThatTakesComponentAsParameter extends Adapter {
+        void updatedWithComponent(Component component, Dictionary settings) {
+        	Assert.assertNotNull(component);
+        	Assert.assertEquals(this, component.getInstance());
+        	super.updated(settings);
+        }
+    }
 
     public static class AdapterServiceConsumer {
         private AdapterService m_adapterService;
diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java
index 4cedfb6..52cd1a2 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java
@@ -122,7 +122,7 @@
         return m_dm;
     }
                 
-    protected void clearComponents() throws InterruptedException {
+    protected void clearComponents() {
         m_dm.clear();
         warn("All component cleared.");
     }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/MethodSignatures.java b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/MethodSignatures.java
new file mode 100644
index 0000000..d340ec9
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/MethodSignatures.java
@@ -0,0 +1,246 @@
+/*
+ * 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.itest.components;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.felix.dm.annotation.api.Component;
+import org.apache.felix.dm.annotation.api.ConfigurationDependency;
+import org.apache.felix.dm.annotation.api.FactoryConfigurationAdapterService;
+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.itest.util.Ensure;
+import org.junit.Assert;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * Tests various bind method signatures
+ */
+public class MethodSignatures {
+	// For Consumer service
+    public final static String ENSURE_SERVICE_DEPENDENCY = "MethodSignatures1";
+    
+    // For FactoryPidComponent
+    public final static String ENSURE_FACTORYPID = "MethodSignatures2";
+
+    // This component configures the Consumer component.
+	@Component
+	public static class ConsumerConfigurator {
+		@ServiceDependency(filter="(name=" + ENSURE_SERVICE_DEPENDENCY + ")")
+		Ensure m_ensure;
+		
+		@ServiceDependency
+		ConfigurationAdmin m_cm;
+
+		private Configuration m_conf;
+		
+		@Start
+		void start() throws IOException {
+			m_conf = m_cm.getConfiguration(Consumer.class.getName());
+			Hashtable<String, Object> props = new Hashtable<>();
+			props.put("foo", "bar");
+			m_conf.update(props);
+		}
+		
+		@Stop
+		void stop() throws IOException {
+			m_conf.delete();
+		}
+	}
+
+	// A simple provider service
+	@Component(provides=Provider.class)
+	public static class Provider {
+		@ServiceDependency(filter="(name=" + ENSURE_SERVICE_DEPENDENCY + ")")
+		Ensure m_ensure;
+	}
+	
+	// This consumer depends on the configuration and on the provider, using multiple method signatures.
+	@Component
+	public static class Consumer {
+		Dictionary<String, Object> m_properties;
+		Dictionary<String, Object> m_properties2;
+
+		@ConfigurationDependency
+		void updated(Dictionary<String, Object> properties) {
+			m_properties = properties;			
+		}
+		
+		@ConfigurationDependency
+		void updated2(org.apache.felix.dm.Component component, Dictionary<String, Object> properties) {
+			Assert.assertNotNull(component);
+			m_properties2 = properties;			
+		}
+
+		@ServiceDependency(filter="(name=" + ENSURE_SERVICE_DEPENDENCY + ")")
+		Ensure m_ensure;
+		
+		@ServiceDependency
+		void bind(org.apache.felix.dm.Component component, ServiceReference ref, Provider provider) {
+			Assert.assertNotNull(component);
+			Assert.assertNotNull(ref);
+			Assert.assertNotNull(provider);
+			m_ensure.step();
+		}
+		
+		@ServiceDependency
+		void bind(org.apache.felix.dm.Component component, Provider provider) {
+			Assert.assertNotNull(component);
+			Assert.assertNotNull(provider);
+			m_ensure.step();
+		}
+		
+		@ServiceDependency
+		void bind(org.apache.felix.dm.Component component, Map<?, ?> properties, Provider provider) {
+			Assert.assertNotNull(component);
+			Assert.assertNotNull(properties);
+			Assert.assertNotNull(provider);
+			m_ensure.step();
+		}
+
+		@ServiceDependency
+		void bind(ServiceReference ref, Provider provider) {
+			Assert.assertNotNull(ref);
+			Assert.assertNotNull(provider);
+			m_ensure.step();
+		}
+
+		@ServiceDependency
+		void bind(Provider provider) {
+			Assert.assertNotNull(provider);
+			m_ensure.step();
+		}
+
+		@ServiceDependency
+		void bind(Provider provider, Map<?,?> properties) {
+			Assert.assertNotNull(provider);
+			Assert.assertNotNull(properties);
+			m_ensure.step();
+		}
+		
+		@ServiceDependency
+		void bind(Map<?,?> properties, Provider provider) {
+			Assert.assertNotNull(properties);
+			Assert.assertNotNull(provider);
+			m_ensure.step();
+		}
+		
+		@ServiceDependency
+		void bind(Provider provider, Dictionary<?,?> properties) {
+			Assert.assertNotNull(properties);
+			Assert.assertNotNull(provider);
+			m_ensure.step();
+		}
+		
+		@ServiceDependency
+		void bind(Dictionary<?,?> properties, Provider provider) {
+			Assert.assertNotNull(properties);
+			Assert.assertNotNull(provider);
+			m_ensure.step();
+		}
+		
+		@Start
+		void start() {
+			Assert.assertNotNull(m_properties);
+			Assert.assertNotNull(m_properties2);
+			Assert.assertEquals("bar", m_properties.get("foo"));
+			Assert.assertEquals("bar", m_properties2.get("foo"));
+			m_ensure.step(10);
+		}
+	}
+	
+    // This component configures the FactoryPidComponent / FactoryPidComponent2 components.
+	@Component
+	public static class FactoryPidConfigurator {
+		@ServiceDependency(filter="(name=" + ENSURE_FACTORYPID + ")")
+		Ensure m_ensure;
+		
+		@ServiceDependency
+		ConfigurationAdmin m_cm;
+
+		private Configuration m_conf1;
+		private Configuration m_conf2;
+
+		@Start
+		void start() throws IOException {
+			m_conf1 = m_cm.createFactoryConfiguration(FactoryPidComponent.class.getName());
+			Hashtable<String, Object> props = new Hashtable<>();
+			props.put("foo", "bar");
+			m_conf1.update(props);
+			
+			m_conf2 = m_cm.createFactoryConfiguration(FactoryPidComponent2.class.getName());
+			props = new Hashtable<>();
+			props.put("foo", "bar");
+			m_conf2.update(props);
+		}
+		
+		@Stop
+		void stop() throws IOException {
+			m_conf1.delete();
+			m_conf2.delete();
+		}
+	}
+
+	// This is a factory pid component with an updated callback having the "updated(Dictionary)" signature
+	@FactoryConfigurationAdapterService
+	public static class FactoryPidComponent {
+		Dictionary<String, Object> m_properties;
+		
+		void updated(Dictionary<String, Object> properties) {
+			m_properties = properties;
+		}
+		
+		@ServiceDependency(filter="(name=" + ENSURE_FACTORYPID + ")")
+		Ensure m_ensure;
+		
+		@Start
+		void start() {
+			Assert.assertNotNull(m_properties);
+			Assert.assertEquals("bar", m_properties.get("foo"));
+			m_ensure.step();
+		}
+	}
+	
+	// This is a factory pid component with an updated callback having the "updated(Component, Dictionary)" signature
+	@FactoryConfigurationAdapterService
+	public static class FactoryPidComponent2 {
+		Dictionary<String, Object> m_properties;
+		
+		void updated(org.apache.felix.dm.Component component, Dictionary<String, Object> properties) {
+			Assert.assertNotNull(component);
+			m_properties = properties;
+		}
+		
+		@ServiceDependency(filter="(name=" + ENSURE_FACTORYPID + ")")
+		Ensure m_ensure;
+		
+		@Start
+		void start() {
+			Assert.assertNotNull(m_properties);
+			Assert.assertEquals("bar", m_properties.get("foo"));
+			m_ensure.step();
+		}
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/tests/MethodSignaturesTest.java b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/tests/MethodSignaturesTest.java
new file mode 100644
index 0000000..1a52580
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/tests/MethodSignaturesTest.java
@@ -0,0 +1,51 @@
+/*
+* 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.itest.tests;
+
+import org.apache.felix.dm.itest.util.Ensure;
+import org.apache.felix.dm.itest.util.TestBase;
+import org.apache.felix.dm.runtime.itest.components.MethodSignatures;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Use case: Validates proper injection on various bind method signatures.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MethodSignaturesTest extends TestBase {
+    /**
+     * Validates ServiceDependency method signatures.
+     */
+    public void testServiceDependencyBindSignatures() {
+        Ensure e = new Ensure();
+        ServiceRegistration sr = register(e, MethodSignatures.ENSURE_SERVICE_DEPENDENCY);
+        e.waitForStep(10, 5000);
+        sr.unregister();
+    }
+    
+    /**
+     * Validates FactoryConfigurationAdapter updated callback signatures.
+     */
+    public void testFactoryPidUpdatedSignature1() {
+        Ensure e = new Ensure();
+        ServiceRegistration sr = register(e, MethodSignatures.ENSURE_FACTORYPID);
+        e.waitForStep(2, 5000);
+        sr.unregister();
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/Activator.java b/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/Activator.java
index f3ac03e..3f36cab 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/Activator.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/Activator.java
@@ -29,13 +29,11 @@
 public class Activator extends DependencyActivatorBase {
     @Override
     public void init(BundleContext ctx, DependencyManager m) throws Exception {
-        CompositionManager compositionMngr = new CompositionManager();
+        CompositionManager factory = new CompositionManager();
         m.add(createComponent()
-            .setFactory(compositionMngr, "create")
-            .setComposition(compositionMngr, "getComposition")
-            .add(createConfigurationDependency()
-                .setPid(CompositionManager.class.getName())
-                .setCallback(compositionMngr, "updated"))
+            .setFactory(factory, "create")
+            .setComposition(factory, "getComposition")
+            .add(createConfigurationDependency().setPid(CompositionManager.class.getName()).setCallback(factory, "updated"))
             .add(createServiceDependency().setService(LogService.class).setRequired(true)));
     }
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/DeviceAccessImpl.java b/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/DeviceAccessImpl.java
index 29b4b2a..610851b 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/DeviceAccessImpl.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/device/api/DeviceAccessImpl.java
@@ -30,19 +30,16 @@
     volatile Device device;
     volatile DeviceParameter deviceParameter;
 
-    void init(Component c) {
+    void init(Component component) {
         // Dynamically add an extra dependency on a DeviceParameter.
-        DependencyManager dm = c.getDependencyManager();
-        c.add(dm.createServiceDependency().setService(DeviceParameter.class, "(device.id=" + device.getDeviceId() + ")").setRequired(
-            true));
-    }
-
-    void start(Component c) {
-        // Our service is starting: before being registered in the OSGi service registry,
-        // add here a service property, using the device.id.
+    	// We also add a "device.access.id" property dynamically.
         Hashtable<String, Object> props = new Hashtable<>();
         props.put("device.access.id", device.getDeviceId());
-        c.setServiceProperties(props);
+
+        DependencyManager dm = component.getDependencyManager();
+        component
+        	.setServiceProperties(props)
+        	.add(dm.createServiceDependency().setService(DeviceParameter.class, "(device.id=" + device.getDeviceId() + ")").setRequired(true));
     }
 
     @Override
diff --git a/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/annot/README b/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/annot/README
index e9e3b7e..4f55f97 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/annot/README
+++ b/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/annot/README
@@ -32,12 +32,12 @@
 aspect configuration metatype is also declared using the bnd metatype annotations (see
 DictionaryAspectConfiguration.java). 
 
-Before running this sample, go to webconsole, and add some words in the Spell Checker Configuration (annotation) factory PID, and
-in the Spell Checker Aspect Dictionary (annotation) PID.
+Before running this sample, go to webconsole (http://localhost:8080/system/console/configMgr), and add some words in the 
+"Spell Checker Dictionary (annotation)" section, and in the "Spell Checker Aspect Dictionary (annotation)" configurations.
 
 Then go to gogo shell, and type dm help. You will normally see the dictionary.annotation:spellcheck command.
 Type 
  
-   dictionary.annotation:spellcheck <some words>
+   dictionary.annotation:spellcheck <some words that you have configured in webconsole>
 
-and the dictionary will check for proper word existence.
+and the command will check for proper word existence.
diff --git a/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/api/README b/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/api/README
index a8a70fb..c792587 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/api/README
+++ b/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/api/README
@@ -32,10 +32,13 @@
 aspect configuration metatype is also declared using the bnd metatype annotations (see
 DictionaryAspectConfiguration.java). 
 
-Before running this sample, go to webconsole, and add some words in the Spell Checker Configuration (api) factory PID, and
-in the Spell Checker Aspect Dictionary (api) PID.
+Before running this sample, go to webconsole (http://localhost:8080/system/console/configMgr), and add some 
+words in the "Spell Checker Dictionary (api)" and in the "Spell Checker Aspect Dictionary (api)" configurations.
 
 Then go to gogo shell, and type dm help. You will normally see the dictionary:spellcheck command.
-Type dictionary:spellcheck <some words configured either in the spell checker configuration, or in the spell checker aspect configuration, 
-and the dictionary will check for proper word existance in the configuration.
+Then type:
+
+  dictionary:spellcheck <some words that you have configured in webconsole> 
+
+and the command will check for proper word existence in the configuration.
 
diff --git a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd
index a75510e..b42cd3c 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd
+++ b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd
@@ -34,7 +34,7 @@
 	META-INF/=resources/changelog.txt
 Import-Package: !org.junit,!org.mockito.*,*
 Bundle-Activator: org.apache.felix.dm.impl.Activator
-Bundle-Version: 4.0.2
+Bundle-Version: 4.1.0
 Bundle-Name: Apache Felix Dependency Manager
 Bundle-Description: Provides dynamic service and component dependency management
 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
index a58b2ef..ec980cb 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
@@ -34,6 +34,11 @@
  * do not depend on these to parse your settings.</li>
  * </ul>
  * 
+ * The callback invoked when a configuration dependency is updated can supports the following signatures:<p>
+ * <ul><li> updated(Dictionary)
+ *     <li> updated(Component, Dictionary)
+ * </ul>
+ * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public interface ConfigurationDependency extends Dependency, ComponentDependencyDeclaration {
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java
index d06b91a..9be94f7 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java
@@ -326,6 +326,16 @@
     }
 
     /**
+     * Creates a new bundle adapter service, using a specific callback instance
+     * 
+     * @return the bundle adapter service
+     */
+    public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate,
+    		Object callbackInstance, String add, String change, String remove) {
+        return m_manager.createBundleAdapterService(bundleStateMask, bundleFilter, propagate, callbackInstance, add, change, remove);
+    }
+
+    /**
      * Creates a new factory configuration adapter service.
      * 
      * @return the factory configuration adapter service
@@ -335,6 +345,15 @@
     }
     
     /**
+     * Creates a new factory configuration adapter service, using a specific callback instance
+     * 
+     * @return the factory configuration adapter service
+     */
+    public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate, Object callbackInstance) {
+        return m_manager.createFactoryConfigurationAdapterService(factoryPid, update, propagate, callbackInstance);
+    }
+  
+    /**
      * Creates a new factory configuration adapter service.
      * 
      * @return the factory configuration adapter service
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java
index 336f8ae..9b0a541 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java
@@ -405,15 +405,42 @@
      * </pre></blockquote>
      * 
      * @param factoryPid the pid matching the factory configuration
-     * @param update the adapter method name that will be notified when the factory configuration is created/updated.
+     * @param update the adapter method name that will be notified when the factory configuration is created/updated.<p>
+     *  The following signatures are supported:<p>
+     *        <ul><li> updated(Dictionary)
+     *        <li> updated(Component, Dictionary)
+     *        </ul>
      * @param propagate true if public factory configuration should be propagated to the adapter service properties
      * @return a service that acts as a factory for generating the managed service factory configuration adapter
      */
     public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate) {
-        return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate);
+        return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate, null);
     }
 
     /**
+     * Creates a new Managed Service Factory Configuration Adapter using a specific update callback instance. 
+     * For each new Config Admin factory configuration matching the factoryPid, an adapter will be created 
+     * based on the adapter implementation class.
+     * 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 
+     * (which don't start with ".") will be propagated along with the adapter service properties. 
+     * It will also inherit all dependencies.
+     * 
+     * @param factoryPid the pid matching the factory configuration
+     * @param update the adapter method name that will be notified when the factory configuration is created/updated.<p>
+     *  The following signatures are supported:<p>
+     *        <ul><li> updated(Dictionary)
+     *        <li> updated(Component, Dictionary)
+     *        </ul>
+     * @param propagate true if public factory configuration should be propagated to the adapter service properties
+     * @param callbackInstance the object on which the updated callback will be invoked.
+     * @return a service that acts as a factory for generating the managed service factory configuration adapter
+     */
+    public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate, Object callbackInstance) {
+        return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate, callbackInstance);
+    }
+
+   /**
      * Creates a new Managed Service Factory Configuration Adapter with meta type support. For each new Config Admin 
      * factory configuration matching the factoryPid, an adapter will be created based on the adapter implementation 
      * class. The adapter will be registered with the specified interface, and with the specified adapter service 
@@ -445,7 +472,11 @@
      * </pre></blockquote>
      * 
      * @param factoryPid the pid matching the factory configuration
-     * @param update the adapter method name that will be notified when the factory configuration is created/updated.
+     * @param update the adapter method name that will be notified when the factory configuration is created/updated.<p>
+     *  The following signatures are supported:<p>
+     *        <ul><li> updated(Dictionary)
+     *        <li> updated(Component, Dictionary)
+     *        </ul>
      * @param propagate true if public factory configuration should be propagated to the adapter service properties
      * @param heading The label used to display the tab name (or section) where the properties are displayed. 
      *        Example: "Printer Service"
@@ -462,7 +493,7 @@
     public Component createAdapterFactoryConfigurationService(String factoryPid, String update, boolean propagate,
         String heading, String desc, String localization, PropertyMetaData[] propertiesMetaData)
     {
-        return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate, m_context, m_logger, heading,
+        return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate, null, m_context, m_logger, heading,
             desc, localization, propertiesMetaData);
     }
 
@@ -498,6 +529,26 @@
     }
 
     /**
+     * Creates a new bundle adapter using specific callback instance. 
+     * The adapter will be applied to any bundle that matches the specified bundle state mask and filter condition. 
+     * For each matching bundle an adapter will be created based on the adapter implementation class, and
+     * The adapter will be registered with the specified interface.
+     * 
+     * @param bundleStateMask the bundle state mask to apply
+     * @param bundleFilter the filter to apply to the bundle manifest
+     * @param propagate <code>true</code> if properties from the bundle should be propagated to the service
+     * @param callbackInstance the instance to invoke the callbacks on, or null if the callbacks have to be invoked on the adapter itself
+     * @param add name of the callback method to invoke on add
+     * @param change name of the callback method to invoke on change
+     * @param remove name of the callback method to invoke on remove
+     * @return a service that acts as a factory for generating bundle adapters
+     */
+    public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate,
+    		Object callbackInstance, String add, String change, String remove) {
+        return new BundleAdapterImpl(this, bundleStateMask, bundleFilter, propagate, callbackInstance, add, change, remove);
+    }
+
+    /**
      * Creates a new resource adapter. The adapter will be applied to any resource that
      * matches the specified filter condition. For each matching resource
      * an adapter will be created based on the adapter implementation class.
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
index c883ebf..9f3d904 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
@@ -37,30 +37,47 @@
  */
 public class BundleAdapterImpl extends FilterComponent
 {
-    /**
+	/**
      * Creates a new Bundle Adapter Service implementation.
      */
     public BundleAdapterImpl(DependencyManager dm, int bundleStateMask, String bundleFilter, boolean propagate)
     {
-        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
-        m_component.setImplementation(new BundleAdapterDecorator(bundleStateMask, propagate))
-                 .add(dm.createBundleDependency()
-                      .setFilter(bundleFilter)
-                      .setStateMask(bundleStateMask)
-                      .setCallbacks("added", "removed"))
-                 .setCallbacks("init", null, "stop", null);
+    	this(dm, bundleStateMask, bundleFilter, propagate, null, null, null, null);
     }
 
-    public class BundleAdapterDecorator extends AbstractDecorator {
+	public BundleAdapterImpl(DependencyManager dm, int stateMask, String filter, boolean propagate, Object cbInstance, String add, String change, String remove) {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_component
+        	.setImplementation(new BundleAdapterDecorator(stateMask, propagate, cbInstance, add, change, remove))
+        	.add(dm.createBundleDependency()
+        		   .setFilter(filter)
+        		   .setStateMask(stateMask)
+        		   .setCallbacks("added", "removed"))
+        		   .setCallbacks("init", null, "stop", null);
+	}
+
+	public class BundleAdapterDecorator extends AbstractDecorator {
         private final boolean m_propagate;
         private final int m_bundleStateMask;
+        public final Object m_cbInstance;
+    	public final String m_add;
+    	public final String m_change;
+    	public final String m_remove;
 
         public BundleAdapterDecorator(int bundleStateMask, boolean propagate) {
-            m_bundleStateMask = bundleStateMask;
-            m_propagate = propagate;
+            this(bundleStateMask, propagate, null, null, null, null);
         }
         
-        public Component createService(Object[] properties) {
+		public BundleAdapterDecorator(int bundleStateMask, boolean propagate, Object callbackInstance, String add, String change, String remove) {
+            m_bundleStateMask = bundleStateMask;
+            m_propagate = propagate;
+            m_cbInstance = callbackInstance;
+            m_add = add;
+            m_change = change;
+            m_remove = remove;
+        }
+
+		public Component createService(Object[] properties) {
             Bundle bundle = (Bundle) properties[0];
             Hashtable<String, Object> props = new Hashtable<>();
             if (m_serviceProperties != null) {
@@ -84,7 +101,7 @@
                     .setBundle(bundle)
                     .setStateMask(m_bundleStateMask)
                     .setPropagate(m_propagate)
-                    .setCallbacks(null, "changed", null)
+                    .setCallbacks(m_cbInstance, m_add, m_change, m_remove)
                     .setAutoConfig(true)
                     .setRequired(true));
 
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleDependencyImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleDependencyImpl.java
index 6e5dbd1..4aad446 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleDependencyImpl.java
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleDependencyImpl.java
@@ -23,6 +23,7 @@
 import java.util.Dictionary;
 
 import org.apache.felix.dm.BundleDependency;
+import org.apache.felix.dm.Component;
 import org.apache.felix.dm.ComponentDependencyDeclaration;
 import org.apache.felix.dm.context.AbstractDependency;
 import org.apache.felix.dm.context.DependencyContext;
@@ -194,8 +195,8 @@
     private void invoke(String method, Event e) {
         BundleEventImpl be = (BundleEventImpl) e;
         m_component.invokeCallbackMethod(getInstances(), method,
-            new Class[][] {{Bundle.class}, {Object.class}, {}},             
-            new Object[][] {{be.getBundle()}, {be.getBundle()}, {}});
+            new Class[][] {{Bundle.class}, {Object.class}, {Component.class, Bundle.class}, {}},             
+            new Object[][] {{be.getBundle()}, {be.getBundle()}, {m_component, be.getBundle()}, {}});
     }
     
     public BundleDependency setBundle(Bundle bundle) {
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
index 63bfe70..9652e8f 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
@@ -343,18 +343,19 @@
         dependencyEvents.add(e);        
         dc.setAvailable(true);
         
-        // In the following switch block, we only recalculate state changes 
+        // In the following switch block, we sometimes only recalculate state changes 
         // if the dependency is fully started. If the dependency is not started,
         // it means it is actually starting (the service tracker is executing the open method). 
-        // And in this case, we don't recalculate state changes now. We'll do it 
+        // And in this case, depending on the state, we don't recalculate state changes now. We'll do it 
         // once all currently available services are found, and then after, 
         // we'll recalculate state change (see the startDependencies method). 
         // 
         // All this is done for two reasons:
-        // 1- optimization: it is preferable to recalculate state changes once we know about all currently available dependency services
-        //    (after the tracker has returned from its open method).
-        // 2- This also allows to determine the list of currently available dependency services from within the component start method callback
-        //    (this will be extremely useful when porting the Felix SCR on top of DM4).
+        // 1- optimization: it is preferable to recalculate state changes once we know about all currently 
+        //    available dependency services (after the tracker has returned from its open method).
+        // 2- This also allows to determine the list of currently available dependency services from within 
+        //    the component start method callback (this will be extremely useful when porting the Felix SCR 
+        //    on top of DM4).
         
         switch (m_state) {
         case WAITING_FOR_REQUIRED:            
@@ -778,7 +779,9 @@
 		        	}
 		        	else {
     		        	try {
-    		        		m_componentInstance = InvocationUtil.invokeMethod(factory, factory.getClass(), m_instanceFactoryCreateMethod, new Class[][] {{}}, new Object[][] {{}}, false);
+    		        		m_componentInstance = InvocationUtil.invokeMethod(factory, 
+    		        		    factory.getClass(), m_instanceFactoryCreateMethod, 
+    		        		    new Class[][] {{}, {Component.class}}, new Object[][] {{}, {this}}, false);
     					}
     		        	catch (Exception e) {
     	                    m_logger.log(Logger.LOG_ERROR, "Could not create service instance using factory " + factory + " method " + m_instanceFactoryCreateMethod + ".", e);
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
index db93df2..8f5f70b 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
@@ -23,6 +23,7 @@
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import org.apache.felix.dm.Component;
 import org.apache.felix.dm.ConfigurationDependency;
 import org.apache.felix.dm.Logger;
 import org.apache.felix.dm.PropertyMetaData;
@@ -92,7 +93,10 @@
 
     @Override
     public boolean needsInstance() {
-        return m_callbackInstance == null;
+    	// we need the component instances even if there is a callback instance, which could need to access to
+    	// component instances while being invoked in the updated callback. So we return true here, even if there
+    	// is a configured callback instance.
+        return true; 
     }
 
     @Override
@@ -266,8 +270,13 @@
 					try {
 						InvocationUtil.invokeCallbackMethod(instances[i],
 								m_add, new Class[][] {
-										{ Dictionary.class }, {} },
-								new Object[][] { { settings }, {} });
+										{ Dictionary.class },
+										{ Component.class, Dictionary.class },
+										{} },
+								new Object[][] { 
+						            { settings }, 
+						            { m_component, settings },
+						            {} });
 					}
 
 					catch (InvocationTargetException e) {
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
index f96214a..eccdd2c 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.dm.impl;
 
-import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Dictionary;
 import java.util.Enumeration;
@@ -50,7 +49,7 @@
     // Our logger
     protected final Logger m_logger;
     
-    public FactoryConfigurationAdapterImpl(DependencyManager dm, String factoryPid, String update, boolean propagate) {
+    public FactoryConfigurationAdapterImpl(DependencyManager dm, String factoryPid, String update, boolean propagate, Object updateCallbackInstance) {
         super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
         m_factoryPid = factoryPid;
         m_logger = ((ComponentImpl) m_component).getLogger();
@@ -59,11 +58,11 @@
         props.put(Constants.SERVICE_PID, factoryPid);
         m_component
             .setInterface(ManagedServiceFactory.class.getName(), props)
-            .setImplementation(new AdapterImpl(update, propagate))
+            .setImplementation(new AdapterImpl(update, propagate, updateCallbackInstance))
             .setCallbacks("init", null, "stop", null);
     }
     
-    public FactoryConfigurationAdapterImpl(DependencyManager dm, String factoryPid, String update, boolean propagate,
+    public FactoryConfigurationAdapterImpl(DependencyManager dm, String factoryPid, String update, boolean propagate, Object updateCallbackInstance,
         BundleContext bctx, Logger logger, String heading, String description, String localization, PropertyMetaData[] properyMetaData) {
         super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
         m_factoryPid = factoryPid;
@@ -72,7 +71,7 @@
         props.put(Constants.SERVICE_PID, factoryPid);
         m_component
             .setInterface(ManagedServiceFactory.class.getName(), props)
-            .setImplementation(new MetaTypeAdapterImpl(update, propagate,
+            .setImplementation(new MetaTypeAdapterImpl(update, propagate, updateCallbackInstance,
                 bctx, logger, heading, description,
                 localization, properyMetaData))
             .setCallbacks("init", null, "stop", null);
@@ -91,6 +90,9 @@
 
         // Tells if the CM config must be propagated along with the adapter service properties
         protected final boolean m_propagate;
+        
+        // A specific callback instance where the update callback is invoked on (or null if default component instances should be used).
+        protected final Object m_updateCallbackInstance;
 
         /**
          * Creates a new CM factory configuration adapter.
@@ -101,10 +103,12 @@
          * @param adapterImplementation
          * @param adapterProperties
          * @param propagate
+         * @param updateCallbackObject null if update should be called on all component instances (composition), or a specific update callback instance.
          */
-        public AdapterImpl(String updateMethod, boolean propagate) {
+        public AdapterImpl(String updateMethod, boolean propagate, Object updateCallbackObject) {
             m_update = updateMethod;
             m_propagate = propagate;
+            m_updateCallbackInstance = updateCallbackObject;
         }
 
         /**
@@ -121,28 +125,11 @@
         public Component createService(Object[] properties) {
             Dictionary<String, ?> settings = (Dictionary<String, ?>) properties[0];     
             Component newService = m_manager.createComponent();        
-            Object impl = null;
-            
-            try {
-                if (m_serviceImpl != null) {
-                    impl = (m_serviceImpl instanceof Class) ? ((Class<?>) m_serviceImpl).newInstance() : m_serviceImpl;
-                }
-                else {
-                    impl = instantiateFromFactory(m_factory, m_factoryCreateMethod);
-                }
-                InvocationUtil.invokeCallbackMethod(impl, m_update, 
-                    new Class[][] {{ Dictionary.class }, {}}, 
-                    new Object[][] {{ settings }, {}});
-            }
-            
-            catch (Throwable t) {
-               handleException(t);
-            }
 
             // Merge adapter service properties, with CM settings 
             Dictionary<String, Object> serviceProperties = getServiceProperties(settings);
             newService.setInterface(m_serviceInterfaces, serviceProperties);
-            newService.setImplementation(impl);
+            newService.setImplementation(m_serviceImpl);
             newService.setComposition(m_compositionInstance, m_compositionMethod); // if not set, no effect
             newService.setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy); // if not set, no effect
             configureAutoConfigState(newService, m_component);
@@ -155,6 +142,27 @@
                 newService.add(m_stateListeners.get(i));
             }
             
+            // Instantiate the component, because we need to invoke the updated callback synchronously, in the CM calling thread.
+            ((ComponentImpl) newService).instantiateComponent();
+                        
+            try {                
+                for (Object instance : getCompositionInstances(newService)) {
+                    InvocationUtil.invokeCallbackMethod(instance, m_update, 
+                        new Class[][] {
+                            {Dictionary.class},
+                            {Component.class, Dictionary.class},
+                            {}}, 
+                        new Object[][] {
+                            {settings}, 
+                            {newService, settings},
+                            {}});
+                }
+            }
+            
+            catch (Throwable t) {
+               handleException(t); // will rethrow a runtime exception.
+            }
+
             return newService;
         }
 
@@ -166,12 +174,21 @@
         public void updateService(Object[] properties) {
             Dictionary<String, ?> cmSettings = (Dictionary<String, ?>) properties[0];
             Component service = (Component) properties[1];
-            Object impl = service.getInstances()[0];
+            Object[] instances = getUpdateCallbackInstances(service);
 
             try {
-                InvocationUtil.invokeCallbackMethod(impl, m_update, 
-                    new Class[][] {{ Dictionary.class }, {}}, 
-                    new Object[][] {{ cmSettings }, {}});
+                for (Object instance : instances) {
+                    InvocationUtil.invokeCallbackMethod(instance, m_update, 
+                        new Class[][] {
+                            { Dictionary.class },
+                            { Component.class, Dictionary.class },
+                            {}}, 
+                        new Object[][] {
+                            { cmSettings }, 
+                            { service, cmSettings },
+                        {}
+                    });
+                }
                 if (m_serviceInterfaces != null && m_propagate == true) {
                     Dictionary<String, ?> serviceProperties = getServiceProperties(cmSettings);
                     service.setServiceProperties(serviceProperties);
@@ -181,7 +198,26 @@
             catch (Throwable t) {
                 handleException(t);
             }
-        }   
+        }
+        
+        /**
+         * Returns the Update callback instances.
+         */
+        private Object[] getUpdateCallbackInstances(Component comp) {
+            if (m_updateCallbackInstance == null) {
+                return comp.getInstances();
+            } else {
+                return new Object[] { m_updateCallbackInstance };
+            }
+        }
+        
+        private Object[] getCompositionInstances(Component component) {
+            if (m_updateCallbackInstance != null) {
+                return new Object[] { m_updateCallbackInstance };
+            } else {
+                return component.getInstances();
+            }         
+        }
 
         /**
          * Merge CM factory configuration setting with the adapter service properties. The private CM factory configuration 
@@ -221,36 +257,7 @@
             
             return props;
         }
-    
-        private Object instantiateFromFactory(Object mFactory, String mFactoryCreateMethod) {
-            Object factory = null;
-            if (m_factory instanceof Class) {
-                try {
-                    factory = createInstance((Class<?>) m_factory);
-                }
-                catch (Throwable t) {
-                    handleException(t);
-                }
-            }
-            else {
-                factory = m_factory;
-            }
-
-            try {
-                return InvocationUtil.invokeMethod(factory, factory.getClass(), m_factoryCreateMethod, new Class[][] { {} }, new Object[][] { {} }, false);
-            }
-            catch (Throwable t) {
-                handleException(t);
-                return null;
-            }
-        }
-
-        private Object createInstance(Class<?> clazz) throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException {
-            Constructor<?> constructor = clazz.getConstructor(new Class[] {});
-            constructor.setAccessible(true);
-            return clazz.newInstance();
-        }
-    
+        
         private void handleException(Throwable t) {
             m_logger.log(Logger.LOG_ERROR, "Got exception while handling configuration update for factory pid " + m_factoryPid, t);
             if (t instanceof InvocationTargetException) {
@@ -276,10 +283,11 @@
         private final MetaTypeProviderImpl m_metaType;
         
         public MetaTypeAdapterImpl(String updateMethod, boolean propagate,
+                                   Object updateCallbackInstance,
                                    BundleContext bctx, Logger logger, String heading, 
                                    String description, String localization,
                                    PropertyMetaData[] properyMetaData) {
-            super(updateMethod, propagate);
+            super(updateMethod, propagate, updateCallbackInstance);
             m_metaType = new MetaTypeProviderImpl(m_factoryPid, bctx, logger, null, this);
             m_metaType.setName(heading);
             m_metaType.setDescription(description);
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo
index bd33369..6ae0565 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo
@@ -1 +1 @@
-version 4.0.0
\ No newline at end of file
+version 4.1.0
\ No newline at end of file