diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java
new file mode 100644
index 0000000..5b1acd1
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java
@@ -0,0 +1,69 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+
+/**
+ * Default null object implementation. Uses a dynamic proxy. Null objects are used
+ * as placeholders for services that are not available.
+ * 
+ * @author Marcel Offermans
+ */
+public class DefaultNullObject implements InvocationHandler {
+    private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;
+    private static final Byte DEFAULT_BYTE = new Byte((byte) 0);
+    private static final Short DEFAULT_SHORT = new Short((short) 0);
+    private static final Integer DEFAULT_INT = new Integer(0);
+    private static final Long DEFAULT_LONG = new Long(0);
+    private static final Float DEFAULT_FLOAT = new Float(0.0f);
+    private static final Double DEFAULT_DOUBLE = new Double(0.0);
+    
+    /**
+     * Invokes a method on this null object. The method will return a default
+     * value without doing anything.
+     */
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        Class returnType = method.getReturnType();
+        if (returnType.equals(Boolean.class) || returnType.equals(Boolean.TYPE)) {
+            return DEFAULT_BOOLEAN;
+        }
+        else if (returnType.equals(Byte.class) || returnType.equals(Byte.TYPE)) {
+            return DEFAULT_BYTE;
+        } 
+        else if (returnType.equals(Short.class) || returnType.equals(Short.TYPE)) {
+            return DEFAULT_SHORT;
+        } 
+        else if (returnType.equals(Integer.class) || returnType.equals(Integer.TYPE)) {
+            return DEFAULT_INT;
+        } 
+        else if (returnType.equals(Long.class) || returnType.equals(Long.TYPE)) {
+            return DEFAULT_LONG;
+        } 
+        else if (returnType.equals(Float.class) || returnType.equals(Float.TYPE)) {
+            return DEFAULT_FLOAT;
+        } 
+        else if (returnType.equals(Double.class) || returnType.equals(Double.TYPE)) {
+            return DEFAULT_DOUBLE;
+        } 
+        else {
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/Dependency.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/Dependency.java
new file mode 100644
index 0000000..97a0866
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/Dependency.java
@@ -0,0 +1,66 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+/**
+ * Generic dependency for a service. A dependency can be required or not.
+ * A dependency will be activated by the service it belongs to. The service
+ * will call the <code>start(Service service)</code> and 
+ * <code>stop(Service service)</code> methods.
+ * 
+ * After it has been started, a dependency must callback
+ * the associated service's <code>dependencyAvailable()</code> and 
+ * <code>dependencyUnavailable()</code>
+ * methods. State changes of the dependency itself may only be made as long as
+ * the dependency is not 'active', meaning it is associated with a running service.
+ * 
+ * @author Marcel Offermans
+ */
+public interface Dependency {
+    /**
+     * Returns <code>true</code> if this a required dependency. Required dependencies
+     * are dependencies that must be available before the service can be activated.
+     * 
+     * @return <code>true</code> if the dependency is required
+     */
+    public boolean isRequired();
+    
+    /**
+     * Returns <code>true</code> if the dependency is available.
+     * 
+     * @return <code>true</code> if the dependency is available
+     */
+    public boolean isAvailable();
+    
+    /**
+     * Starts tracking the dependency. This activates some implementation
+     * specific mechanism to do the actual tracking. If the tracking discovers
+     * that the dependency becomes available, it should call 
+     * <code>dependencyAvailable()</code> on the service.
+     * 
+     * @param service the service that is associated with this dependency
+     */
+    public void start(Service service);
+    
+    /**
+     * Stops tracking the dependency. This deactivates the tracking. If the
+     * dependency was available, the tracker should call 
+     * <code>dependencyUnavaible()</code> before stopping itself to ensure
+     * that dependencies that aren't "active" are unavailable.
+     */
+    public void stop(Service service);
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
new file mode 100644
index 0000000..38847b0
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
@@ -0,0 +1,123 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import java.util.List;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Base bundle activator class. Subclass this activator if you want to use dependency
+ * management in your bundle. There are two methods you should implement:
+ * <code>init()</code> and <code>destroy()</code>. Both methods take two arguments,
+ * the bundle context and the dependency manager. The dependency manager can be used
+ * to define all the dependencies.
+ * 
+ * @author Marcel Offermans
+ */
+public abstract class DependencyActivatorBase implements BundleActivator {
+    private BundleContext m_context;
+    private DependencyManager m_manager;
+    
+    /**
+     * Initialize the dependency manager. Here you can add all services and their dependencies.
+     * If something goes wrong and you do not want your bundle to be started, you can throw an
+     * exception. This exception will be passed on to the <code>start()</code> method of the
+     * bundle activator, causing the bundle not to start.
+     * 
+     * @param context the bundle context
+     * @param manager the dependency manager
+     * @throws Exception if the initialization fails
+     */
+    public abstract void init(BundleContext context, DependencyManager manager) throws Exception;
+    
+    /**
+     * Destroy the dependency manager. Here you can remove all services and their dependencies.
+     * Actually, the base class will clean up your dependencies anyway, so most of the time you
+     * don't need to do anything here.
+     * If something goes wrong and you do not want your bundle to be stopped, you can throw an
+     * exception. This exception will be passed on to the <code>stop()</code> method of the
+     * bundle activator, causing the bundle not to stop.
+     * 
+     * @param context the bundle context
+     * @param manager the dependency manager
+     * @throws Exception if the destruction fails
+     */
+    public abstract void destroy(BundleContext context, DependencyManager manager) throws Exception;
+
+    /**
+     * Start method of the bundle activator. Initializes the dependency manager
+     * and calls <code>init()</code>.
+     * 
+     * @param context the bundle context
+     */
+    public void start(BundleContext context) throws Exception {
+        m_context = context;
+        m_manager = new DependencyManager(context);
+        init(m_context, m_manager);
+    }
+
+    /**
+     * Stop method of the bundle activator. Calls the <code>destroy()</code> method
+     * and cleans up all left over dependencies.
+     * 
+     * @param context the bundle context
+     */
+    public void stop(BundleContext context) throws Exception {
+        destroy(m_context, m_manager);
+        cleanup(m_manager);
+        m_manager = null;
+        m_context = null;
+    }
+    
+    /**
+     * Creates a new service.
+     * 
+     * @return the new service
+     */
+    public Service createService() {
+        return new ServiceImpl(m_context);
+    }
+    
+    /**
+     * Creates a new service dependency.
+     * 
+     * @return the service dependency
+     */
+    public ServiceDependency createServiceDependency() {
+        return new ServiceDependency(m_context);
+    }
+
+    /**
+     * Cleans up all services and their dependencies.
+     * 
+     * @param manager the dependency manager
+     */
+    private void cleanup(DependencyManager manager) {
+        List services = manager.getServices();
+        for (int i = services.size() - 1; i >= 0; i--) {
+            Service service = (Service) services.get(i);
+            manager.remove(service);
+            // remove any state listeners that are still registered
+            if (service instanceof ServiceImpl) {
+                ServiceImpl si = (ServiceImpl) service;
+                si.removeStateListeners();
+            }
+        }
+    }
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
new file mode 100644
index 0000000..e641615
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
@@ -0,0 +1,92 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * The dependency manager. Manages all services and their dependencies.
+ * 
+ * @author Marcel Offermans
+ */
+public class DependencyManager {
+    private BundleContext m_context;
+    private List m_services = Collections.synchronizedList(new ArrayList());
+
+    /**
+     * Creates a new dependency manager.
+     * 
+     * @param context the bundle context
+     */
+    public DependencyManager(BundleContext context) {
+        m_context = context;
+    }
+    
+    /**
+     * Adds a new service to the dependency manager. After the service was added
+     * it will be started immediately.
+     * 
+     * @param service the service to add
+     */
+    public void add(Service service) {
+        m_services.add(service);
+        service.start();
+    }
+
+    /**
+     * Removes a service from the dependency manager. Before the service is removed
+     * it is stopped first.
+     * 
+     * @param service the service to remove
+     */
+    public void remove(Service service) {
+        service.stop();
+        m_services.remove(service);
+    }
+
+    /**
+     * Creates a new service.
+     * 
+     * @return the new service
+     */
+    public Service createService() {
+        return new ServiceImpl(m_context);
+    }
+    
+    /**
+     * Creates a new service dependency.
+     * 
+     * @return the service dependency
+     */
+    public ServiceDependency createServiceDependency() {
+        return new ServiceDependency(m_context);
+    }
+    
+    /**
+     * Returns a list of services.
+     * 
+     * @return a list of services
+     */
+    public List getServices() {
+        return Collections.unmodifiableList(m_services);
+    }
+
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java
new file mode 100644
index 0000000..85a6c4a
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java
@@ -0,0 +1,195 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import java.util.Dictionary;
+import java.util.List;
+
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Service interface.
+ * 
+ * @author Marcel Offermans
+ */
+public interface Service {
+    /**
+     * Adds a new dependency to this service.
+     * 
+     * @param dependency the dependency to add
+     * @return this service
+     */
+    public Service add(Dependency dependency);
+    
+    /**
+     * Removes a dependency from this service.
+     * 
+     * @param dependency the dependency to remove
+     * @return this service
+     */
+    public Service remove(Dependency dependency);
+
+    /**
+     * Sets the public interface under which this service should be registered
+     * in the OSGi service registry.
+     *  
+     * @param serviceName the name of the service interface
+     * @param properties the properties for this service
+     * @return this service
+     */
+    public Service setInterface(String serviceName, Dictionary properties);
+    /**
+     * Sets the public interfaces under which this service should be registered
+     * in the OSGi service registry.
+     *  
+     * @param serviceNames the names of the service interface
+     * @param properties the properties for this service
+     * @return this service
+     */
+    public Service setInterface(String[] serviceNames, Dictionary properties);
+    
+    /**
+     * Sets the implementation for this service. You can actually specify
+     * an instance you have instantiated manually, or a <code>Class</code>
+     * that will be instantiated using its default constructor when the
+     * required dependencies are resolved (effectively giving you a lazy
+     * instantiation mechanism).
+     * 
+     * There are four special methods that are called when found through
+     * reflection to give you some life-cycle management options:
+     * <ol>
+     * <li><code>init()</code> when the implementation should be initialized,
+     * before it is actually registered as a service (if at all)</li>
+     * <li><code>start()</code> when the implementation has been registered
+     * as a service (if at all)</li>
+     * <li><code>stop()</code> when the implementation will be stopped, just
+     * before the service will go away (if it had been registered)</li>
+     * <li><code>destroy()</code>after the service has gone away (if it had
+     * been registered)</li>
+     * </ol>
+     * In short, this allows you to initialize your instance before it is
+     * registered, perform some post-initialization and pre-destruction code
+     * as well as final cleanup. If a method is not defined, it simply is not
+     * called, so you can decide which one(s) you need.
+     * 
+     * @param implementation the implementation
+     * @return this service
+     */
+    public Service setImplementation(Object implementation);
+    
+    /**
+     * Returns a list of dependencies.
+     * 
+     * @return a list of dependencies
+     */
+    public List getDependencies();
+    
+    /**
+     * Returns the service registration for this service. The method
+     * will return <code>null</code> if no service registration is
+     * available.
+     * 
+     * @return the service registration
+     */
+    public ServiceRegistration getServiceRegistration();
+    
+    /**
+     * Returns the service instance for this service. The method will
+     * return <code>null</code> if no service instance is available.
+     * 
+     * @return the service instance
+     */
+    public Object getService();
+
+    /**
+     * Returns the service properties associated with the service.
+     * 
+     * @return the properties or <code>null</code> if there are none
+     */
+    public Dictionary getServiceProperties();
+    
+    /**
+     * Sets the service properties associated with the service. If the service
+     * was already registered, it will be updated.
+     * 
+     * @param serviceProperties the properties
+     */
+    public void setServiceProperties(Dictionary serviceProperties);
+    
+    /**
+     * Sets the names of the methods used as callbacks. These methods, when found, are
+     * invoked as part of the life-cycle management of the service implementation. The
+     * methods should not have any parameters.
+     * 
+     * @param init the name of the init method
+     * @param start the name of the start method
+     * @param stop the name of the stop method
+     * @param destroy the name of the destroy method
+     * @return the service instance
+     */
+    public Service setCallbacks(String init, String start, String stop, String destroy);
+
+    // listener
+    /**
+     * Adds a service state listener to this service.
+     * 
+     * @param listener the state listener
+     */
+    public void addStateListener(ServiceStateListener listener);
+
+    /**
+     * Removes a service state listener from this service.
+     * 
+     * @param listener the state listener
+     */
+    public void removeStateListener(ServiceStateListener listener);
+    
+    // events, must be fired when the dependency is started/active
+    
+    /**
+     * Will be called when the dependency becomes available.
+     * 
+     * @param dependency the dependency
+     */
+    public void dependencyAvailable(Dependency dependency);
+    
+    /**
+     * Will be called when the dependency changes.
+     * 
+     * @param dependency the dependency
+     */
+    public void dependencyUnavailable(Dependency dependency);
+    
+    /**
+     * Will be called when the dependency becomes unavailable.
+     * 
+     * @param dependency the dependency
+     */
+    public void dependencyChanged(Dependency dependency);
+
+    /**
+     * Starts the service. This activates the dependency tracking mechanism
+     * for this service.
+     */
+    public void start();
+    
+    /**
+     * Stops the service. This deactivates the dependency tracking mechanism
+     * for this service.
+     */
+    public void stop();
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
new file mode 100644
index 0000000..6f0d97f
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
@@ -0,0 +1,429 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Service dependency that can track an OSGi service.
+ * 
+ * @author Marcel Offermans
+ */
+public class ServiceDependency implements Dependency, ServiceTrackerCustomizer {
+    private boolean m_isRequired;
+    private Service m_service;
+    private ServiceTracker m_tracker;
+    private BundleContext m_context;
+    private boolean m_isAvailable;
+    private Class m_trackedServiceName;
+    private Object m_nullObject;
+    private String m_trackedServiceFilter;
+    private ServiceReference m_trackedServiceReference;
+    private boolean m_isStarted;
+    private Object m_callbackInstance;
+    private String m_callbackAdded;
+    private String m_callbackChanged;
+    private String m_callbackRemoved;
+    private boolean m_autoConfig;
+    private ServiceReference m_reference;
+    private Object m_serviceInstance;
+    
+    /**
+     * Creates a new service dependency.
+     * 
+     * @param context the bundle context
+     */
+    public ServiceDependency(BundleContext context) {
+        m_context = context;
+        m_autoConfig = true;
+    }
+
+    public boolean isRequired() {
+        return m_isRequired;
+    }
+
+    public boolean isAvailable() {
+        return m_isAvailable;
+    }
+    
+    public boolean isAutoConfig() {
+        return m_autoConfig;
+    }
+
+    public synchronized Object getService() {
+        Object service = null;
+        if (m_isStarted) {
+            service = m_tracker.getService();
+        }
+        if (service == null) {
+            service = getNullObject(); 
+        }
+        return service;
+    }
+
+    private Object getNullObject() {
+        if (m_nullObject == null) {
+            m_nullObject = Proxy.newProxyInstance(m_trackedServiceName.getClassLoader(), new Class[] {m_trackedServiceName}, new DefaultNullObject()); 
+        }
+        return m_nullObject;
+    }
+    
+    public Class getInterface() {
+        return m_trackedServiceName;
+    }
+
+    public synchronized void start(Service service) {
+        if (m_isStarted) {
+            throw new IllegalStateException("Service dependency was already started." + m_trackedServiceName);
+        }
+        m_service = service;
+        if (m_trackedServiceName != null) {
+            if (m_trackedServiceFilter != null) {
+                try {
+                    m_tracker = new ServiceTracker(m_context, m_context.createFilter(m_trackedServiceFilter), this);
+                }
+                catch (InvalidSyntaxException e) {
+                    throw new IllegalStateException("Invalid filter definition for dependency.");
+                }
+            }
+            else if (m_trackedServiceReference != null) {
+                m_tracker = new ServiceTracker(m_context, m_trackedServiceReference, this);
+            }
+            else {
+                m_tracker = new ServiceTracker(m_context, m_trackedServiceName.getName(), this);
+            }
+        }
+        else {
+            throw new IllegalStateException("Could not create tracker for dependency, no service name specified.");
+        }
+        m_isStarted = true;
+        m_tracker.open();
+    }
+
+    public synchronized void stop(Service service) {
+        if (!m_isStarted) {
+            throw new IllegalStateException("Service dependency was not started.");
+        }
+        m_tracker.close();
+        m_isStarted = false;
+        m_tracker = null;
+    }
+
+    public Object addingService(ServiceReference ref) {
+        Object service = m_context.getService(ref);
+        // we remember these for future reference, needed for required service callbacks
+        m_reference = ref;
+        m_serviceInstance = service;
+        return service;
+    }
+
+    public void addedService(ServiceReference ref, Object service) {
+        if (makeAvailable()) {
+            m_service.dependencyAvailable(this);
+        }
+        else {
+            m_service.dependencyChanged(this);
+        }
+        // try to invoke callback, if specified, but only for optional dependencies
+        // because callbacks for required dependencies are handled differently
+        if (!isRequired()) {
+            invokeAdded(ref, service);
+        }
+    }
+
+    public void invokeAdded() {
+        invokeAdded(m_reference, m_serviceInstance);
+    }
+    
+    public void invokeAdded(ServiceReference reference, Object serviceInstance) {
+        Object callbackInstance = getCallbackInstance();
+        if ((callbackInstance != null) && (m_callbackAdded != null)) {
+            try {
+                invokeCallbackMethod(callbackInstance, m_callbackAdded, reference, serviceInstance);
+            } catch (NoSuchMethodException e) {
+                // silently ignore this
+            }
+        }
+    }
+
+    public void modifiedService(ServiceReference ref, Object service) {
+        m_reference = ref;
+        m_serviceInstance = service;
+        m_service.dependencyChanged(this);
+        // only invoke the changed callback if the service itself is "active"
+        if (((ServiceImpl) m_service).isRegistered()) {
+            invokeChanged(ref, service);
+        }
+    }
+
+    public void invokeChanged(ServiceReference reference, Object serviceInstance) {
+        Object callbackInstance = getCallbackInstance();
+        if ((callbackInstance != null) && (m_callbackChanged != null)) {
+            try {
+                if (m_reference == null) {
+                    Thread.dumpStack();
+                }
+                invokeCallbackMethod(callbackInstance, m_callbackChanged, reference, serviceInstance);
+            }
+            catch (NoSuchMethodException e) {
+                // ignore when the service has no such method
+            }
+        }
+    }
+
+    public void removedService(ServiceReference ref, Object service) {
+        if (makeUnavailable()) {
+            m_service.dependencyUnavailable(this);
+        }
+        // try to invoke callback, if specified, but only for optional dependencies
+        // because callbacks for required dependencies are handled differently
+        if (!isRequired()) {
+            invokeRemoved(ref, service);
+        }
+        m_context.ungetService(ref);
+    }
+
+    public void invokeRemoved() {
+        invokeRemoved(m_reference, m_serviceInstance);
+    }
+    
+    public void invokeRemoved(ServiceReference reference, Object serviceInstance) {
+        Object callbackInstance = getCallbackInstance();
+        if ((callbackInstance != null) && (m_callbackRemoved != null)) {
+            try {
+                if (m_reference == null) {
+                    Thread.dumpStack();
+                }
+                invokeCallbackMethod(callbackInstance, m_callbackRemoved, reference, serviceInstance);
+            }
+            catch (NoSuchMethodException e) {
+                // ignore when the service has no such method
+            }
+        }
+    }
+    
+    private synchronized boolean makeAvailable() {
+        if (!m_isAvailable) {
+            m_isAvailable = true;
+            return true;
+        }
+        return false;
+    }
+    
+    private synchronized boolean makeUnavailable() {
+        if ((m_isAvailable) && (m_tracker.getServiceReference() == null)) {
+            m_isAvailable = false;
+            return true;
+        }
+        return false;
+    }
+    
+    private Object getCallbackInstance() {
+        Object callbackInstance = m_callbackInstance;
+        if (callbackInstance == null) {
+            callbackInstance = m_service.getService();
+        }
+        return callbackInstance;
+    }
+    
+    // TODO a lot of things in this method can be cached instead of done each time
+    // TODO Richard had an example where he could not invoke a private method
+    private void invokeCallbackMethod(Object instance, String methodName, ServiceReference reference, Object service) throws NoSuchMethodException {
+        Method method = null;
+        Class clazz = instance.getClass();
+        AccessibleObject.setAccessible(clazz.getDeclaredMethods(), true);
+        try {
+            try {
+                method = clazz.getDeclaredMethod(methodName, new Class[] {ServiceReference.class, Object.class});
+                method.invoke(instance, new Object[] {reference, service});
+            }
+            catch (NoSuchMethodException e) {
+                try {
+                    method = clazz.getDeclaredMethod(methodName, new Class[] {ServiceReference.class});
+                    method.invoke(instance, new Object[] {reference});
+                } 
+                catch (NoSuchMethodException e1) {
+                    try {
+                        method = clazz.getDeclaredMethod(methodName, new Class[] {Object.class});
+                        method.invoke(instance, new Object[] {service});
+                    } 
+                    catch (NoSuchMethodException e2) {
+                        try {
+                            method = clazz.getDeclaredMethod(methodName, new Class[] {m_trackedServiceName});
+                            method.invoke(instance, new Object[] {service});
+                        } 
+                        catch (NoSuchMethodException e3) {
+                            method = clazz.getDeclaredMethod(methodName, null);
+                            method.invoke(instance, null);
+                        }
+                    }
+                }
+            }
+        } catch (IllegalArgumentException e1) {
+            // TODO handle this exception, probably best to ignore it
+            e1.printStackTrace();
+        } catch (IllegalAccessException e1) {
+            // TODO handle this exception, probably best to ignore it
+            e1.printStackTrace();
+        } catch (InvocationTargetException e1) {
+            // TODO handle this exception, probably best to ignore it
+            e1.printStackTrace();
+        }
+    }
+    
+    // ----- CREATION
+
+    /**
+     * Sets the name of the service that should be tracked. 
+     * 
+     * @param serviceName the name of the service
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setService(Class serviceName) {
+        ensureNotActive();
+        if (serviceName == null) {
+            throw new IllegalArgumentException("Service name cannot be null.");
+        }
+        m_trackedServiceName = serviceName;
+        m_trackedServiceReference = null;
+        m_trackedServiceFilter = null;
+        return this;
+    }
+    
+    /**
+     * Sets the name of the service that should be tracked. You can either specify
+     * only the name, or the name and a filter. In the latter case, the filter is used
+     * to track the service and should only return services of the type that was specified
+     * in the name.
+     * 
+     * @param serviceName the name of the service
+     * @param serviceFilter the filter condition
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setService(Class serviceName, String serviceFilter) {
+        ensureNotActive();
+        if (serviceName == null) {
+            throw new IllegalArgumentException("Service name cannot be null.");
+        }
+        m_trackedServiceName = serviceName;
+        m_trackedServiceFilter = serviceFilter;
+        m_trackedServiceReference = null;
+        return this;
+    }
+
+    /**
+     * Sets the name of the service that should be tracked. You can either specify
+     * only the name, or the name and a reference. In the latter case, the service reference
+     * is used to track the service and should only return services of the type that was 
+     * specified in the name.
+     * 
+     * @param serviceName the name of the service
+     * @param serviceReference the service reference to track
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setService(Class serviceName, ServiceReference serviceReference) {
+        ensureNotActive();
+        if (serviceName == null) {
+            throw new IllegalArgumentException("Service name cannot be null.");
+        }
+        m_trackedServiceName = serviceName;
+        m_trackedServiceReference = serviceReference;
+        m_trackedServiceFilter = null;
+        return this;
+    }
+
+    /**
+     * Sets the required flag which determines if this service is required or not.
+     * 
+     * @param required the required flag
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setRequired(boolean required) {
+        ensureNotActive();
+        m_isRequired = required;
+        return this;
+    }
+
+    /**
+     * Sets auto configuration for this service. Auto configuration allows the
+     * dependency to fill in any attributes in the service implementation that
+     * are of the same type as this dependency. Default is on.
+     * 
+     * @param autoConfig the value of auto config
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setAutoConfig(boolean autoConfig) {
+        ensureNotActive();
+        m_autoConfig = autoConfig;
+        return this;
+    }
+    
+    /**
+     * Sets the callbacks for this service. These callbacks can be used as hooks whenever
+     * a dependency is added or removed. They are called on the service implementation.
+     * 
+     * @param added the method to call when a service was added
+     * @param removed the method to call when a service was removed
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setCallbacks(String added, String removed) {
+        return setCallbacks(null, added, null, removed);
+    }
+    public synchronized ServiceDependency setCallbacks(String added, String changed, String removed) {
+        return setCallbacks(null, added, changed, removed);
+    }
+    public synchronized ServiceDependency setCallbacks(Object instance, String added, String removed) {
+        return setCallbacks(instance, added, null, removed);
+    }
+    
+    /**
+     * Sets the callbacks for this service. These callbacks can be used as hooks whenever
+     * a dependency is added or removed. They are called on the instance you provide.
+     * 
+     * @param instance the instance to call the callbacks on
+     * @param added the method to call when a service was added
+     * @param changed the method to call when a service was changed
+     * @param removed the method to call when a service was removed
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setCallbacks(Object instance, String added, String changed, String removed) {
+        ensureNotActive();
+        m_callbackInstance = instance;
+        m_callbackAdded = added;
+        m_callbackChanged = changed;
+        m_callbackRemoved = removed;
+        return this;
+    }
+    
+    
+    private void ensureNotActive() {
+        if (m_tracker != null) {
+            throw new IllegalStateException("Cannot modify state while active.");
+        }
+    }
+    
+    public String toString() {
+        return "ServiceDependency[" + m_trackedServiceName + " " + m_trackedServiceFilter + " " + m_isRequired + "] for " + m_service;
+    }
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
new file mode 100644
index 0000000..26a6a4f
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
@@ -0,0 +1,565 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Service implementation.
+ * 
+ * @author Marcel Offermans
+ */
+public class ServiceImpl implements Service {
+    private static final ServiceRegistration NULL_REGISTRATION;
+    private static final int STARTING = 1;
+    private static final int WAITING_FOR_REQUIRED = 2;
+    private static final int TRACKING_OPTIONAL = 3;
+    private static final int STOPPING = 4;
+    private static final String[] STATE_NAMES = {
+        "(unknown)", 
+        "starting", 
+        "waiting for required dependencies", 
+        "tracking optional dependencies", 
+        "stopping"};
+    
+    private BundleContext m_context;
+    private ServiceRegistration m_registration;
+    
+    private String m_callbackInit;
+    private String m_callbackStart;
+    private String m_callbackStop;
+    private String m_callbackDestroy;
+    
+    private List m_listeners = new ArrayList();
+    private ArrayList m_dependencies = new ArrayList();
+    private int m_state;
+    
+    private Object m_serviceInstance;
+    private Object m_implementation;
+    private Object m_serviceName;
+    private Dictionary m_serviceProperties;
+
+    public ServiceImpl(BundleContext context) {
+        m_state = STARTING;
+        m_context = context;
+        m_callbackInit = "init";
+        m_callbackStart = "start";
+        m_callbackStop = "stop";
+        m_callbackDestroy = "destroy";
+    }
+    
+    public Service add(Dependency dependency) {
+        synchronized (m_dependencies) {
+            m_dependencies.add(dependency);
+        }
+        if (m_state == WAITING_FOR_REQUIRED) {
+            // if we're waiting for required dependencies, and
+            // this is a required dependency, start tracking it
+            // ...otherwise, we don't need to do anything yet
+            if (dependency.isRequired()) {
+                dependency.start(this);
+            }
+        }
+        else if (m_state == TRACKING_OPTIONAL) {
+            // start tracking the dependency
+            dependency.start(this);
+            if (dependency.isRequired() && !dependency.isAvailable()) {
+                // if this is a required dependency and it can not
+                // be resolved right away, then we need to go back to 
+                // the waiting for required state, until this
+                // dependency is available
+                deactivateService();
+            }
+        }
+        return this;
+    }
+
+    public Service remove(Dependency dependency) {
+        synchronized (m_dependencies) {
+            m_dependencies.remove(dependency);
+        }
+        if (m_state == TRACKING_OPTIONAL) {
+            // if we're tracking optional dependencies, then any
+            // dependency that is removed can be stopped without
+            // causing state changes
+            dependency.stop(this);
+        }
+        else if (m_state == WAITING_FOR_REQUIRED) {
+            // if we're waiting for required dependencies, then
+            // we only need to stop tracking the dependency if it
+            // too is required; this might trigger a state change
+            dependency.stop(this);
+            if (allRequiredDependenciesAvailable()) {
+                activateService();
+            }
+        }
+        return this;
+    }
+
+    public List getDependencies() {
+        List list;
+        synchronized (m_dependencies) {
+            list = (List) m_dependencies.clone();
+        }
+        return list;
+    }
+    
+    public ServiceRegistration getServiceRegistration() {
+        return m_registration;
+    }
+    
+    public Object getService() {
+        return m_serviceInstance;
+    }
+    
+    public void dependencyAvailable(Dependency dependency) {
+        if ((dependency.isRequired()) 
+            && (m_state == WAITING_FOR_REQUIRED) 
+            && (allRequiredDependenciesAvailable())) {
+            activateService();
+        }
+        if ((!dependency.isRequired()) && (m_state == TRACKING_OPTIONAL)) {
+            updateInstance(dependency);
+        }
+    }
+
+    public void dependencyChanged(Dependency dependency) {
+        if (m_state == TRACKING_OPTIONAL) {
+            updateInstance(dependency);
+        }
+    }
+    
+    public void dependencyUnavailable(Dependency dependency) {
+        if (dependency.isRequired()) {
+            if (m_state == TRACKING_OPTIONAL) {
+                if (!allRequiredDependenciesAvailable()) {
+                    deactivateService();
+                }
+            }
+        }
+        else {
+            // optional dependency
+        }
+        if (m_state == TRACKING_OPTIONAL) {
+            updateInstance(dependency);
+        }
+    }
+
+    public synchronized void start() {
+        if ((m_state != STARTING) && (m_state != STOPPING)) {
+            throw new IllegalStateException("Cannot start from state " + STATE_NAMES[m_state]);
+        }
+        startTrackingRequired();
+        if (allRequiredDependenciesAvailable() && (m_state == WAITING_FOR_REQUIRED)) {
+            activateService();
+        }
+    }
+
+    public synchronized void stop() {
+        if ((m_state != WAITING_FOR_REQUIRED) && (m_state != TRACKING_OPTIONAL)) {
+            if ((m_state > 0) && (m_state < STATE_NAMES.length)) {
+                throw new IllegalStateException("Cannot stop from state " + STATE_NAMES[m_state]);
+            }
+            throw new IllegalStateException("Cannot stop from unknown state.");
+        }
+        if (m_state == TRACKING_OPTIONAL) {
+            deactivateService();
+        }
+        stopTrackingRequired();
+    }
+
+    private void activateService() {
+        // service activation logic, first we initialize the service instance itself
+        // meaning it is created if necessary and the bundle context is set
+        initService();
+        // then we invoke the init callback so the service can further initialize
+        // itself
+        invoke(m_callbackInit);
+        // now is the time to configure the service, meaning all required
+        // dependencies will be set and any callbacks called
+        configureService();
+        // inform the state listeners we're starting
+        stateListenersStarting();
+        // start tracking optional services
+        startTrackingOptional();
+        // invoke the start callback, since we're now ready to be used
+        invoke(m_callbackStart);
+        // register the service in the framework's service registry
+        registerService();
+        // inform the state listeners we've started
+        stateListenersStarted();
+    }
+
+    private void deactivateService() {
+        // service deactivation logic, first inform the state listeners
+        // we're stopping
+        stateListenersStopping();
+        // then, unregister the service from the framework
+        unregisterService();
+        // invoke the stop callback
+        invoke(m_callbackStop);
+        // stop tracking optional services
+        stopTrackingOptional();
+        // inform the state listeners we've stopped
+        stateListenersStopped();
+        // invoke the destroy callback
+        invoke(m_callbackDestroy);
+        // destroy the service instance
+        destroyService();
+    }
+
+    private void invoke(String name) {
+        if (name != null) {
+            // invoke method if it exists
+            AccessibleObject.setAccessible(m_serviceInstance.getClass().getDeclaredMethods(), true);
+            try {
+                m_serviceInstance.getClass().getDeclaredMethod(name, null).invoke(m_serviceInstance, null);
+            }
+            catch (NoSuchMethodException e) {
+                // ignore this, we don't care if the method does not exist
+            }
+            catch (Exception e) {
+                // TODO handle this exception
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    private synchronized void stateListenersStarting() {
+        Iterator i = m_listeners.iterator();
+        while (i.hasNext()) {
+            ServiceStateListener ssl = (ServiceStateListener) i.next();
+            ssl.starting(this);
+        }
+    }
+
+    private synchronized void stateListenersStarted() {
+        Iterator i = m_listeners.iterator();
+        while (i.hasNext()) {
+            ServiceStateListener ssl = (ServiceStateListener) i.next();
+            ssl.started(this);
+        }
+    }
+
+    private synchronized void stateListenersStopping() {
+        Iterator i = m_listeners.iterator();
+        while (i.hasNext()) {
+            ServiceStateListener ssl = (ServiceStateListener) i.next();
+            ssl.stopping(this);
+        }
+    }
+
+    private synchronized void stateListenersStopped() {
+        Iterator i = m_listeners.iterator();
+        while (i.hasNext()) {
+            ServiceStateListener ssl = (ServiceStateListener) i.next();
+            ssl.stopped(this);
+        }
+    }
+
+    private boolean allRequiredDependenciesAvailable() {
+        Iterator i = getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (dependency.isRequired() && !dependency.isAvailable()) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    private void startTrackingOptional() {
+        m_state = TRACKING_OPTIONAL;
+        Iterator i = getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (!dependency.isRequired()) {
+                dependency.start(this);
+            }
+        }
+    }
+
+    private void stopTrackingOptional() {
+        m_state = WAITING_FOR_REQUIRED;
+        Iterator i = getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (!dependency.isRequired()) {
+                dependency.stop(this);
+            }
+        }
+    }
+
+    private void startTrackingRequired() {
+        m_state = WAITING_FOR_REQUIRED;
+        Iterator i = getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (dependency.isRequired()) {
+                dependency.start(this);
+            }
+        }
+    }
+
+    private void stopTrackingRequired() {
+        m_state = STOPPING;
+        Iterator i = getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (dependency.isRequired()) {
+                dependency.stop(this);
+            }
+        }
+    }
+
+    private void initService() {
+        if (m_implementation instanceof Class) {
+            // instantiate
+            try {
+                m_serviceInstance = ((Class) m_implementation).newInstance();
+            } catch (InstantiationException e) {
+                // TODO handle this exception
+                e.printStackTrace();
+            } catch (IllegalAccessException e) {
+                // TODO handle this exception
+                e.printStackTrace();
+            }
+        }
+        else {
+            m_serviceInstance = m_implementation;
+        }
+        // configure the bundle context
+        configureImplementation(BundleContext.class, m_context);
+        configureImplementation(ServiceRegistration.class, NULL_REGISTRATION);
+        
+    }
+    
+    private void configureService() {
+        // configure all services (the optional dependencies might be configured
+        // as null objects but that's what we want at this point)
+        configureServices();
+    }
+
+    private void destroyService() {
+        unconfigureServices();
+        m_serviceInstance = null;
+    }
+    
+    private void registerService() {
+        if (m_serviceName != null) {
+            ServiceRegistrationImpl wrapper = new ServiceRegistrationImpl();
+            m_registration = wrapper;
+            configureImplementation(ServiceRegistration.class, wrapper);
+            // service name can either be a string or an array of strings
+            ServiceRegistration registration;
+            if (m_serviceName instanceof String) {
+                registration = m_context.registerService((String) m_serviceName, m_serviceInstance, m_serviceProperties);
+            }
+            else {
+                registration = m_context.registerService((String[]) m_serviceName, m_serviceInstance, m_serviceProperties);
+            }
+            wrapper.setServiceRegistration(registration);
+        }
+    }
+    
+    private void unregisterService() {
+        if (m_serviceName != null) {
+            m_registration.unregister();
+            configureImplementation(ServiceRegistration.class, NULL_REGISTRATION);
+        }
+    }
+    
+    private void updateInstance(Dependency dependency) {
+        if (dependency instanceof ServiceDependency) {
+            ServiceDependency sd = (ServiceDependency) dependency;
+            // update the dependency in the service instance (it will use
+            // a null object if necessary)
+            if (sd.isAutoConfig()) {
+                configureImplementation(sd.getInterface(), sd.getService());
+            }
+        }
+    }
+    
+    /**
+     * Configure a field in the service implementation. The service implementation
+     * is searched for fields that have the same type as the class that was specified
+     * and for each of these fields, the specified instance is filled in.
+     * 
+     * @param clazz the class to search for
+     * @param instance the instance to fill in
+     */
+    private void configureImplementation(Class clazz, Object instance) {
+        Class serviceClazz = m_serviceInstance.getClass();
+        while (serviceClazz != null) {
+            Field[] fields = serviceClazz.getDeclaredFields();
+            AccessibleObject.setAccessible(fields, true);
+            for (int j = 0; j < fields.length; j++) {
+                if (fields[j].getType().equals(clazz)) {
+                    try {
+                        // synchronized makes sure the field is actually written to immediately
+                        synchronized (new Object()) {
+                            fields[j].set(m_serviceInstance, instance);
+                        }
+                    }
+                    catch (Exception e) {
+                        System.err.println("Exception while trying to set " + fields[j].getName() +
+                            " of type " + fields[j].getType().getName() +
+                            " by classloader " + fields[j].getType().getClassLoader() +
+                            " which should equal type " + clazz.getName() +
+                            " by classloader " + clazz.getClassLoader() +
+                            " of type " + serviceClazz.getName() +
+                            " by classloader " + serviceClazz.getClassLoader() +
+                            " on " + m_serviceInstance + 
+                            " by classloader " + m_serviceInstance.getClass().getClassLoader() +
+                            "\nDumping stack:"
+                        );
+                        e.printStackTrace();
+                        System.out.println("C: " + clazz);
+                        System.out.println("I: " + instance);
+                        System.out.println("I:C: " + instance.getClass().getClassLoader());
+                        Class[] classes = instance.getClass().getInterfaces();
+                        for (int i = 0; i < classes.length; i++) {
+                            Class c = classes[i];
+                            System.out.println("I:C:I: " + c);
+                            System.out.println("I:C:I:C: " + c.getClassLoader());
+                        }
+                        System.out.println("F: " + fields[j]);
+                        throw new IllegalStateException("Could not set field " + fields[j].getName() + " on " + m_serviceInstance);
+                    }
+                }
+            }
+            serviceClazz = serviceClazz.getSuperclass();
+        }
+    }
+
+    private void configureServices() {
+        Iterator i = getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (dependency instanceof ServiceDependency) {
+                ServiceDependency sd = (ServiceDependency) dependency;
+                if (sd.isAutoConfig()) {
+                    configureImplementation(sd.getInterface(), sd.getService());
+                }
+                // for required dependencies, we invoke any callbacks here
+                if (sd.isRequired()) {
+                    sd.invokeAdded();
+                }
+            }
+        }
+    }
+    
+    private void unconfigureServices() {
+        Iterator i = getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (dependency instanceof ServiceDependency) {
+                ServiceDependency sd = (ServiceDependency) dependency;
+                // for required dependencies, we invoke any callbacks here
+                if (sd.isRequired()) {
+                    sd.invokeRemoved();
+                }
+            }
+        }
+    }
+
+    public synchronized void addStateListener(ServiceStateListener listener) {
+        m_listeners.add(listener);
+        if (m_state == TRACKING_OPTIONAL) {
+        	listener.starting(this);
+        	listener.started(this);
+        }
+    }
+
+    public synchronized void removeStateListener(ServiceStateListener listener) {
+        m_listeners.remove(listener);
+    }
+
+    synchronized void removeStateListeners() {
+        m_listeners.clear();
+    }
+    
+    public synchronized Service setInterface(String serviceName, Dictionary properties) {
+        ensureNotActive();
+        m_serviceName = serviceName;
+        m_serviceProperties = properties;
+        return this;
+    }
+
+    public synchronized Service setInterface(String[] serviceName, Dictionary properties) {
+        ensureNotActive();
+        m_serviceName = serviceName;
+        m_serviceProperties = properties;
+        return this;
+    }
+    
+    public synchronized Service setCallbacks(String init, String start, String stop, String destroy) {
+        ensureNotActive();
+        m_callbackInit = init;
+        m_callbackStart = start;
+        m_callbackStop = stop;
+        m_callbackDestroy = destroy;
+        return this;
+    }
+    
+    public synchronized Service setImplementation(Object implementation) {
+        ensureNotActive();
+        m_implementation = implementation;
+        return this;
+    }
+    
+    private void ensureNotActive() {
+        if ((m_state == TRACKING_OPTIONAL) || (m_state == WAITING_FOR_REQUIRED)) {
+            throw new IllegalStateException("Cannot modify state while active.");
+        }
+    }
+    boolean isRegistered() {
+        return (m_state == TRACKING_OPTIONAL);
+    }
+    
+    public String toString() {
+        return "ServiceImpl[" + m_serviceName + " " + m_implementation + "]";
+    }
+
+    public synchronized Dictionary getServiceProperties() {
+        if (m_serviceProperties != null) {
+            return (Dictionary) ((Hashtable) m_serviceProperties).clone();
+        }
+        return null;
+    }
+
+    public synchronized void setServiceProperties(Dictionary serviceProperties) {
+        m_serviceProperties = serviceProperties;
+        if (isRegistered() && (m_serviceName != null) && (m_serviceProperties != null)) {
+            m_registration.setProperties(m_serviceProperties);
+        }
+    }
+    
+    static {
+        NULL_REGISTRATION = (ServiceRegistration) Proxy.newProxyInstance(ServiceImpl.class.getClassLoader(), new Class[] {ServiceRegistration.class}, new DefaultNullObject()); 
+    }
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java
new file mode 100644
index 0000000..6e5189d
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java
@@ -0,0 +1,85 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * A wrapper around a service registration that blocks until the
+ * service registration is available.
+ * 
+ * @author Marcel Offermans
+ */
+public class ServiceRegistrationImpl implements ServiceRegistration {
+    private ServiceRegistration m_registration;
+
+    public ServiceRegistrationImpl() {
+        m_registration = null;
+    }
+    
+    public ServiceReference getReference() {
+        ensureRegistration();
+        return m_registration.getReference();
+    }
+
+    public void setProperties(Dictionary dictionary) {
+        ensureRegistration();
+        m_registration.setProperties(dictionary);
+    }
+
+    public void unregister() {
+        ensureRegistration();
+        m_registration.unregister();
+    }
+
+    public boolean equals(Object obj) {
+        ensureRegistration();
+        return m_registration.equals(obj);
+    }
+
+    public int hashCode() {
+        ensureRegistration();
+        return m_registration.hashCode();
+    }
+
+    public String toString() {
+        ensureRegistration();
+        return m_registration.toString();
+    }
+    
+    private synchronized void ensureRegistration() {
+        while (m_registration == null) {
+            try {
+                wait();
+            }
+            catch (InterruptedException ie) {
+                // we were interrupted so hopefully we will now have a
+                // service registration ready; if not we wait again
+            }
+        }
+    }
+
+    void setServiceRegistration(ServiceRegistration registration) {
+        m_registration = registration;
+        synchronized (this) {
+            notifyAll();
+        }
+    }
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java
new file mode 100644
index 0000000..468a266
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java
@@ -0,0 +1,52 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+/**
+ * This interface can be used to register a service state listener. Service
+ * state listeners are called whenever a service state changes. You get notified
+ * when the service is starting, started, stopping and stopped. Each callback
+ * includes a reference to the service in question.
+ * 
+ * @author Marcel Offermans
+ */
+public interface ServiceStateListener {
+    /**
+     * Called when the service is starting.
+     * 
+     * @param service the service
+     */
+    public void starting(Service service);
+    /**
+     * Called when the service is started.
+     * 
+     * @param service the service
+     */
+    public void started(Service service);
+    /**
+     * Called when the service is stopping.
+     * 
+     * @param service the service
+     */
+    public void stopping(Service service);
+    /**
+     * Called when the service is stopped.
+     * 
+     * @param service the service
+     */
+    public void stopped(Service service);
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java
new file mode 100644
index 0000000..1135c80
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java
@@ -0,0 +1,847 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * TODO copied this from the OSGi specification, but it's not clear if that
+ * is allowed or not, for now I modified as little as possible but I might
+ * integrate only the parts I want as soon as this code is finished. Perhaps
+ * it would be better to borrow the Knopflerfish implementation here.
+ * 
+ * @author Marcel Offermans
+ */
+public class ServiceTracker implements ServiceTrackerCustomizer
+{
+    /**
+	 * Bundle context this <tt>ServiceTracker</tt> object is tracking against.
+	 */
+    protected final BundleContext context;
+
+    /**
+	 * Filter specifying search criteria for the services to track.
+	 * @since 1.1
+	 */
+    protected final Filter filter;
+
+    /**
+	 * Tracked services: <tt>ServiceReference</tt> object -> customized Object
+	 * and <tt>ServiceListener</tt> object
+	 */
+    private Tracked tracked;
+
+    /** <tt>ServiceTrackerCustomizer</tt> object for this tracker. */
+    private ServiceTrackerCustomizer customizer;
+
+    /**
+	 * Create a <tt>ServiceTracker</tt> object on the specified <tt>ServiceReference</tt> object.
+	 *
+	 * <p>The service referenced by the specified <tt>ServiceReference</tt> object
+	 * will be tracked by this <tt>ServiceTracker</tt> object.
+	 *
+	 * @param context   <tt>BundleContext</tt> object against which the tracking is done.
+	 * @param reference <tt>ServiceReference</tt> object for the service to be tracked.
+	 * @param customizer The customizer object to call when services are
+	 * added, modified, or removed in this <tt>ServiceTracker</tt> object.
+	 * If customizer is <tt>null</tt>, then this <tt>ServiceTracker</tt> object will be used
+	 * as the <tt>ServiceTrackerCustomizer</tt> object and the <tt>ServiceTracker</tt>
+	 * object will call the <tt>ServiceTrackerCustomizer</tt> methods on itself.
+	 */
+    public ServiceTracker(BundleContext context, ServiceReference reference,
+                          ServiceTrackerCustomizer customizer)
+    {
+        this.context = context;
+        this.customizer = (customizer == null) ? this : customizer;
+
+        try
+        {
+            this.filter = context.createFilter("("+Constants.SERVICE_ID+"="+reference.getProperty(Constants.SERVICE_ID).toString()+")");
+        }
+        catch (InvalidSyntaxException e)
+        {
+            throw new RuntimeException("unexpected InvalidSyntaxException: "+e.getMessage());
+        }
+    }
+
+    /**
+	 * Create a <tt>ServiceTracker</tt> object on the specified class name.
+	 *
+	 * <p>Services registered under the specified class name will be tracked
+	 * by this <tt>ServiceTracker</tt> object.
+	 *
+	 * @param context   <tt>BundleContext</tt> object against which the tracking is done.
+	 * @param clazz     Class name of the services to be tracked.
+	 * @param customizer The customizer object to call when services are
+	 * added, modified, or removed in this <tt>ServiceTracker</tt> object.
+	 * If customizer is <tt>null</tt>, then this <tt>ServiceTracker</tt> object will be used
+	 * as the <tt>ServiceTrackerCustomizer</tt> object and the <tt>ServiceTracker</tt> object
+	 * will call the <tt>ServiceTrackerCustomizer</tt> methods on itself.
+	 */
+    public ServiceTracker(BundleContext context, String clazz,
+                          ServiceTrackerCustomizer customizer)
+    {
+        this.context = context;
+        this.customizer = (customizer == null) ? this : customizer;
+
+        try
+        {
+            this.filter = context.createFilter("("+Constants.OBJECTCLASS+"="+clazz+")");
+        }
+        catch (InvalidSyntaxException e)
+        {
+            throw new RuntimeException("unexpected InvalidSyntaxException: "+e.getMessage());
+        }
+
+        if (clazz == null)
+        {
+            throw new NullPointerException();
+        }
+    }
+
+    /**
+	 * Create a <tt>ServiceTracker</tt> object on the specified <tt>Filter</tt> object.
+	 *
+	 * <p>Services which match the specified <tt>Filter</tt> object will be tracked
+	 * by this <tt>ServiceTracker</tt> object.
+	 *
+	 * @param context   <tt>BundleContext</tt> object against which the tracking is done.
+	 * @param filter    <tt>Filter</tt> object to select the services to be tracked.
+	 * @param customizer The customizer object to call when services are
+	 * added, modified, or removed in this <tt>ServiceTracker</tt> object.
+	 * If customizer is null, then this <tt>ServiceTracker</tt> object will be used
+	 * as the <tt>ServiceTrackerCustomizer</tt> object and the <tt>ServiceTracker</tt>
+	 * object will call the <tt>ServiceTrackerCustomizer</tt> methods on itself.
+	 * @since 1.1
+	 */
+    public ServiceTracker(BundleContext context, Filter filter,
+                          ServiceTrackerCustomizer customizer)
+    {
+        this.context = context;
+        this.filter = filter;
+        this.customizer = (customizer == null) ? this : customizer;
+
+        if ((context == null) || (filter == null))
+        {
+            throw new NullPointerException();
+        }
+    }
+
+    /**
+	 * Open this <tt>ServiceTracker</tt> object and begin tracking services.
+	 *
+	 * <p>Services which match the search criteria specified when
+	 * this <tt>ServiceTracker</tt> object was created are now tracked
+	 * by this <tt>ServiceTracker</tt> object.
+	 *
+	 * @throws java.lang.IllegalStateException if the <tt>BundleContext</tt>
+	 * object with which this <tt>ServiceTracker</tt> object was created is no longer valid.
+	 */
+    public synchronized void open()
+    {
+        if (tracked == null)
+        {
+            tracked = new Tracked(customizer, filter);
+
+            ServiceReference[] references;
+
+            synchronized (tracked)
+            {
+                context.addServiceListener(tracked);
+
+                try
+                {
+                    references = context.getServiceReferences(null, filter.toString());
+                }
+                catch (InvalidSyntaxException e)
+                {
+                    throw new RuntimeException("unexpected InvalidSyntaxException");
+                }
+            }
+
+            /* Call tracked outside of synchronized region */
+            if (references != null)
+            {
+                int size = references.length;
+
+                for (int i=0; i < size; i++)
+                {
+                    ServiceReference reference = references[i];
+
+                    /* if the service is still registered */
+                    if (reference.getBundle() != null)
+                    {
+                        tracked.track(reference);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+	 * Close this <tt>ServiceTracker</tt> object.
+	 *
+	 * <p>This method should be called when this <tt>ServiceTracker</tt> object
+	 * should end the tracking of services.
+	 */
+
+    public synchronized void close()
+    {
+        if (tracked != null)
+        {
+            tracked.close();
+
+            ServiceReference references[] = getServiceReferences();
+
+            Tracked outgoing = tracked;
+            tracked = null;
+
+            try
+            {
+                context.removeServiceListener(outgoing);
+            }
+            catch (IllegalStateException e)
+            {
+                /* In case the context was stopped. */
+            }
+
+            if (references != null)
+            {
+                for (int i = 0; i < references.length; i++)
+                {
+                    outgoing.untrack(references[i]);
+                }
+            }
+        }
+    }
+
+    /**
+	 * Properly close this <tt>ServiceTracker</tt> object when finalized.
+	 * This method calls the <tt>close</tt> method to close this <tt>ServiceTracker</tt> object
+	 * if it has not already been closed.
+	 *
+	 */
+    protected void finalize() throws Throwable
+    {
+        close();
+    }
+
+    /**
+	 * Default implementation of the <tt>ServiceTrackerCustomizer.addingService</tt> method.
+	 *
+	 * <p>This method is only called when this <tt>ServiceTracker</tt> object
+	 * has been constructed with a <tt>null ServiceTrackerCustomizer</tt> argument.
+	 *
+	 * The default implementation returns the result of
+	 * calling <tt>getService</tt>, on the
+	 * <tt>BundleContext</tt> object with which this <tt>ServiceTracker</tt> object was created,
+	 * passing the specified <tt>ServiceReference</tt> object.
+	 * <p>This method can be overridden in a subclass to customize
+	 * the service object to be tracked for the service
+	 * being added. In that case, take care not
+	 * to rely on the default implementation of removedService that will unget the service.
+	 *
+	 * @param reference Reference to service being added to this
+	 * <tt>ServiceTracker</tt> object.
+	 * @return The service object to be tracked for the service
+	 * added to this <tt>ServiceTracker</tt> object.
+	 * @see ServiceTrackerCustomizer
+	 */
+    public Object addingService(ServiceReference reference)
+    {
+        return context.getService(reference);
+    }
+    public void addedService(ServiceReference ref, Object service) {
+        // do nothing
+    }
+    
+    /**
+	 * Default implementation of the <tt>ServiceTrackerCustomizer.modifiedService</tt> method.
+	 *
+	 * <p>This method is only called when this <tt>ServiceTracker</tt> object
+	 * has been constructed with a <tt>null ServiceTrackerCustomizer</tt> argument.
+	 *
+	 * The default implementation does nothing.
+	 *
+	 * @param reference Reference to modified service.
+	 * @param service The service object for the modified service.
+	 * @see ServiceTrackerCustomizer
+	 */
+    public void modifiedService(ServiceReference reference, Object service)
+    {
+    }
+
+    /**
+	 * Default implementation of the <tt>ServiceTrackerCustomizer.removedService</tt> method.
+	 *
+	 * <p>This method is only called when this <tt>ServiceTracker</tt> object
+	 * has been constructed with a <tt>null ServiceTrackerCustomizer</tt> argument.
+	 *
+	 * The default implementation
+	 * calls <tt>ungetService</tt>, on the
+	 * <tt>BundleContext</tt> object with which this <tt>ServiceTracker</tt> object was created,
+	 * passing the specified <tt>ServiceReference</tt> object.
+	 * <p>This method can be overridden in a subclass. If the default
+	 * implementation of <tt>addingService</tt> method was used, this method must unget the service.
+	 *
+	 * @param reference Reference to removed service.
+	 * @param object The service object for the removed service.
+	 * @see ServiceTrackerCustomizer
+	 */
+    public void removedService(ServiceReference reference, Object object)
+    {
+        context.ungetService(reference);
+    }
+
+    /**
+	 * Wait for at least one service to be tracked by this <tt>ServiceTracker</tt> object.
+	 * <p>It is strongly recommended that <tt>waitForService</tt> is not used
+	 * during the calling of the <tt>BundleActivator</tt> methods. <tt>BundleActivator</tt> methods are
+	 * expected to complete in a short period of time.
+	 *
+	 * @param timeout time interval in milliseconds to wait.  If zero,
+	 * the method will wait indefinately.
+	 * @return Returns the result of <tt>getService()</tt>.
+	 * @throws IllegalArgumentException If the value of timeout is
+	 * negative.
+	 */
+    public Object waitForService(long timeout) throws InterruptedException
+    {
+        if (timeout < 0)
+        {
+            throw new IllegalArgumentException("timeout value is negative");
+        }
+
+        Object object = getService();
+
+        while (object == null)
+        {
+            Tracked tracked = this.tracked;     /* use local var since we are not synchronized */
+
+            if (tracked == null)    /* if ServiceTracker is not open */
+            {
+                return null;
+            }
+
+            synchronized (tracked)
+            {
+                if (tracked.size() == 0)
+                {
+                    tracked.wait(timeout);
+                }
+            }
+
+            object = getService();
+
+            if (timeout > 0)
+            {
+                return object;
+            }
+        }
+
+        return object;
+    }
+
+    /**
+	 * Return an array of <tt>ServiceReference</tt> objects for all services
+	 * being tracked by this <tt>ServiceTracker</tt> object.
+	 *
+	 * @return Array of <tt>ServiceReference</tt> objects or <tt>null</tt> if no service
+	 * are being tracked.
+	 */
+    public ServiceReference[] getServiceReferences()
+    {
+        Tracked tracked = this.tracked;     /* use local var since we are not synchronized */
+
+        if (tracked == null)    /* if ServiceTracker is not open */
+        {
+            return null;
+        }
+
+        synchronized (tracked)
+        {
+            int size = tracked.size();
+
+            if (size == 0)
+            {
+                return null;
+            }
+
+            ServiceReference references[] = new ServiceReference[size];
+
+            Enumeration trackedServiceRefs = tracked.keys();
+
+            for (int i = 0; i < size; i++)
+            {
+                references[i] = (ServiceReference)trackedServiceRefs.nextElement();
+            }
+
+            return references;
+        }
+    }
+
+    /**
+	 * Return an array of service objects for all services
+	 * being tracked by this <tt>ServiceTracker</tt> object.
+	 *
+	 * @return Array of service objects or <tt>null</tt> if no service
+	 * are being tracked.
+	 */
+    public Object[] getServices()
+    {
+        Tracked tracked = this.tracked;     /* use local var since we are not synchronized */
+
+        if (tracked == null)    /* if ServiceTracker is not open */
+        {
+            return null;
+        }
+
+        synchronized (tracked)
+        {
+            int size = tracked.size();
+
+            if (size == 0)
+            {
+                return null;
+            }
+
+            Object objects[] = new Object[size];
+
+            Enumeration trackedServices = tracked.elements();
+
+            for (int i = 0; i < size; i++)
+            {
+                objects[i] = trackedServices.nextElement();
+            }
+
+            return objects;
+        }
+    }
+
+    /**
+	 * Returns a <tt>ServiceReference</tt> object for one of the services
+	 * being tracked by this <tt>ServiceTracker</tt> object.
+	 *
+	 * <p>If multiple services are being tracked, the service
+	 * with the highest ranking (as specified in its <tt>service.ranking</tt> property) is
+	 * returned.
+	 *
+	 * <p>If there is a tie in ranking, the service with the lowest
+	 * service ID (as specified in its <tt>service.id</tt> property); that is,
+	 * the service that was registered first is returned.
+	 * <p>This is the same algorithm used by <tt>BundleContext.getServiceReference</tt>.
+	 *
+	 * @return <tt>ServiceReference</tt> object or <tt>null</tt> if no service is being tracked.
+	 * @since 1.1
+	 */
+    public ServiceReference getServiceReference()
+    {
+        ServiceReference[] references = getServiceReferences();
+
+        int length = (references == null) ? 0 : references.length;
+
+        if (length > 0)         /* if a service is being tracked */
+        {
+            int index = 0;
+
+            if (length > 1)     /* if more than one service, select highest ranking */
+            {
+                int rankings[] = new int[length];
+                int count = 0;
+                int maxRanking = Integer.MIN_VALUE;
+
+                for (int i = 0 ; i < length; i++)
+                {
+                    Object property = references[i].getProperty(Constants.SERVICE_RANKING);
+
+                    int ranking = (property instanceof Integer)
+                                    ? ((Integer)property).intValue() : 0;
+
+                    rankings[i] = ranking;
+
+                    if (ranking > maxRanking)
+                    {
+                        index = i;
+                        maxRanking = ranking;
+                        count = 1;
+                    }
+                    else
+                    {
+                        if (ranking == maxRanking)
+                        {
+                            count++;
+                        }
+                    }
+                }
+
+                if (count > 1)  /* if still more than one service, select lowest id */
+                {
+                    long minId = Long.MAX_VALUE;
+
+                    for (int i = 0 ; i < length; i++)
+                    {
+                        if (rankings[i] == maxRanking)
+                        {
+                            long id = ((Long)(references[i].getProperty(Constants.SERVICE_ID))).longValue();
+
+                            if (id < minId)
+                            {
+                                index = i;
+                                minId = id;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return references[index];
+        }
+
+        return null;
+    }
+
+    /**
+	 * Returns the service object for the specified <tt>ServiceReference</tt> object
+	 * if the referenced service is
+	 * being tracked by this <tt>ServiceTracker</tt> object.
+	 *
+	 * @param reference Reference to the desired service.
+	 * @return Service object or <tt>null</tt> if the service referenced by the
+	 * specified <tt>ServiceReference</tt> object is not being tracked.
+	 */
+    public Object getService(ServiceReference reference)
+    {
+        Tracked tracked = this.tracked;     /* use local var since we are not synchronized */
+
+        if (tracked == null)    /* if ServiceTracker is not open */
+        {
+            return null;
+        }
+
+        return tracked.get(reference);
+    }
+
+    /**
+	 * Returns a service object for one of the services
+	 * being tracked by this <tt>ServiceTracker</tt> object.
+	 *
+	 * <p>If any services are being tracked, this method returns the result
+	 * of calling <tt>getService(getServiceReference())</tt>.
+	 *
+	 * @return Service object or <tt>null</tt> if no service is being tracked.
+	 */
+    public Object getService()
+    {
+        ServiceReference reference = getServiceReference();
+
+        if (reference != null)
+        {
+            return getService(reference);
+        }
+
+        return null;
+    }
+
+    /**
+	 * Remove a service from this <tt>ServiceTracker</tt> object.
+	 *
+	 * The specified service will be removed from this
+	 * <tt>ServiceTracker</tt> object.
+	 * If the specified service was being tracked then the
+	 * <tt>ServiceTrackerCustomizer.removedService</tt> method will be
+	 * called for that service.
+	 *
+	 * @param reference Reference to the service to be removed.
+	 */
+    public void remove(ServiceReference reference)
+    {
+        Tracked tracked = this.tracked;     /* use local var since we are not synchronized */
+
+        if (tracked == null)    /* if ServiceTracker is not open */
+        {
+            return;
+        }
+
+        tracked.untrack(reference);
+    }
+
+    /**
+	 * Return the number of services being tracked by this <tt>ServiceTracker</tt> object.
+	 *
+	 * @return Number of services being tracked.
+	 */
+
+    public int size()
+    {
+        Tracked tracked = this.tracked;     /* use local var since we are not synchronized */
+
+        if (tracked == null)    /* if ServiceTracker is not open */
+        {
+            return 0;
+        }
+
+        return tracked.size();
+    }
+
+    /**
+	 * Returns the tracking count for this <tt>ServiceTracker</tt> object.
+	 *
+	 * The tracking count is initialized to 0 when this
+	 * <tt>ServiceTracker</tt> object is opened. Every time a service is
+	 * added or removed from this <tt>ServiceTracker</tt> object
+	 * the tracking count is incremented.
+	 *
+	 * <p>The tracking count can
+	 * be used to determine if this <tt>ServiceTracker</tt> object
+	 * has added or removed a service by comparing a tracking count value
+	 * previously collected with the current tracking count value. If the value
+	 * has not changed, then no service has been added or removed from
+	 * this <tt>ServiceTracker</tt> object
+	 * since the previous tracking count was collected.
+	 *
+	 * @since 1.2
+	 * @return The tracking count for this <tt>ServiceTracker</tt> object
+	 * or -1 if this <tt>ServiceTracker</tt> object is not open.
+	 */
+    public int getTrackingCount()
+    {
+        Tracked tracked = this.tracked;     /* use local var since we are not synchronized */
+
+        if (tracked == null)    /* if ServiceTracker is not open */
+        {
+            return -1;
+        }
+
+        return tracked.getTrackingCount();
+    }
+
+    /**
+	 * Inner class to track the services.
+	 * This class is a hashtable mapping <tt>ServiceReference</tt> object -> customized Object.
+	 * This class also implements the <tt>ServiceListener</tt> interface for the tracker.
+	 * This is not a public class. It is only for use by the implementation
+	 * of the <tt>ServiceTracker</tt> class.
+	 *
+	 */
+    static class Tracked extends Hashtable implements ServiceListener {
+        private ServiceTrackerCustomizer customizer;    /** ServiceTrackerCustomizer object for this tracker. */
+        private Filter filter;      /** The filter used to track */
+        private Vector adding;      /** list of ServiceReferences currently being added */
+        private boolean closed;     /** true if the tracked object is closed */
+        private int trackingCount;  /** modification count */
+
+
+        /**
+		 * Tracked constructor.
+		 *
+		 * @param customizer Customizer object from parent <tt>ServiceTracker</tt> object.
+		 * @param filter <tt>Filter</tt> object from parent <tt>ServiceTracker</tt> object.
+		 */
+        protected Tracked(ServiceTrackerCustomizer customizer, Filter filter)
+        {
+            super();
+            this.customizer = customizer;
+            this.filter = filter;
+            closed = false;
+            trackingCount = 0;
+            adding = new Vector(10, 10);
+        }
+
+        /**
+		 * Called by the parent <tt>ServiceTracker</tt> object when it is closed.
+		 */
+        protected void close()
+        {
+            closed = true;
+        }
+
+        /**
+		 * Called by the parent <tt>ServiceTracker</tt> object to get
+		 * the modification count.
+		 *
+		 * @since 1.2
+		 * @return modification count.
+		 */
+        protected int getTrackingCount()
+        {
+            return trackingCount;
+        }
+
+        /**
+		 * <tt>ServiceListener</tt> method for the <tt>ServiceTracker</tt> class.
+		 * This method must NOT be synchronized to avoid deadlock potential.
+		 *
+		 * @param event <tt>ServiceEvent</tt> object from the framework.
+		 */
+        public void serviceChanged(ServiceEvent event)
+        {
+            /* Check if we had a delayed call (which could happen when we close). */
+            if (closed)
+            {
+                return;
+            }
+
+            ServiceReference reference = event.getServiceReference();
+
+            switch (event.getType())
+            {
+                case ServiceEvent.REGISTERED:
+                case ServiceEvent.MODIFIED:
+                    if (filter.match(reference))
+                    {
+                        track(reference);
+                        /* If the customizer throws an unchecked exception, it is safe to let it propagate */
+                    }
+                    else
+                    {
+                        untrack(reference);
+                        /* If the customizer throws an unchecked exception, it is safe to let it propagate */
+                    }
+
+                    break;
+
+                case ServiceEvent.UNREGISTERING:
+                    untrack(reference);
+                    /* If the customizer throws an unchecked exception, it is safe to let it propagate */
+
+                    break;
+            }
+        }
+
+        /**
+		 * Begin to track the referenced service.
+		 *
+		 * @param reference Reference to a service to be tracked.
+		 */
+        protected void track(ServiceReference reference)
+        {
+            Object object = get(reference);
+
+            if (object != null)     /* we are already tracking the service */
+            {
+                /* Call customizer outside of synchronized region */
+                customizer.modifiedService(reference, object);
+                /* If the customizer throws an unchecked exception, it is safe to let it propagate */
+
+                return;
+            }
+
+            synchronized (this)
+            {
+                if (adding.indexOf(reference, 0) != -1) /* if this service is already
+                                                         * in the process of being added. */
+                {
+                    return;
+                }
+
+                adding.addElement(reference);   /* mark this service is being added */
+            }
+
+            boolean becameUntracked = false;
+
+            /* Call customizer outside of synchronized region */
+            try
+            {
+                object = customizer.addingService(reference);
+                /* If the customizer throws an unchecked exception, it will propagate after the finally */
+            }
+            finally
+            {
+                boolean needToCallback = false;
+                synchronized (this)
+                {
+                    if (adding.removeElement(reference))    /* if the service was not untracked
+                                                             * during the customizer callback */
+                    {
+                        if (object != null)
+                        {
+                            put(reference, object);
+
+                            trackingCount++;            /* increment modification count */
+
+                            notifyAll();
+                            
+                            // Marrs: extra callback added, will be invoked after the synchronized block
+                            needToCallback = true;
+                        }
+                    }
+                    else
+                    {
+                        becameUntracked = true;
+                    }
+                }
+                if (needToCallback) {
+                    customizer.addedService(reference, object);
+                }
+            }
+
+            /* The service became untracked during
+			 * the customizer callback.
+			 */
+            if (becameUntracked)
+            {
+                /* Call customizer outside of synchronized region */
+                customizer.removedService(reference, object);
+                /* If the customizer throws an unchecked exception, it is safe to let it propagate */
+            }
+        }
+
+        /**
+		 * Discontinue tracking the referenced service.
+		 *
+		 * @param reference Reference to the tracked service.
+		 */
+        protected void untrack(ServiceReference reference)
+        {
+            Object object;
+
+            synchronized (this)
+            {
+                if (adding.removeElement(reference)) /* if the service is in the process
+                                                      * of being added */
+                {
+                    return;                          /* in case the service is untracked
+                                                      * while in the process of adding */
+                }
+
+                object = this.remove(reference);     /* must remove from tracker before calling
+                                                      * customizer callback */
+
+                if (object == null)             /* are we actually tracking the service */
+                {
+                    return;
+                }
+
+                trackingCount++;                /* increment modification count */
+            }
+
+            /* Call customizer outside of synchronized region */
+            customizer.removedService(reference, object);
+            /* If the customizer throws an unchecked exception, it is safe to let it propagate */
+        }
+    }
+}
diff --git a/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTrackerCustomizer.java b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTrackerCustomizer.java
new file mode 100644
index 0000000..0a8c778
--- /dev/null
+++ b/org.apache.felix.dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTrackerCustomizer.java
@@ -0,0 +1,33 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.dependencymanager;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * TODO modified version of a normal service tracker customizer, this one has an
+ * extra callback "addedservice" that is invoked after the service has been added
+ * to the tracker (and therefore is accessible through the tracker API)
+ * 
+ * @author Marcel Offermans
+ */
+public interface ServiceTrackerCustomizer {
+    public Object addingService(ServiceReference ref);
+    public void addedService(ServiceReference ref, Object service);
+    public void modifiedService(ServiceReference ref, Object service);
+    public void removedService(ServiceReference ref, Object service);
+}
