diff --git a/dependencymanager/pom.xml b/dependencymanager/pom.xml
index 9e67a3e..b24df4e 100644
--- a/dependencymanager/pom.xml
+++ b/dependencymanager/pom.xml
@@ -58,7 +58,8 @@
             <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
             <Export-Package>org.apache.felix.dependencymanager</Export-Package>
             <Import-Package>!org.apache.felix.dependencymanager,*</Import-Package>
-            <Include-Resource>META-INF/LICENCE=LICENSE,META-INF/NOTICE=NOTICE</Include-Resource>
+            <Include-Resource>META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,org/osgi/util/tracker/=target/clas
+ses/org/osgi/util/tracker</Include-Resource>
           </instructions>
         </configuration>
       </plugin>
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
index 7b81464..43946ff 100644
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
+++ b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
@@ -29,6 +29,8 @@
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
 /**
  * Service dependency that can track an OSGi service.
diff --git a/dependencymanager/src/main/java/org/osgi/util/tracker/ServiceTracker.java b/dependencymanager/src/main/java/org/osgi/util/tracker/ServiceTracker.java
new file mode 100644
index 0000000..ca35468
--- /dev/null
+++ b/dependencymanager/src/main/java/org/osgi/util/tracker/ServiceTracker.java
@@ -0,0 +1,1153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.osgi.util.tracker;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.LinkedList;
+
+import org.osgi.framework.AllServiceListener;
+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;
+
+/**
+ * A modified <code>ServiceTracker</code> class simplifies using services 
+ * from the Framework's service registry. This class is used internally
+ * by the dependency manager. It is based on the OSGi R4.1 sources, which
+ * are made available under the same ASF 2.0 license.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceTracker implements ServiceTrackerCustomizer {
+    /* set this to true to compile in debug messages */
+    static final boolean                DEBUG           = false;
+    /**
+     * Bundle context against which this <code>ServiceTracker</code> object is
+     * tracking.
+     */
+    protected final BundleContext       context;
+    /**
+     * Filter specifying search criteria for the services to track.
+     * 
+     * @since 1.1
+     */
+    protected final Filter              filter;
+    /**
+     * <code>ServiceTrackerCustomizer</code> object for this tracker.
+     */
+    final ServiceTrackerCustomizer      customizer;
+    /**
+     * Filter string for use when adding the ServiceListener. If this field is
+     * set, then certain optimizations can be taken since we don't have a user
+     * supplied filter.
+     */
+    final String                        listenerFilter;
+    /**
+     * Class name to be tracked. If this field is set, then we are tracking by
+     * class name.
+     */
+    private final String                trackClass;
+    /**
+     * Reference to be tracked. If this field is set, then we are tracking a
+     * single ServiceReference.
+     */
+    private final ServiceReference      trackReference;
+    /**
+     * Tracked services: <code>ServiceReference</code> object -> customized
+     * Object and <code>ServiceListener</code> object
+     */
+    private volatile Tracked            tracked;
+    /**
+     * Modification count. This field is initialized to zero by open, set to -1
+     * by close and incremented by modified.
+     * 
+     * This field is volatile since it is accessed by multiple threads.
+     */
+    private volatile int                trackingCount   = -1;
+    /**
+     * Cached ServiceReference for getServiceReference.
+     * 
+     * This field is volatile since it is accessed by multiple threads.
+     */
+    private volatile ServiceReference   cachedReference;
+    /**
+     * Cached service object for getService.
+     * 
+     * This field is volatile since it is accessed by multiple threads.
+     */
+    private volatile Object             cachedService;
+
+    /**
+     * Create a <code>ServiceTracker</code> object on the specified
+     * <code>ServiceReference</code> object.
+     * 
+     * <p>
+     * The service referenced by the specified <code>ServiceReference</code>
+     * object will be tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param context <code>BundleContext</code> object against which the
+     *        tracking is done.
+     * @param reference <code>ServiceReference</code> object for the service
+     *        to be tracked.
+     * @param customizer The customizer object to call when services are added,
+     *        modified, or removed in this <code>ServiceTracker</code> object.
+     *        If customizer is <code>null</code>, then this
+     *        <code>ServiceTracker</code> object will be used as the
+     *        <code>ServiceTrackerCustomizer</code> object and the
+     *        <code>ServiceTracker</code> object will call the
+     *        <code>ServiceTrackerCustomizer</code> methods on itself.
+     */
+    public ServiceTracker(BundleContext context, ServiceReference reference,
+            ServiceTrackerCustomizer customizer) {
+        this.context = context;
+        this.trackReference = reference;
+        this.trackClass = null;
+        this.customizer = (customizer == null) ? this : customizer;
+        this.listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        try {
+            this.filter = context.createFilter(listenerFilter);
+        }
+        catch (InvalidSyntaxException e) { // we could only get this exception
+            // if the ServiceReference was
+            // invalid
+            throw new IllegalArgumentException(
+                    "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Create a <code>ServiceTracker</code> object on the specified class
+     * name.
+     * 
+     * <p>
+     * Services registered under the specified class name will be tracked by
+     * this <code>ServiceTracker</code> object.
+     * 
+     * @param context <code>BundleContext</code> 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 <code>ServiceTracker</code> object.
+     *        If customizer is <code>null</code>, then this
+     *        <code>ServiceTracker</code> object will be used as the
+     *        <code>ServiceTrackerCustomizer</code> object and the
+     *        <code>ServiceTracker</code> object will call the
+     *        <code>ServiceTrackerCustomizer</code> methods on itself.
+     */
+    public ServiceTracker(BundleContext context, String clazz,
+            ServiceTrackerCustomizer customizer) {
+        this.context = context;
+        this.trackReference = null;
+        this.trackClass = clazz;
+        this.customizer = (customizer == null) ? this : customizer;
+        this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        try {
+            this.filter = context.createFilter(listenerFilter);
+        }
+        catch (InvalidSyntaxException e) { // we could only get this exception
+            // if the clazz argument was
+            // malformed
+            throw new IllegalArgumentException(
+                    "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Create a <code>ServiceTracker</code> object on the specified
+     * <code>Filter</code> object.
+     * 
+     * <p>
+     * Services which match the specified <code>Filter</code> object will be
+     * tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param context <code>BundleContext</code> object against which the
+     *        tracking is done.
+     * @param filter <code>Filter</code> object to select the services to be
+     *        tracked.
+     * @param customizer The customizer object to call when services are added,
+     *        modified, or removed in this <code>ServiceTracker</code> object.
+     *        If customizer is null, then this <code>ServiceTracker</code>
+     *        object will be used as the <code>ServiceTrackerCustomizer</code>
+     *        object and the <code>ServiceTracker</code> object will call the
+     *        <code>ServiceTrackerCustomizer</code> methods on itself.
+     * @since 1.1
+     */
+    public ServiceTracker(BundleContext context, Filter filter,
+            ServiceTrackerCustomizer customizer) {
+        this.context = context;
+        this.trackReference = null;
+        this.trackClass = null;
+        this.listenerFilter = null;
+        this.filter = filter;
+        this.customizer = (customizer == null) ? this : customizer;
+        if ((context == null) || (filter == null)) { // we throw a NPE here
+            // to
+            // be consistent with the
+            // other constructors
+            throw new NullPointerException();
+        }
+    }
+
+    /**
+     * Open this <code>ServiceTracker</code> object and begin tracking
+     * services.
+     * 
+     * <p>
+     * This method calls <code>open(false)</code>.
+     * 
+     * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
+     *         object with which this <code>ServiceTracker</code> object was
+     *         created is no longer valid.
+     * @see #open(boolean)
+     */
+    public void open() {
+        open(false);
+    }
+
+    /**
+     * Open this <code>ServiceTracker</code> object and begin tracking
+     * services.
+     * 
+     * <p>
+     * Services which match the search criteria specified when this
+     * <code>ServiceTracker</code> object was created are now tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * @param trackAllServices If <code>true</code>, then this
+     *        <code>ServiceTracker</code> will track all matching services
+     *        regardless of class loader accessibility. If <code>false</code>,
+     *        then this <code>ServiceTracker</code> will only track matching
+     *        services which are class loader accessibile to the bundle whose
+     *        <code>BundleContext</code> is used by this
+     *        <code>ServiceTracker</code>.
+     * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
+     *         object with which this <code>ServiceTracker</code> object was
+     *         created is no longer valid.
+     * @since 1.3
+     */
+    public synchronized void open(boolean trackAllServices) {
+        if (tracked != null) {
+            return;
+        }
+        if (DEBUG) {
+            System.out.println("ServiceTracker.open: " + filter); //$NON-NLS-1$
+        }
+        tracked = trackAllServices ? new AllTracked() : new Tracked();
+        trackingCount = 0;
+        synchronized (tracked) {
+            try {
+                context.addServiceListener(tracked, listenerFilter);
+                ServiceReference[] references;
+                if (listenerFilter == null) { // user supplied filter
+                    references = getInitialReferences(trackAllServices, null,
+                            filter.toString());
+                }
+                else { // constructor supplied filter
+                    if (trackClass == null) {
+                        references = new ServiceReference[] {trackReference};
+                    }
+                    else {
+                        references = getInitialReferences(trackAllServices,
+                                trackClass, null);
+                    }
+                }
+
+                tracked.setInitialServices(references); // set tracked with
+                // the initial
+                // references
+            }
+            catch (InvalidSyntaxException e) {
+                throw new RuntimeException(
+                        "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+            }
+        }
+        /* Call tracked outside of synchronized region */
+        tracked.trackInitialServices(); // process the initial references
+    }
+
+    /**
+     * Returns the list of initial <code>ServiceReference</code> objects that
+     * will be tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param trackAllServices If true, use getAllServiceReferences.
+     * @param trackClass the class name with which the service was registered,
+     *        or null for all services.
+     * @param filterString the filter criteria or null for all services.
+     * @return the list of initial <code>ServiceReference</code> objects.
+     * @throws InvalidSyntaxException if the filter uses an invalid syntax.
+     */
+    private ServiceReference[] getInitialReferences(boolean trackAllServices,
+            String trackClass, String filterString)
+            throws InvalidSyntaxException {
+        if (trackAllServices) {
+            return context.getAllServiceReferences(trackClass, filterString);
+        }
+        else {
+            return context.getServiceReferences(trackClass, filterString);
+        }
+    }
+
+    /**
+     * Close this <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * This method should be called when this <code>ServiceTracker</code>
+     * object should end the tracking of services.
+     */
+    public synchronized void close() {
+        if (tracked == null) {
+            return;
+        }
+        if (DEBUG) {
+            System.out.println("ServiceTracker.close: " + filter); //$NON-NLS-1$
+        }
+        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]);
+            }
+        }
+        trackingCount = -1;
+        if (DEBUG) {
+            if ((cachedReference == null) && (cachedService == null)) {
+                System.out
+                        .println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * Default implementation of the
+     * <code>ServiceTrackerCustomizer.addingService</code> method.
+     * 
+     * <p>
+     * This method is only called when this <code>ServiceTracker</code> object
+     * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+     * argument.
+     * 
+     * The default implementation returns the result of calling
+     * <code>getService</code>, on the <code>BundleContext</code> object
+     * with which this <code>ServiceTracker</code> object was created, passing
+     * the specified <code>ServiceReference</code> 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
+     *        <code>ServiceTracker</code> object.
+     * @return The service object to be tracked for the service added to this
+     *         <code>ServiceTracker</code> object.
+     * @see ServiceTrackerCustomizer
+     */
+    public Object addingService(ServiceReference reference) {
+        return context.getService(reference);
+    }
+
+    /**
+     * Default implementation of the
+     * <code>ServiceTrackerCustomizer.modifiedService</code> method.
+     * 
+     * <p>
+     * This method is only called when this <code>ServiceTracker</code> object
+     * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+     * 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
+     * <code>ServiceTrackerCustomizer.removedService</code> method.
+     * 
+     * <p>
+     * This method is only called when this <code>ServiceTracker</code> object
+     * has been constructed with a <code>null ServiceTrackerCustomizer</code>
+     * argument.
+     * 
+     * The default implementation calls <code>ungetService</code>, on the
+     * <code>BundleContext</code> object with which this
+     * <code>ServiceTracker</code> object was created, passing the specified
+     * <code>ServiceReference</code> object.
+     * <p>
+     * This method can be overridden in a subclass. If the default
+     * implementation of <code>addingService</code> method was used, this
+     * method must unget the service.
+     * 
+     * @param reference Reference to removed service.
+     * @param service The service object for the removed service.
+     * @see ServiceTrackerCustomizer
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        context.ungetService(reference);
+    }
+
+    /**
+     * Wait for at least one service to be tracked by this
+     * <code>ServiceTracker</code> object.
+     * <p>
+     * It is strongly recommended that <code>waitForService</code> is not used
+     * during the calling of the <code>BundleActivator</code> methods.
+     * <code>BundleActivator</code> 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 <code>getService()</code>.
+     * @throws InterruptedException If another thread has interrupted the
+     *         current thread.
+     * @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"); //$NON-NLS-1$
+        }
+        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 <code>ServiceReference</code> objects for all
+     * services being tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @return Array of <code>ServiceReference</code> objects or
+     *         <code>null</code> 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 length = tracked.size();
+            if (length == 0) {
+                return null;
+            }
+            ServiceReference[] references = new ServiceReference[length];
+            Enumeration keys = tracked.keys();
+            for (int i = 0; i < length; i++) {
+                references[i] = (ServiceReference) keys.nextElement();
+            }
+            return references;
+        }
+    }
+
+    /**
+     * Returns a <code>ServiceReference</code> object for one of the services
+     * being tracked by this <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * If multiple services are being tracked, the service with the highest
+     * ranking (as specified in its <code>service.ranking</code> property) is
+     * returned.
+     * 
+     * <p>
+     * If there is a tie in ranking, the service with the lowest service ID (as
+     * specified in its <code>service.id</code> property); that is, the
+     * service that was registered first is returned.
+     * <p>
+     * This is the same algorithm used by
+     * <code>BundleContext.getServiceReference</code>.
+     * 
+     * @return <code>ServiceReference</code> object or <code>null</code> if
+     *         no service is being tracked.
+     * @since 1.1
+     */
+    public ServiceReference getServiceReference() {
+        ServiceReference reference = cachedReference;
+        if (reference != null) {
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$
+            }
+            return reference;
+        }
+        if (DEBUG) {
+            System.out.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$
+        }
+        ServiceReference[] references = getServiceReferences();
+        int length = (references == null) ? 0 : references.length;
+        if (length == 0) /* if no service is being tracked */
+        {
+            return null;
+        }
+        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 cachedReference = references[index];
+    }
+
+    /**
+     * Returns the service object for the specified
+     * <code>ServiceReference</code> object if the referenced service is being
+     * tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param reference Reference to the desired service.
+     * @return Service object or <code>null</code> if the service referenced
+     *         by the specified <code>ServiceReference</code> 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;
+        }
+        synchronized (tracked) {
+            return tracked.get(reference);
+        }
+    }
+
+    /**
+     * Return an array of service objects for all services being tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * @return Array of service objects or <code>null</code> 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) {
+            ServiceReference[] references = getServiceReferences();
+            int length = (references == null) ? 0 : references.length;
+            if (length == 0) {
+                return null;
+            }
+            Object[] objects = new Object[length];
+            for (int i = 0; i < length; i++) {
+                objects[i] = getService(references[i]);
+            }
+            return objects;
+        }
+    }
+
+    /**
+     * Returns a service object for one of the services being tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * If any services are being tracked, this method returns the result of
+     * calling <code>getService(getServiceReference())</code>.
+     * 
+     * @return Service object or <code>null</code> if no service is being
+     *         tracked.
+     */
+    public Object getService() {
+        Object service = cachedService;
+        if (service != null) {
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$
+            }
+            return service;
+        }
+        if (DEBUG) {
+            System.out.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$
+        }
+        ServiceReference reference = getServiceReference();
+        if (reference == null) {
+            return null;
+        }
+        return cachedService = getService(reference);
+    }
+
+    /**
+     * Remove a service from this <code>ServiceTracker</code> object.
+     * 
+     * The specified service will be removed from this
+     * <code>ServiceTracker</code> object. If the specified service was being
+     * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
+     * 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
+     * <code>ServiceTracker</code> 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 <code>ServiceTracker</code> object.
+     * 
+     * The tracking count is initialized to 0 when this
+     * <code>ServiceTracker</code> object is opened. Every time a service is
+     * added, modified or removed from this <code>ServiceTracker</code> object
+     * the tracking count is incremented.
+     * 
+     * <p>
+     * The tracking count can be used to determine if this
+     * <code>ServiceTracker</code> object has added, modified 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, modified or removed from this
+     * <code>ServiceTracker</code> object since the previous tracking count
+     * was collected.
+     * 
+     * @since 1.2
+     * @return The tracking count for this <code>ServiceTracker</code> object
+     *         or -1 if this <code>ServiceTracker</code> object is not open.
+     */
+    public int getTrackingCount() {
+        return trackingCount;
+    }
+
+    /**
+     * Called by the Tracked object whenever the set of tracked services is
+     * modified. Increments the tracking count and clears the cache.
+     * 
+     * @GuardedBy tracked
+     */
+    /*
+     * This method must not be synchronized since it is called by Tracked while
+     * Tracked is synchronized. We don't want synchronization interactions
+     * between the ServiceListener thread and the user thread.
+     */
+    void modified() {
+        trackingCount++; /* increment modification count */
+        cachedReference = null; /* clear cached value */
+        cachedService = null; /* clear cached value */
+        if (DEBUG) {
+            System.out.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Inner class to track services. If a <code>ServiceTracker</code> object
+     * is reused (closed then reopened), then a new Tracked object is used. This
+     * class is a hashtable mapping <code>ServiceReference</code> object ->
+     * customized Object. This class is the <code>ServiceListener</code>
+     * object for the tracker. This class is used to synchronize access to the
+     * tracked services. This is not a public class. It is only for use by the
+     * implementation of the <code>ServiceTracker</code> class.
+     * 
+     * @ThreadSafe
+     */
+    class Tracked extends Hashtable implements ServiceListener {
+        static final long           serialVersionUID    = -7420065199791006079L;
+        /**
+         * List of ServiceReferences in the process of being added. This is used
+         * to deal with nesting of ServiceEvents. Since ServiceEvents are
+         * synchronously delivered, ServiceEvents can be nested. For example,
+         * when processing the adding of a service and the customizer causes the
+         * service to be unregistered, notification to the nested call to
+         * untrack that the service was unregistered can be made to the track
+         * method.
+         * 
+         * Since the ArrayList implementation is not synchronized, all access to
+         * this list must be protected by the same synchronized object for
+         * thread-safety.
+         * 
+         * @GuardedBy this
+         */
+        private final ArrayList     adding;
+
+        /**
+         * true if the tracked object is closed.
+         * 
+         * This field is volatile because it is set by one thread and read by
+         * another.
+         */
+        private volatile boolean    closed;
+
+        /**
+         * Initial list of ServiceReferences for the tracker. This is used to
+         * correctly process the initial services which could become
+         * unregistered before they are tracked. This is necessary since the
+         * initial set of tracked services are not "announced" by ServiceEvents
+         * and therefore the ServiceEvent for unregistration could be delivered
+         * before we track the service.
+         * 
+         * A service must not be in both the initial and adding lists at the
+         * same time. A service must be moved from the initial list to the
+         * adding list "atomically" before we begin tracking it.
+         * 
+         * Since the LinkedList implementation is not synchronized, all access
+         * to this list must be protected by the same synchronized object for
+         * thread-safety.
+         * 
+         * @GuardedBy this
+         */
+        private final LinkedList    initial;
+
+        /**
+         * Tracked constructor.
+         */
+        protected Tracked() {
+            super();
+            closed = false;
+            adding = new ArrayList(6);
+            initial = new LinkedList();
+        }
+
+        /**
+         * Set initial list of services into tracker before ServiceEvents begin
+         * to be received.
+         * 
+         * This method must be called from ServiceTracker.open while
+         * synchronized on this object in the same synchronized block as the
+         * addServiceListener call.
+         * 
+         * @param references The initial list of services to be tracked.
+         * @GuardedBy this
+         */
+        protected void setInitialServices(ServiceReference[] references) {
+            if (references == null) {
+                return;
+            }
+            int size = references.length;
+            for (int i = 0; i < size; i++) {
+                if (DEBUG) {
+                    System.out
+                            .println("ServiceTracker.Tracked.setInitialServices: " + references[i]); //$NON-NLS-1$
+                }
+                initial.add(references[i]);
+            }
+        }
+
+        /**
+         * Track the initial list of services. This is called after
+         * ServiceEvents can begin to be received.
+         * 
+         * This method must be called from ServiceTracker.open while not
+         * synchronized on this object after the addServiceListener call.
+         * 
+         */
+        protected void trackInitialServices() {
+            while (true) {
+                ServiceReference reference;
+                synchronized (this) {
+                    if (initial.size() == 0) {
+                        /*
+                         * if there are no more inital services
+                         */
+                        return; /* we are done */
+                    }
+                    /*
+                     * move the first service from the initial list to the
+                     * adding list within this synchronized block.
+                     */
+                    reference = (ServiceReference) initial.removeFirst();
+                    if (this.get(reference) != null) {
+                        /* if we are already tracking this service */
+                        if (DEBUG) {
+                            System.out
+                                    .println("ServiceTracker.Tracked.trackInitialServices[already tracked]: " + reference); //$NON-NLS-1$
+                        }
+                        continue; /* skip this service */
+                    }
+                    if (adding.contains(reference)) {
+                        /*
+                         * if this service is already in the process of being
+                         * added.
+                         */
+                        if (DEBUG) {
+                            System.out
+                                    .println("ServiceTracker.Tracked.trackInitialServices[already adding]: " + reference); //$NON-NLS-1$
+                        }
+                        continue; /* skip this service */
+                    }
+                    adding.add(reference);
+                }
+                if (DEBUG) {
+                    System.out
+                            .println("ServiceTracker.Tracked.trackInitialServices: " + reference); //$NON-NLS-1$
+                }
+                trackAdding(reference); /*
+                                         * Begin tracking it. We call
+                                         * trackAdding since we have already put
+                                         * the reference in the adding list.
+                                         */
+            }
+        }
+
+        /**
+         * Called by the owning <code>ServiceTracker</code> object when it is
+         * closed.
+         */
+        protected void close() {
+            closed = true;
+        }
+
+        /**
+         * <code>ServiceListener</code> method for the
+         * <code>ServiceTracker</code> class. This method must NOT be
+         * synchronized to avoid deadlock potential.
+         * 
+         * @param event <code>ServiceEvent</code> 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();
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+
+            switch (event.getType()) {
+                case ServiceEvent.REGISTERED :
+                case ServiceEvent.MODIFIED :
+                    if (listenerFilter != null) { // constructor supplied
+                        // filter
+                        track(reference);
+                        /*
+                         * If the customizer throws an unchecked exception, it
+                         * is safe to let it propagate
+                         */
+                    }
+                    else { // user supplied filter
+                        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.
+         */
+        private void track(ServiceReference reference) {
+            Object object;
+            synchronized (this) {
+                object = this.get(reference);
+            }
+            if (object != null) /* we are already tracking the service */
+            {
+                if (DEBUG) {
+                    System.out
+                            .println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$
+                }
+                synchronized (this) {
+                    modified(); /* increment modification count */
+                }
+                /* 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.contains(reference)) { /*
+                                                     * if this service is
+                                                     * already in the process of
+                                                     * being added.
+                                                     */
+                    if (DEBUG) {
+                        System.out
+                                .println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$
+                    }
+                    return;
+                }
+                adding.add(reference); /* mark this service is being added */
+            }
+
+            trackAdding(reference); /*
+                                     * call trackAdding now that we have put the
+                                     * reference in the adding list
+                                     */
+        }
+
+        /**
+         * Common logic to add a service to the tracker used by track and
+         * trackInitialServices. The specified reference must have been placed
+         * in the adding list before calling this method.
+         * 
+         * @param reference Reference to a service to be tracked.
+         */
+        private void trackAdding(ServiceReference reference) {
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.Tracked.trackAdding: " + reference); //$NON-NLS-1$
+            }
+            Object object = null;
+            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.remove(reference)) { /*
+                                                     * if the service was not
+                                                     * untracked during the
+                                                     * customizer callback
+                                                     */
+                        if (object != null) {
+                            this.put(reference, object);
+                            modified(); /* increment modification count */
+                            notifyAll(); /*
+                                             * notify any waiters in
+                                             * waitForService
+                                             */
+                            // 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) {
+                if (DEBUG) {
+                    System.out
+                            .println("ServiceTracker.Tracked.trackAdding[removed]: " + reference); //$NON-NLS-1$
+                }
+                /* 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 (initial.remove(reference)) { /*
+                                                     * if this service is
+                                                     * already in the list of
+                                                     * initial references to
+                                                     * process
+                                                     */
+                    if (DEBUG) {
+                        System.out
+                                .println("ServiceTracker.Tracked.untrack[removed from initial]: " + reference); //$NON-NLS-1$
+                    }
+                    return; /*
+                             * we have removed it from the list and it will not
+                             * be processed
+                             */
+                }
+
+                if (adding.remove(reference)) { /*
+                                                 * if the service is in the
+                                                 * process of being added
+                                                 */
+                    if (DEBUG) {
+                        System.out
+                                .println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$
+                    }
+                    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;
+                }
+                modified(); /* increment modification count */
+            }
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$
+            }
+            /* Call customizer outside of synchronized region */
+            customizer.removedService(reference, object);
+            /*
+             * If the customizer throws an unchecked exception, it is safe to
+             * let it propagate
+             */
+        }
+    }
+
+    /**
+     * Subclass of Tracked which implements the AllServiceListener interface.
+     * This class is used by the ServiceTracker if open is called with true.
+     * 
+     * @since 1.3
+     * @ThreadSafe
+     */
+    class AllTracked extends Tracked implements AllServiceListener {
+        static final long   serialVersionUID    = 4050764875305137716L;
+
+        /**
+         * AllTracked constructor.
+         */
+        protected AllTracked() {
+            super();
+        }
+    }
+
+    public void addedService(ServiceReference ref, Object service) {
+        // do nothing
+    }
+}
diff --git a/dependencymanager/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java b/dependencymanager/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
new file mode 100644
index 0000000..d33cacc
--- /dev/null
+++ b/dependencymanager/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.osgi.util.tracker;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A 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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+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);
+}
