Added support for invoking life cycle callbacks on something else than the service instance. Refactored some of the callback invocation code so all of them now use the same implementation. Implemented some still missing things.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@930293 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java
index cab04b6..71fd6e9 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java
@@ -164,17 +164,26 @@
         return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, factory, factoryCreateMethod, properties);
     }
     
-    public Service createAdapterService(Class serviceInterface, String serviceFilter, Class adapterInterface, Object adapterImplementation, Dictionary adapterProperties) {
+    public Service createAdapterService(Class serviceInterface, String serviceFilter, String adapterInterface, Object adapterImplementation, Dictionary adapterProperties) {
+        return m_manager.createAdapterService(serviceInterface, serviceFilter, adapterInterface, adapterImplementation, adapterProperties);
+    }
+    public Service createAdapterService(Class serviceInterface, String serviceFilter, String[] adapterInterface, Object adapterImplementation, Dictionary adapterProperties) {
         return m_manager.createAdapterService(serviceInterface, serviceFilter, adapterInterface, adapterImplementation, adapterProperties);
     }
     
-    public Service createResourceAdapter(String resourceFilter, Class adapterInterface, Dictionary adapterProperties, Object adapterImplementation, boolean propagate) {
+    public Service createResourceAdapter(String resourceFilter, String adapterInterface, Dictionary adapterProperties, Object adapterImplementation, boolean propagate) {
+        return m_manager.createResourceAdapterService(resourceFilter, adapterInterface, adapterProperties, adapterImplementation, propagate);
+    }
+    public Service createResourceAdapter(String resourceFilter, String[] adapterInterface, Dictionary adapterProperties, Object adapterImplementation, boolean propagate) {
         return m_manager.createResourceAdapterService(resourceFilter, adapterInterface, adapterProperties, adapterImplementation, propagate);
     }
     
     public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, Object adapterImplementation, String adapterInterface, Dictionary adapterProperties, boolean propagate) {
         return m_manager.createBundleAdapterService(bundleStateMask, bundleFilter, adapterImplementation, adapterInterface, adapterProperties, propagate);
     }
+    public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, Object adapterImplementation, String[] adapterInterface, Dictionary adapterProperties, boolean propagate) {
+        return m_manager.createBundleAdapterService(bundleStateMask, bundleFilter, adapterImplementation, adapterInterface, adapterProperties, propagate);
+    }
 
     /**
      * Cleans up all services and their dependencies.
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
index 981c13f..040ca85 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
@@ -222,9 +222,19 @@
      * @param adapterProperties additional properties to use with the adapter service registration
      * @return a service that acts as a factory for generating adapters
      */
-    public Service createAdapterService(Class serviceInterface, String serviceFilter, Class adapterInterface, Object adapterImplementation, Dictionary adapterProperties) {
+    public Service createAdapterService(Class serviceInterface, String serviceFilter, String adapterInterface, Object adapterImplementation, Dictionary adapterProperties) {
         return createService()
-            .setImplementation(new AdapterImpl(serviceInterface, serviceFilter, adapterImplementation, adapterInterface.getName(), adapterProperties))
+            .setImplementation(new AdapterImpl(serviceInterface, serviceFilter, adapterImplementation, adapterInterface, adapterProperties))
+            .add(createServiceDependency()
+                .setService(serviceInterface)
+                .setAutoConfig(false)
+                .setCallbacks("added", "removed")
+            );
+    }
+    
+    public Service createAdapterService(Class serviceInterface, String serviceFilter, String[] adapterInterface, Object adapterImplementation, Dictionary adapterProperties) {
+        return createService()
+            .setImplementation(new AdapterImpl(serviceInterface, serviceFilter, adapterImplementation, adapterInterface, adapterProperties))
             .add(createServiceDependency()
                 .setService(serviceInterface)
                 .setAutoConfig(false)
@@ -249,9 +259,18 @@
      * @return a service that acts as a factory for generating resource adapters
      * @see Resource
      */
-    public Service createResourceAdapterService(String resourceFilter, Class adapterInterface, Dictionary adapterProperties, Object adapterImplementation, boolean propagate) {
+    public Service createResourceAdapterService(String resourceFilter, String adapterInterface, Dictionary adapterProperties, Object adapterImplementation, boolean propagate) {
         return createService()
-            .setImplementation(new ResourceAdapterImpl(resourceFilter, adapterImplementation, adapterInterface.getName(), adapterProperties, propagate))
+            .setImplementation(new ResourceAdapterImpl(resourceFilter, adapterImplementation, adapterInterface, adapterProperties, propagate))
+            .add(createResourceDependency()
+                .setFilter(resourceFilter)
+                .setAutoConfig(false)
+                .setCallbacks("added", "removed")
+            );
+    }
+    public Service createResourceAdapterService(String resourceFilter, String[] adapterInterface, Dictionary adapterProperties, Object adapterImplementation, boolean propagate) {
+        return createService()
+            .setImplementation(new ResourceAdapterImpl(resourceFilter, adapterImplementation, adapterInterface, adapterProperties, propagate))
             .add(createResourceDependency()
                 .setFilter(resourceFilter)
                 .setAutoConfig(false)
@@ -286,6 +305,15 @@
                 .setCallbacks("added", "removed")
             );
     }
+    public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, Object adapterImplementation, String[] adapterInterface, Dictionary adapterProperties, boolean propagate) {
+        return createService()
+            .setImplementation(new BundleAdapterImpl(bundleStateMask, bundleFilter, adapterImplementation, adapterInterface, adapterProperties, propagate))
+            .add(createBundleDependency()
+                .setFilter(bundleFilter)
+                .setStateMask(bundleStateMask)
+                .setCallbacks("added", "removed")
+            );
+    }
 
     /**
      * Returns a list of services.
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/BundleDependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/BundleDependency.java
index 87474b6..98676ea 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/BundleDependency.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/BundleDependency.java
@@ -77,4 +77,7 @@
   BundleDependency setStateMask(int mask);
   
   BundleDependency setPropagate(boolean propagate);
+  
+  BundleDependency setInstanceBound(boolean isInstanceBound);
+
 }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/ConfigurationDependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/ConfigurationDependency.java
index 75cc61e..da6e212 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/ConfigurationDependency.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/dependencies/ConfigurationDependency.java
@@ -71,4 +71,7 @@
    * Adds a MetaData regarding a given configuration property.
    */
   ConfigurationDependency add(PropertyMetaData properties);
+  
+  ConfigurationDependency setInstanceBound(boolean isInstanceBound);
+
 }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/InvocationUtil.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/InvocationUtil.java
new file mode 100644
index 0000000..f4298d4
--- /dev/null
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/InvocationUtil.java
@@ -0,0 +1,49 @@
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class InvocationUtil {
+    public static void invokeCallbackMethod(Object[] instances, String methodName, Class[][] signatures, Object[][] parameters) throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+        for (int i = 0; i < instances.length; i++) {
+            invokeCallbackMethod(instances[i], methodName, signatures, parameters);
+            return;
+        }
+        throw new NoSuchMethodException("Method '" + methodName + "' does not exist. Callback skipped.");
+    }
+
+    public static void invokeCallbackMethod(Object instance, String methodName, Class[][] signatures, Object[][] parameters) throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+        Class currentClazz = instance.getClass();
+        while (currentClazz != null) {
+            try {
+                invokeMethod(instance, currentClazz, methodName, signatures, parameters, false);
+                return;
+            }
+            catch (NoSuchMethodException nsme) {
+                // ignore
+            }
+            currentClazz = currentClazz.getSuperclass();
+        }
+        throw new NoSuchMethodException(methodName);
+    }
+
+    public static void invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) throws NoSuchMethodException, InvocationTargetException, IllegalArgumentException, IllegalAccessException {
+        Method m = null;
+        for (int i = 0; i < signatures.length; i++) {
+            Class[] signature = signatures[i];
+            try {
+                m = clazz.getDeclaredMethod(name, signature);
+                if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
+                    m.setAccessible(true);
+                    m.invoke(object, parameters[i]);
+                    return;
+                }
+            }
+            catch (NoSuchMethodException e) {
+                // ignore this and keep looking
+            }
+        }
+        throw new NoSuchMethodException();
+    }
+}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
index 51a42cd..f63b556 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
@@ -20,7 +20,6 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
@@ -65,6 +64,7 @@
     private String m_callbackDestroy;
     private Object m_serviceName;
     private Object m_implementation;
+    private Object m_callbackInstance;
 
     // configuration (dynamic, but does not affect state)
     private Dictionary m_serviceProperties;
@@ -370,6 +370,18 @@
 	    m_callbackDestroy = destroy;
 	    return this;
 	}
+	
+    public synchronized Service setCallbacks(Object instance, String init, String start, String stop, String destroy) {
+        ensureNotActive();
+        m_callbackInstance = instance;
+        m_callbackInit = init;
+        m_callbackStart = start;
+        m_callbackStop = stop;
+        m_callbackDestroy = destroy;
+        return this;
+    }
+	
+	
 
 	public synchronized Service setImplementation(Object implementation) {
 	    ensureNotActive();
@@ -572,26 +584,12 @@
         if (name != null) {
             // invoke method if it exists
             try {
-                Class clazz = m_serviceInstance.getClass();
-                while (clazz != null) {
-                	try {
-                	Method method = clazz.getDeclaredMethod(name, null);
-	                	if (method != null) {
-	                		method.setAccessible(true);
-	                		try {
-    	                		method.invoke(m_serviceInstance, null);
-	                		}
-	                		catch (InvocationTargetException e) {
-	                		    m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + method + ".", e);
-	                		}
-	                		return;
-	                	}
-                	}
-                	catch (NoSuchMethodException e) {
-                		// ignore this, we keep searching if the method does not exist
-                	}
-                	clazz = clazz.getSuperclass();
-                }
+                // if a callback instance was specified, look for the method there, if not, look for the method in the
+                // instance itself
+                Object instance = m_callbackInstance != null ? m_callbackInstance : m_serviceInstance;
+                InvocationUtil.invokeCallbackMethod(instance, name, 
+                    new Class[][] {{ Object.class, DependencyManager.class, Service.class }, { DependencyManager.class, Service.class }, { Object.class }, {}}, 
+                    new Object[][] {{ m_serviceInstance, m_manager, this }, { m_manager, this }, { m_serviceInstance }, {}});
             }
             catch (Exception e) {
                 m_logger.log(Logger.LOG_ERROR, "Error trying to invoke method named " + name + ".", e);
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/AbstractDependency.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/AbstractDependency.java
deleted file mode 100644
index 6dc29c1..0000000
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/AbstractDependency.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.apache.felix.dm.impl.dependencies;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import org.apache.felix.dm.dependencies.Dependency;
-import org.apache.felix.dm.impl.Logger;
-
-public abstract class AbstractDependency implements Dependency, DependencyActivation {
-    private boolean m_isRequired;
-    protected final Logger m_logger;
-
-    public AbstractDependency(Logger logger) {
-        m_logger = logger;
-    }
-
-    public synchronized boolean isRequired() {
-        return m_isRequired;
-    }
-    
-    protected synchronized void setIsRequired(boolean isRequired) {
-        m_isRequired = isRequired;
-    }
-    
-    protected void invokeCallbackMethod(Object[] instances, String methodName, Class[][] signatures, Object[][] parameters) {
-        for (int i = 0; i < instances.length; i++) {
-            try {
-                invokeCallbackMethod(instances[i], methodName, signatures, parameters);
-            }
-            catch (NoSuchMethodException e) {
-                m_logger.log(Logger.LOG_DEBUG, "Method '" + methodName + "' does not exist on " + instances[i] + ". Callback skipped.");
-            }
-        }
-    }
-
-    protected void invokeCallbackMethod(Object instance, String methodName, Class[][] signatures, Object[][] parameters) throws NoSuchMethodException {
-        Class currentClazz = instance.getClass();
-        boolean done = false;
-        while (!done && currentClazz != null) {
-            done = invokeMethod(instance, currentClazz, methodName, signatures, parameters, false);
-            if (!done) {
-                currentClazz = currentClazz.getSuperclass();
-            }
-        }
-        if (!done && currentClazz == null) {
-            throw new NoSuchMethodException(methodName);
-        }
-    }
-
-    protected boolean invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) {
-        Method m = null;
-        for (int i = 0; i < signatures.length; i++) {
-            Class[] signature = signatures[i];
-            try {
-                m = clazz.getDeclaredMethod(name, signature);
-                if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
-                    m.setAccessible(true);
-                    try {
-                        m.invoke(object, parameters[i]);
-                    }
-                    catch (InvocationTargetException e) {
-                        m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + m + ".", e);
-                    }
-                    // we did find and invoke the method, so we return true
-                    return true;
-                }
-            }
-            catch (NoSuchMethodException e) {
-                // ignore this and keep looking
-            }
-            catch (Exception e) {
-                // could not even try to invoke the method
-                m_logger.log(Logger.LOG_ERROR, "Exception while trying to invoke method " + m + ".", e);
-            }
-        }
-        return false;
-    }
-}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
index a97d054..0245174 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/BundleDependencyImpl.java
@@ -35,7 +35,7 @@
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 
-public class BundleDependencyImpl extends AbstractDependency implements BundleDependency, BundleTrackerCustomizer, ServiceComponentDependency {
+public class BundleDependencyImpl extends DependencyBase implements BundleDependency, BundleTrackerCustomizer, ServiceComponentDependency {
 	private final BundleContext m_context;
 	private boolean m_isStarted;
 	private BundleTracker m_tracker;
@@ -63,15 +63,15 @@
 		m_autoConfig = true;
 	}
 
-	public boolean isInstanceBound() {
-		return false; // TODO for now we are never bound to the service implementation instance
-	}
-
+    public BundleDependency setInstanceBound(boolean isInstanceBound) {
+        setIsInstanceBound(isInstanceBound);
+        return this;
+    }
+    
 	public synchronized boolean isAvailable() {
         return m_isAvailable;
     }
 
-
     public void start(DependencyService service) {
         boolean needsStarting = false;
 		synchronized (this) {
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
index 5588d68..42c490c 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ConfigurationDependencyImpl.java
@@ -58,22 +58,21 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ConfigurationDependencyImpl implements ConfigurationDependency, ManagedService, ServiceComponentDependency, DependencyActivation {
+public class ConfigurationDependencyImpl extends DependencyBase implements ConfigurationDependency, ManagedService, ServiceComponentDependency, DependencyActivation {
 	private BundleContext m_context;
 	private String m_pid;
 	private ServiceRegistration m_registration;
     protected List m_services = new ArrayList();
 	private Dictionary m_settings;
 	private boolean m_propagate;
-	private final Logger m_logger;
     private String m_callback;
     private boolean m_isStarted;
 	private final Set m_updateInvokedCache = new HashSet();
     private MetaTypeProviderImpl m_metaType;
 	
 	public ConfigurationDependencyImpl(BundleContext context, Logger logger) {
+	    super(logger);
 		m_context = context;
-		m_logger = logger;
 	}
 	
 	public synchronized boolean isAvailable() {
@@ -89,11 +88,6 @@
 		return true;
 	}
 	
-	public boolean isInstanceBound() {
-	    // for now, configuration dependencies never are
-	    return false;
-	}
-	
 	/**
 	 * Returns <code>true</code> when configuration properties should be propagated
 	 * as service properties.
@@ -102,6 +96,12 @@
 		return m_propagate;
 	}
 	
+    public ConfigurationDependency setInstanceBound(boolean isInstanceBound) {
+        setIsInstanceBound(isInstanceBound);
+        return this;
+    }
+
+	
 	public Dictionary getConfiguration() {
 		return m_settings;
 	}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java
new file mode 100644
index 0000000..ac70c71
--- /dev/null
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/DependencyBase.java
@@ -0,0 +1,43 @@
+package org.apache.felix.dm.impl.dependencies;
+
+import org.apache.felix.dm.dependencies.Dependency;
+import org.apache.felix.dm.impl.InvocationUtil;
+import org.apache.felix.dm.impl.Logger;
+
+public abstract class DependencyBase implements Dependency, DependencyActivation {
+    private boolean m_isRequired;
+    private boolean m_isInstanceBound;
+    protected final Logger m_logger;
+
+    public DependencyBase(Logger logger) {
+        m_logger = logger;
+    }
+
+    public synchronized boolean isRequired() {
+        return m_isRequired;
+    }
+    
+    protected synchronized void setIsRequired(boolean isRequired) {
+        m_isRequired = isRequired;
+    }
+    
+    public final boolean isInstanceBound() {
+        return m_isInstanceBound;
+    }
+
+    public final void setIsInstanceBound(boolean isInstanceBound) {
+        m_isInstanceBound = isInstanceBound;
+    }
+    
+    protected void invokeCallbackMethod(Object[] instances, String methodName, Class[][] signatures, Object[][] parameters) {
+        try {
+            InvocationUtil.invokeCallbackMethod(instances, methodName, signatures, parameters);
+        }
+        catch (NoSuchMethodException e) {
+            m_logger.log(Logger.LOG_DEBUG, "Method '" + methodName + "' does not exist. Callback skipped.");
+        }
+        catch (Exception e) {
+            m_logger.log(Logger.LOG_DEBUG, "Invocation of '" + methodName + "' failed.", e);
+        }
+    }
+}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
index 9e0ea4c..1e5e14c 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ResourceDependencyImpl.java
@@ -18,9 +18,6 @@
  */
 package org.apache.felix.dm.impl.dependencies;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.List;
@@ -33,7 +30,7 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
-public class ResourceDependencyImpl implements ResourceDependency, ResourceHandler, DependencyActivation {
+public class ResourceDependencyImpl extends DependencyBase implements ResourceDependency, ResourceHandler, DependencyActivation {
 	private volatile BundleContext m_context;
 	private volatile ServiceRegistration m_registration;
 //	private long m_resourceCounter;
@@ -43,7 +40,6 @@
     private String m_callbackChanged;
     private String m_callbackRemoved;
     private boolean m_autoConfig;
-    private final Logger m_logger;
     private String m_autoConfigInstance;
     protected List m_services = new ArrayList();
 	private boolean m_isRequired;
@@ -53,11 +49,10 @@
     private List m_resources = new ArrayList();
     private Resource m_resourceInstance;
     private boolean m_propagate;
-	private boolean m_isInstanceBound;
 	
     public ResourceDependencyImpl(BundleContext context, Logger logger) {
+        super(logger);
     	m_context = context;
-    	m_logger = logger;
     	m_autoConfig = true;
     }
     
@@ -65,19 +60,6 @@
 		return m_resources.size() > 0;
 	}
 
-	public boolean isRequired() {
-		return m_isRequired;
-	}
-	
-	public boolean isInstanceBound() {
-		return m_isInstanceBound;
-	}
-	
-	public ResourceDependency setInstanceBound(boolean isInstanceBound) {
-		m_isInstanceBound = isInstanceBound;
-		return this;
-	}
-
 	public void start(DependencyService service) {
 	    boolean needsStarting = false;
 	    synchronized (this) {
@@ -178,21 +160,30 @@
     public void invokeAdded(DependencyService ds, Resource serviceInstance) {
         Object[] callbackInstances = getCallbackInstances(ds);
         if ((callbackInstances != null) && (m_callbackAdded != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackAdded, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackAdded, 
+                new Class[][] {{ Resource.class }, { Object.class }, {}},
+                new Object[][] {{ serviceInstance}, { serviceInstance }, {}}
+            );
         }
     }
 
     public void invokeChanged(DependencyService ds, Resource serviceInstance) {
         Object[] callbackInstances = getCallbackInstances(ds);
         if ((callbackInstances != null) && (m_callbackChanged != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackChanged, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackChanged,
+                new Class[][] {{ Resource.class }, { Object.class }, {}},
+                new Object[][] {{ serviceInstance}, { serviceInstance }, {}}
+            );
         }
     }
 
     public void invokeRemoved(DependencyService ds, Resource serviceInstance) {
         Object[] callbackInstances = getCallbackInstances(ds);
         if ((callbackInstances != null) && (m_callbackRemoved != null)) {
-            invokeCallbackMethod(callbackInstances, m_callbackRemoved, serviceInstance);
+            invokeCallbackMethod(callbackInstances, m_callbackRemoved,
+                new Class[][] {{ Resource.class }, { Object.class }, {}},
+                new Object[][] {{ serviceInstance}, { serviceInstance }, {}}
+            );
         }
     }
 
@@ -300,62 +291,62 @@
         return this;
     }
     
-    private void invokeCallbackMethod(Object[] instances, String methodName, Object service) {
-        for (int i = 0; i < instances.length; i++) {
-            try {
-                invokeCallbackMethod(instances[i], methodName, service);
-            }
-            catch (NoSuchMethodException e) {
-                m_logger.log(Logger.LOG_DEBUG, "Method '" + methodName + "' does not exist on " + instances[i] + ". Callback skipped.");
-            }
-        }
-    }
-
-    private void invokeCallbackMethod(Object instance, String methodName, Object service) throws NoSuchMethodException {
-        Class currentClazz = instance.getClass();
-        boolean done = false;
-        while (!done && currentClazz != null) {
-            done = invokeMethod(instance, currentClazz, methodName,
-                new Class[][] {{Resource.class}, {Object.class}, {}},
-                new Object[][] {{service}, {service}, {}},
-                false);
-            if (!done) {
-                currentClazz = currentClazz.getSuperclass();
-            }
-        }
-        if (!done && currentClazz == null) {
-            throw new NoSuchMethodException(methodName);
-        }
-    }
-    
-    private boolean invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) {
-        Method m = null;
-        for (int i = 0; i < signatures.length; i++) {
-            Class[] signature = signatures[i];
-            try {
-                m = clazz.getDeclaredMethod(name, signature);
-                if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
-                    m.setAccessible(true);
-                    try {
-                        m.invoke(object, parameters[i]);
-                    }
-                    catch (InvocationTargetException e) {
-                        m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + m + ".", e);
-                    }
-                    // we did find and invoke the method, so we return true
-                    return true;
-                }
-            }
-            catch (NoSuchMethodException e) {
-                // ignore this and keep looking
-            }
-            catch (Exception e) {
-                // could not even try to invoke the method
-                m_logger.log(Logger.LOG_ERROR, "Exception while trying to invoke method " + m + ".", e);
-            }
-        }
-        return false;
-    }
+//    private void invokeCallbackMethod(Object[] instances, String methodName, Object service) {
+//        for (int i = 0; i < instances.length; i++) {
+//            try {
+//                invokeCallbackMethod(instances[i], methodName, service);
+//            }
+//            catch (NoSuchMethodException e) {
+//                m_logger.log(Logger.LOG_DEBUG, "Method '" + methodName + "' does not exist on " + instances[i] + ". Callback skipped.");
+//            }
+//        }
+//    }
+//
+//    private void invokeCallbackMethod(Object instance, String methodName, Object service) throws NoSuchMethodException {
+//        Class currentClazz = instance.getClass();
+//        boolean done = false;
+//        while (!done && currentClazz != null) {
+//            done = invokeMethod(instance, currentClazz, methodName,
+//                new Class[][] {{Resource.class}, {Object.class}, {}},
+//                new Object[][] {{service}, {service}, {}},
+//                false);
+//            if (!done) {
+//                currentClazz = currentClazz.getSuperclass();
+//            }
+//        }
+//        if (!done && currentClazz == null) {
+//            throw new NoSuchMethodException(methodName);
+//        }
+//    }
+//    
+//    private boolean invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) {
+//        Method m = null;
+//        for (int i = 0; i < signatures.length; i++) {
+//            Class[] signature = signatures[i];
+//            try {
+//                m = clazz.getDeclaredMethod(name, signature);
+//                if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
+//                    m.setAccessible(true);
+//                    try {
+//                        m.invoke(object, parameters[i]);
+//                    }
+//                    catch (InvocationTargetException e) {
+//                        m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + m + ".", e);
+//                    }
+//                    // we did find and invoke the method, so we return true
+//                    return true;
+//                }
+//            }
+//            catch (NoSuchMethodException e) {
+//                // ignore this and keep looking
+//            }
+//            catch (Exception e) {
+//                // could not even try to invoke the method
+//                m_logger.log(Logger.LOG_ERROR, "Exception while trying to invoke method " + m + ".", e);
+//            }
+//        }
+//        return false;
+//    }
     
     private synchronized Object[] getCallbackInstances(DependencyService ds) {
         if (m_callbackInstance == null) {
@@ -373,7 +364,7 @@
 	
     public synchronized ResourceDependency setRequired(boolean required) {
         ensureNotActive();
-        m_isRequired = required;
+        setIsRequired(required);
         return this;
     }
 
@@ -445,4 +436,9 @@
     public boolean isPropagated() {
         return m_propagate;
     }
+
+    public ResourceDependency setInstanceBound(boolean isInstanceBound) {
+        setIsInstanceBound(isInstanceBound);
+        return this;
+    }
 }
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
index 89f68d4..3c26dd4 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/dependencies/ServiceDependencyImpl.java
@@ -45,7 +45,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ServiceDependencyImpl extends AbstractDependency implements ServiceDependency, ServiceTrackerCustomizer, ServiceComponentDependency {
+public class ServiceDependencyImpl extends DependencyBase implements ServiceDependency, ServiceTrackerCustomizer, ServiceComponentDependency {
     protected List m_services = new ArrayList();
     protected volatile ServiceTracker m_tracker;
     protected BundleContext m_context;
@@ -66,7 +66,6 @@
     private boolean m_autoConfigInvoked;
     private Object m_defaultImplementation;
     private Object m_defaultImplementationInstance;
-    private boolean m_isInstanceBound;
     private boolean m_isAvailable;
     
     private static final Comparator COMPARATOR = new Comparator() {
@@ -187,10 +186,6 @@
         return m_isAvailable;
     }
 
-    public boolean isInstanceBound() {
-        return m_isInstanceBound;
-    }
-
     public synchronized Object getService() {
         Object service = null;
         if (m_isStarted) {
@@ -611,7 +606,7 @@
     }
     
     public ServiceDependency setInstanceBound(boolean isInstanceBound) {
-        m_isInstanceBound = isInstanceBound;
+        setIsInstanceBound(isInstanceBound);
         return this;
     }