diff --git a/dependencymanager.temp/LICENSE b/dependencymanager.temp/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/dependencymanager.temp/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/dependencymanager.temp/NOTICE b/dependencymanager.temp/NOTICE
new file mode 100644
index 0000000..cfc3633
--- /dev/null
+++ b/dependencymanager.temp/NOTICE
@@ -0,0 +1,26 @@
+Apache Felix Dependency Manager
+Copyright 2009 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2007).
+Licensed under the Apache License 2.0.
+
+
+II. Used Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2007).
+Licensed under the Apache License 2.0.
+
+
+III. License Summary
+- Apache License 2.0
diff --git a/dependencymanager.temp/pom.xml b/dependencymanager.temp/pom.xml
new file mode 100644
index 0000000..9012544
--- /dev/null
+++ b/dependencymanager.temp/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+  <!--
+    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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>1.0.4</version>
+    <relativePath>../pom/pom.xml</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <name>Apache Felix Dependency Manager</name>
+  <version>3.0.0-SNAPSHOT</version>
+  <artifactId>org.apache.felix.dependencymanager</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>1.2.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>1.2.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam</artifactId>
+      <version>1.2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-container-default</artifactId>
+      <version>1.2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-junit</artifactId>
+      <version>1.2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.7</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>1.4.0</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-SymbolicName>org.apache.felix.dependencymanager</Bundle-SymbolicName>
+            <Bundle-Name>Apache Felix Dependency Manager</Bundle-Name>
+            <Bundle-Description>A bundle that provides a run-time
+              service dependency manager.</Bundle-Description>
+            <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
+            <Export-Package>org.apache.felix.dependencymanager</Export-Package>
+            <Import-Package>!org.apache.felix.dependencymanager,*</Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>default-testCompile</id>
+            <configuration>
+              <source>1.5</source>
+              <target>1.5</target>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.ops4j.pax.exam</groupId>
+        <artifactId>maven-paxexam-plugin</artifactId>
+        <version>1.2.0</version>
+        <executions>
+          <execution>
+            <id>generate-config</id>
+            <goals>
+              <goal>generate-depends-file</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <scm>
+    <connection>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.dependencymanager-3.0.0</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.dependencymanager-3.0.0</developerConnection>
+    <url>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.dependencymanager-3.0.0</url>
+  </scm>
+</project>
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
new file mode 100644
index 0000000..f7ac01b
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+
+/**
+ * Configuration dependency that can track the availability of a (valid) configuration.
+ * To use it, specify a PID for the configuration. The dependency is always required,
+ * because if it is not, it does not make sense to use the dependency manager. In that
+ * scenario, simply register your service as a <code>ManagedService(Factory)</code> and
+ * handle everything yourself. Also, only managed services are supported, not factories.
+ * There are a couple of things you need to be aware of when implementing the
+ * <code>updated(Dictionary)</code> method:
+ * <ul>
+ * <li>Make sure it throws a <code>ConfigurationException</code> when you get a
+ * configuration that is invalid. In this case, the dependency will not change:
+ * if it was not available, it will still not be. If it was available, it will
+ * remain available and implicitly assume you keep working with your old
+ * configuration.</li>
+ * <li>This method will be called before all required dependencies are available.
+ * Make sure you do not depend on these to parse your settings.</li>
+ * </ul>
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ConfigurationDependency implements Dependency, ManagedService, ServiceComponentDependency {
+	private BundleContext m_context;
+	private String m_pid;
+	private ServiceRegistration m_registration;
+	private volatile Service m_service;
+	private Dictionary m_settings;
+	private boolean m_propagate;
+	private final Logger m_logger;
+    private String m_callback;
+	
+	public ConfigurationDependency(BundleContext context, Logger logger) {
+		m_context = context;
+		m_logger = logger;
+	}
+	
+	public synchronized boolean isAvailable() {
+		return m_settings != null;
+	}
+
+	/**
+	 * Will always return <code>true</code> as optional configuration dependencies
+	 * do not make sense. You might as well just implement <code>ManagedService</code>
+	 * yourself in those cases.
+	 */
+	public boolean isRequired() {
+		return true;
+	}
+	
+	/**
+	 * Returns <code>true</code> when configuration properties should be propagated
+	 * as service properties.
+	 */
+	public boolean isPropagated() {
+		return m_propagate;
+	}
+	
+	public Dictionary getConfiguration() {
+		return m_settings;
+	}
+	
+	public void start(Service service) {
+		m_service = service;
+		Properties props = new Properties();
+		props.put(Constants.SERVICE_PID, m_pid);
+		m_registration = m_context.registerService(ManagedService.class.getName(), this, props);
+	}
+
+	public void stop(Service service) {
+		m_registration.unregister();
+		m_service = null;
+	}
+
+        public Dependency setCallback(String callback) {
+		m_callback = callback;
+		return this;
+	}
+
+	public void updated(Dictionary settings) throws ConfigurationException {
+		// if non-null settings come in, we have to instantiate the service and
+		// apply these settings
+		((ServiceImpl) m_service).initService();
+		Object service = m_service.getService();
+				
+		Dictionary oldSettings = null; 
+		synchronized (this) {
+			oldSettings = m_settings;
+		}
+		
+		if (oldSettings == null && settings == null) {
+	       // CM has started but our configuration is not still present in the CM database: ignore
+	       return;
+		}
+		
+        if (service != null) {
+          	String callback = (m_callback == null) ? "updated" : m_callback;
+      	  	Method m;
+			try {
+			  	m = service.getClass().getDeclaredMethod(callback, new Class[] { Dictionary.class });
+			  	m.setAccessible(true);
+			  	// if exception is thrown here, what does that mean for the
+			  	// state of this dependency? how smart do we want to be??
+			  	// it's okay like this, if the new settings contain errors, we
+			  	// remain in the state we were, assuming that any error causes
+			  	// the "old" configuration to stay in effect.
+			  	// CM will log any thrown exceptions.
+			  	m.invoke(service, new Object[] { settings });
+			} 
+      	  	catch (InvocationTargetException e) {
+                // The component has thrown an exception during it's callback invocation.
+                if (e.getTargetException() instanceof ConfigurationException) {
+                    // the callback threw an OSGi ConfigurationException: just re-throw it.
+                    throw (ConfigurationException) e.getTargetException();
+                }
+                else {
+                    // wrap the callback exception into a ConfigurationException.
+                    throw new ConfigurationException(null, "Service " + m_service + " with " + this.toString() + " could not be updated", e.getTargetException());
+                }
+            }
+            catch (Throwable t) {
+                // wrap any other exception as a ConfigurationException.
+                throw new ConfigurationException(null, "Service " + m_service + " with " + this.toString() + " could not be updated", t);
+            }
+        }
+        else {
+            m_logger.log(Logger.LOG_ERROR, "Service " + m_service + " with configuration dependency " + this + " could not be instantiated.");
+            return;
+        }
+
+		// If these settings did not cause a configuration exception, we determine if they have 
+		// caused the dependency state to change
+		synchronized (this) {
+			m_settings = settings;
+		}
+
+		if ((oldSettings == null) && (settings != null)) {
+			m_service.dependencyAvailable(this);
+		}
+		if ((oldSettings != null) && (settings == null)) {
+			m_service.dependencyUnavailable(this);
+		}
+		if ((oldSettings != null) && (settings != null)) {
+			m_service.dependencyChanged(this);
+		}
+	}
+
+	/**
+	 * Sets the <code>service.pid</code> of the configuration you
+	 * are depending on.
+	 */
+	public ConfigurationDependency setPid(String pid) {
+		ensureNotActive();
+		m_pid = pid;
+		return this;
+	}
+
+	/**
+	 * Sets propagation of the configuration properties to the service
+	 * properties. Any additional service properties specified directly
+	 * are merged with these.
+	 */
+	public ConfigurationDependency setPropagate(boolean propagate) {
+		ensureNotActive();
+		m_propagate = propagate;
+		return this;
+	}
+	
+	private void ensureNotActive() {
+	  	if (m_service != null) {
+	  	  throw new IllegalStateException("Cannot modify state while active.");
+	  	}
+    }
+    
+    public String toString() {
+    	return "ConfigurationDependency[" + m_pid + "]";
+    }
+
+    public String getName() {
+        return m_pid;
+    }
+
+    public int getState() {
+        return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
+    }
+
+    public String getType() {
+        return "configuration";
+    }
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java
new file mode 100644
index 0000000..79bb240
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public final 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/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Dependency.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Dependency.java
new file mode 100644
index 0000000..64d241a
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Dependency.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+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/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
new file mode 100644
index 0000000..2fa8b13
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class DependencyActivatorBase implements BundleActivator {
+    private BundleContext m_context;
+    private DependencyManager m_manager;
+    private Logger m_logger;
+    
+    /**
+     * 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_logger = new Logger(context);
+        m_manager = new DependencyManager(context, m_logger);
+        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, m_manager, m_logger);
+    }
+    
+    /**
+     * Creates a new service dependency.
+     * 
+     * @return the service dependency
+     */
+    public ServiceDependency createServiceDependency() {
+        return new ServiceDependency(m_context, m_logger);
+    }
+    
+    /**
+     * Creates a new configuration dependency.
+     * 
+     * @return the configuration dependency
+     */
+    public ConfigurationDependency createConfigurationDependency() {
+    	return new ConfigurationDependency(m_context, m_logger);
+    }
+
+    /**
+     * 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/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
new file mode 100644
index 0000000..5c99c7b
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DependencyManager {
+    private final BundleContext m_context;
+    private final Logger m_logger;
+    private List m_services = Collections.synchronizedList(new ArrayList());
+
+    /**
+     * Creates a new dependency manager.
+     * 
+     * @param context the bundle context
+     * @param logger 
+     */
+    public DependencyManager(BundleContext context, Logger logger) {
+        m_context = context;
+        m_logger = logger;
+    }
+    
+    /**
+     * 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, this, m_logger);
+    }
+    
+    /**
+     * Creates a new service dependency.
+     * 
+     * @return the service dependency
+     */
+    public ServiceDependency createServiceDependency() {
+        return new ServiceDependency(m_context, m_logger);
+    }
+    
+    public ConfigurationDependency createConfigurationDependency() {
+        return new ConfigurationDependency(m_context, m_logger);
+    }
+    
+    /**
+     * Returns a list of services.
+     * 
+     * @return a list of services
+     */
+    public List getServices() {
+        return Collections.unmodifiableList(m_services);
+    }
+
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Logger.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Logger.java
new file mode 100644
index 0000000..ab85366
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Logger.java
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This class mimics the standard OSGi <tt>LogService</tt> interface. An
+ * instance of this class is used by the dependency manager for all logging. 
+ * By default this class logs messages to standard out. The log level can be set to
+ * control the amount of logging performed, where a higher number results in
+ * more logging. A log level of zero turns off logging completely.
+ * 
+ * The log levels match those specified in the OSGi Log Service.
+ * This class also tracks log services and will use the highest ranking 
+ * log service, if present, as a back end instead of printing to standard
+ * out. The class uses reflection to invoking the log service's method to 
+ * avoid a dependency on the log interface. This class is in many ways similar
+ * to the one used in the system bundle for that same purpose.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Logger implements ServiceListener {
+    public static final int LOG_ERROR = 1;
+    public static final int LOG_WARNING = 2;
+    public static final int LOG_INFO = 3;
+    public static final int LOG_DEBUG = 4;
+
+    private final BundleContext m_context;
+
+    private final static int LOGGER_OBJECT_IDX = 0;
+    private final static int LOGGER_METHOD_IDX = 1;
+    private ServiceReference m_logRef = null;
+    private Object[] m_logger = null;
+
+    public Logger(BundleContext context) {
+        m_context = context;
+        startListeningForLogService();
+    }
+
+    public final void log(int level, String msg) {
+        _log(null, level, msg, null);
+    }
+
+    public final void log(int level, String msg, Throwable throwable) {
+        _log(null, level, msg, throwable);
+    }
+
+    public final void log(ServiceReference sr, int level, String msg) {
+        _log(sr, level, msg, null);
+    }
+
+    public final void log(ServiceReference sr, int level, String msg, Throwable throwable) {
+        _log(sr, level, msg, throwable);
+    }
+
+    protected void doLog(ServiceReference sr, int level, String msg, Throwable throwable) {
+        String s = (sr == null) ? null : "SvcRef " + sr;
+        s = (s == null) ? msg : s + " " + msg;
+        s = (throwable == null) ? s : s + " (" + throwable + ")";
+        switch (level) {
+            case LOG_DEBUG:
+                System.out.println("DEBUG: " + s);
+                break;
+            case LOG_ERROR:
+                System.out.println("ERROR: " + s);
+                if (throwable != null) {
+                    if ((throwable instanceof BundleException) && (((BundleException) throwable).getNestedException() != null)) {
+                        throwable = ((BundleException) throwable).getNestedException();
+                    }
+                    throwable.printStackTrace();
+                }
+                break;
+            case LOG_INFO:
+                System.out.println("INFO: " + s);
+                break;
+            case LOG_WARNING:
+                System.out.println("WARNING: " + s);
+                break;
+            default:
+                System.out.println("UNKNOWN[" + level + "]: " + s);
+        }
+    }
+
+    private void _log(ServiceReference sr, int level, String msg, Throwable throwable) {
+        // Save our own copy just in case it changes. We could try to do
+        // more conservative locking here, but let's be optimistic.
+        Object[] logger = m_logger;
+        // Use the log service if available.
+        if (logger != null) {
+            _logReflectively(logger, sr, level, msg, throwable);
+        }
+        // Otherwise, default logging action.
+        else {
+            doLog(sr, level, msg, throwable);
+        }
+    }
+
+    private void _logReflectively(Object[] logger, ServiceReference sr, int level, String msg, Throwable throwable) {
+        if (logger != null) {
+            Object[] params = { sr, new Integer(level), msg, throwable };
+            try {
+                ((Method) logger[LOGGER_METHOD_IDX]).invoke(logger[LOGGER_OBJECT_IDX], params);
+            }
+            catch (InvocationTargetException ex) {
+                System.err.println("Logger: " + ex);
+            }
+            catch (IllegalAccessException ex) {
+                System.err.println("Logger: " + ex);
+            }
+        }
+    }
+
+    /**
+     * This method is called when the bundle context is set;
+     * it simply adds a service listener so that the bundle can track
+     * log services to be used as the back end of the logging mechanism. It also
+     * attempts to get an existing log service, if present, but in general
+     * there will never be a log service present since the system bundle is
+     * started before every other bundle.
+     */
+    private synchronized void startListeningForLogService() {
+        // Add a service listener for log services.
+        try {
+            m_context.addServiceListener(this, "(objectClass=org.osgi.service.log.LogService)");
+        }
+        catch (InvalidSyntaxException ex) {
+            // This will never happen since the filter is hard coded.
+        }
+        // Try to get an existing log service.
+        m_logRef = m_context.getServiceReference("org.osgi.service.log.LogService");
+        // Get the service object if available and set it in the logger.
+        if (m_logRef != null) {
+            setLogger(m_context.getService(m_logRef));
+        }
+    }
+
+    /**
+     * This method implements the callback for the ServiceListener interface.
+     * It is public as a byproduct of implementing the interface and should
+     * not be called directly. This method tracks run-time changes to log
+     * service availability. If the log service being used by the framework's
+     * logging mechanism goes away, then this will try to find an alternative.
+     * If a higher ranking log service is registered, then this will switch
+     * to the higher ranking log service.
+     */
+    public final synchronized void serviceChanged(ServiceEvent event) {
+        // If no logger is in use, then grab this one.
+        if ((event.getType() == ServiceEvent.REGISTERED) && (m_logRef == null)) {
+            m_logRef = event.getServiceReference();
+            // Get the service object and set it in the logger.
+            setLogger(m_context.getService(m_logRef));
+        }
+        // If a logger is in use, but this one has a higher ranking, then swap
+        // it for the existing logger.
+        else if ((event.getType() == ServiceEvent.REGISTERED) && (m_logRef != null)) {
+            ServiceReference ref = m_context.getServiceReference("org.osgi.service.log.LogService");
+            if (!ref.equals(m_logRef)) {
+                m_context.ungetService(m_logRef);
+                m_logRef = ref;
+                setLogger(m_context.getService(m_logRef));
+            }
+        }
+        // If the current logger is going away, release it and try to
+        // find another one.
+        else if ((event.getType() == ServiceEvent.UNREGISTERING) && m_logRef.equals(event.getServiceReference())) {
+            // Unget the service object.
+            m_context.ungetService(m_logRef);
+            // Try to get an existing log service.
+            m_logRef = m_context.getServiceReference("org.osgi.service.log.LogService");
+            // Get the service object if available and set it in the logger.
+            if (m_logRef != null) {
+                setLogger(m_context.getService(m_logRef));
+            }
+            else {
+                setLogger(null);
+            }
+        }
+    }
+
+    /**
+     * This method sets the new log service object. It also caches the method to
+     * invoke. The service object and method are stored in array to optimistically
+     * eliminate the need to locking when logging.
+     */
+    private void setLogger(Object logObj) {
+        if (logObj == null) {
+            m_logger = null;
+        }
+        else {
+            Class[] formalParams = { ServiceReference.class, Integer.TYPE, String.class, Throwable.class };
+            try {
+                Method logMethod = logObj.getClass().getMethod("log", formalParams);
+                logMethod.setAccessible(true);
+                m_logger = new Object[] { logObj, logMethod };
+            }
+            catch (NoSuchMethodException ex) {
+                System.err.println("Logger: " + ex);
+                m_logger = null;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/SerialExecutor.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/SerialExecutor.java
new file mode 100644
index 0000000..72063c3
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/SerialExecutor.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+
+/**
+ * Allows you to enqueue tasks from multiple threads and then execute
+ * them on one thread sequentially. It assumes more than one thread will
+ * try to execute the tasks and it will make an effort to pick the first
+ * task that comes along whilst making sure subsequent tasks return
+ * without waiting.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public final class SerialExecutor {
+    private final LinkedList m_workQueue = new LinkedList();
+    private Runnable m_active;
+    
+    /**
+     * Enqueue a new task for later execution. This method is
+     * thread-safe, so multiple threads can contribute tasks.
+     * 
+     * @param runnable the runnable containing the actual task
+     */
+    public synchronized void enqueue(final Runnable runnable) {
+    	m_workQueue.addLast(new Runnable() {
+			public void run() {
+				try {
+					runnable.run();
+				}
+				finally {
+					scheduleNext();
+				}
+			}
+		});
+    }
+    
+    /**
+     * Execute any pending tasks. This method is thread safe,
+     * so multiple threads can try to execute the pending
+     * tasks, but only the first will be used to actually do
+     * so. Other threads will return immediately.
+     */
+    public void execute() {
+    	Runnable active;
+    	synchronized (this) {
+    		active = m_active;
+    	}
+    	if (active == null) {
+    		scheduleNext();
+    	}
+    }
+
+    private void scheduleNext() {
+    	Runnable active;
+    	synchronized (this) {
+    		try {
+    			m_active = (Runnable) m_workQueue.removeFirst();
+    		}
+    		catch (NoSuchElementException e) {
+    			m_active = null;
+    		}
+    		active = m_active;
+    	}
+    	if (active != null) {
+            active.run();
+        }
+    }
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Service.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Service.java
new file mode 100644
index 0000000..dddc800
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/Service.java
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+
+import java.util.Dictionary;
+import java.util.List;
+
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Service interface.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+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> is invoked right after the instance has been
+     * created, and before any dependencies are resolved, and can be used to
+     * initialize the internal state of the instance</li>
+     * <li><code>start()</code> is invoked after the required dependencies
+     * are resolved and injected, and before the service is registered</li>
+     * <li><code>stop()</code> is invoked right after the service is
+     * unregistered</li>
+     * <li><code>destroy()</code> is invoked after all dependencies are
+     * removed</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. If you need even more
+     * fine-grained control, you can register as a service state listener too.
+     * 
+     * @param implementation the implementation
+     * @return this service
+     * @see ServiceStateListener
+     */
+    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();
+    
+    /**
+     * Sets the factory to use to create the implementation. You can specify
+     * both the factory class and method to invoke. The method should return
+     * the implementation, and can use any method to create it. Actually, this
+     * can be used together with <code>setComposition</code> to create a
+     * composition of instances that work together to implement a service. The
+     * factory itself can also be instantiated lazily by not specifying an
+     * instance, but a <code>Class</code>.
+     * 
+     * @param factory the factory instance or class
+     * @param createMethod the name of the create method
+     */
+	public Service setFactory(Object factory, String createMethod);
+	
+	/**
+	 * Sets the factory to use to create the implementation. You specify the
+	 * method to invoke. The method should return the implementation, and can
+	 * use any method to create it. Actually, this can be used together with
+	 * <code>setComposition</code> to create a composition of instances that
+	 * work together to implement a service.
+	 * <p>
+	 * Note that currently, there is no default for the factory, so please use
+	 * <code>setFactory(factory, createMethod)</code> instead.
+	 * 
+	 * @param createMethod the name of the create method
+	 */
+	public Service setFactory(String createMethod);
+	
+	/**
+	 * Sets the instance and method to invoke to get back all instances that
+	 * are part of a composition and need dependencies injected. All of them
+	 * will be searched for any of the dependencies. The method that is
+	 * invoked must return an <code>Object[]</code>.
+	 * 
+	 * @param instance the instance that has the method
+	 * @param getMethod the method to invoke
+	 */
+	public Service setComposition(Object instance, String getMethod);
+	
+	/**
+	 * Sets the method to invoke on the service implementation to get back all
+	 * instances that are part of a composition and need dependencies injected.
+	 * All of them will be searched for any of the dependencies. The method that
+	 * is invoked must return an <code>Object[]</code>.
+	 * 
+	 * @param getMethod the method to invoke
+	 */
+	public Service setComposition(String getMethod);
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java
new file mode 100644
index 0000000..2d70ea7
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+
+/**
+ * Describes a service component. Service components form descriptions of services
+ * that are managed by the dependency manager. They can be used to query their state
+ * for monitoring tools. The dependency manager shell command is an example of
+ * such a tool.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ServiceComponent {
+    /** Names for the states of this component. */
+    public static final String[] STATE_NAMES = { "unregistered", "registered" };
+    /** State constant for an unregistered component. */
+    public static final int STATE_UNREGISTERED = 0;
+    /** State constant for a registered component. */
+    public static final int STATE_REGISTERED = 1;
+    /** Returns a list of dependencies associated with this service component. */
+    public ServiceComponentDependency[] getComponentDependencies();
+    /** Returns the name of this service component. */
+    public String getName();
+    /** Returns the state of this service component. */
+    public int getState();
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java
new file mode 100644
index 0000000..53c13ac
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+
+/**
+ * Describes a service component dependency. They form descriptions of dependencies
+ * that are managed by the dependency manager. They can be used to query their state
+ * for monitoring tools. The dependency manager shell command is an example of
+ * such a tool.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ServiceComponentDependency {
+    /** Names for the states of this dependency. */
+    public static final String[] STATE_NAMES = { 
+        "optional unavailable", 
+        "optional available", 
+        "required unavailable", 
+        "required available" 
+        };
+    /** State constant for an unavailable, optional dependency. */
+    public static final int STATE_UNAVAILABLE_OPTIONAL = 0;
+    /** State constant for an available, optional dependency. */
+    public static final int STATE_AVAILABLE_OPTIONAL = 1;
+    /** State constant for an unavailable, required dependency. */
+    public static final int STATE_UNAVAILABLE_REQUIRED = 2;
+    /** State constant for an available, required dependency. */
+    public static final int STATE_AVAILABLE_REQUIRED = 3;
+    /** Returns the name of this dependency. */
+    public String getName();
+    /** Returns the name of the type of this dependency. */
+    public String getType();
+    /** Returns the state of this dependency. */
+    public int getState();
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
new file mode 100644
index 0000000..195fa12
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
@@ -0,0 +1,720 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Service dependency that can track an OSGi service.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceDependency implements Dependency, ServiceTrackerCustomizer, ServiceComponentDependency {
+    private boolean m_isRequired;
+    private Service m_service;
+    private volatile ServiceTracker m_tracker;
+    private BundleContext m_context;
+    private boolean m_isAvailable;
+    private volatile Class m_trackedServiceName;
+    private Object m_nullObject;
+    private volatile String m_trackedServiceFilter;
+    private volatile String m_trackedServiceFilterUnmodified;
+    private volatile ServiceReference m_trackedServiceReference;
+    private volatile 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;
+    private final Logger m_logger;
+    private String m_autoConfigInstance;
+    private boolean m_autoConfigInvoked;
+    private Object m_defaultImplementation;
+    private Object m_defaultImplementationInstance;
+    
+    private static final Comparator COMPARATOR = new Comparator() {
+        public int getRank(ServiceReference ref) {
+            Object ranking = ref.getProperty(Constants.SERVICE_RANKING);
+            if (ranking != null && (ranking instanceof Integer)) {
+                return ((Integer) ranking).intValue();
+            }
+            return 0;
+        }
+
+        public int compare(Object a, Object b) {
+            ServiceReference ra = (ServiceReference) a, rb = (ServiceReference) b;
+            int ranka = getRank(ra);
+            int rankb = getRank(rb);
+            if (ranka < rankb) {
+                return -1;
+            }
+            else if (ranka > rankb) {
+                return 1;
+            }
+            return 0;
+        }
+    };
+    
+    /**
+     * Entry to wrap service properties behind a Map.
+     */
+    private final static class ServicePropertiesMapEntry implements Map.Entry {
+        private final String m_key;
+        private Object m_value;
+
+        public ServicePropertiesMapEntry(String key, Object value) {
+            m_key = key;
+            m_value = value;
+        }
+
+        public Object getKey() {
+            return m_key;
+        }
+
+        public Object getValue() {
+            return m_value;
+        }
+
+        public String toString() {
+            return m_key + "=" + m_value;
+        }
+
+        public Object setValue(Object value) {
+            Object oldValue = m_value;
+            m_value = value;
+            return oldValue;
+        }
+
+        public boolean equals(Object o) {
+            if (!(o instanceof Map.Entry)) {
+                return false;
+            }
+            Map.Entry e = (Map.Entry) o;
+            return eq(m_key, e.getKey()) && eq(m_value, e.getValue());
+        }
+
+        public int hashCode() {
+            return ((m_key == null) ? 0 : m_key.hashCode()) ^ ((m_value == null) ? 0 : m_value.hashCode());
+        }
+
+        private static final boolean eq(Object o1, Object o2) {
+            return (o1 == null ? o2 == null : o1.equals(o2));
+        }
+    }
+
+    /**
+     * Wraps service properties behind a Map.
+     */
+    private final static class ServicePropertiesMap extends AbstractMap {
+        private final ServiceReference m_ref;
+
+        public ServicePropertiesMap(ServiceReference ref) {
+            m_ref = ref;
+        }
+
+        public Object get(Object key) {
+            return m_ref.getProperty(key.toString());
+        }
+
+        public int size() {
+            return m_ref.getPropertyKeys().length;
+        }
+
+        public Set entrySet() {
+            Set set = new HashSet();
+            String[] keys = m_ref.getPropertyKeys();
+            for (int i = 0; i < keys.length; i++) {
+                set.add(new ServicePropertiesMapEntry(keys[i], m_ref.getProperty(keys[i])));
+            }
+            return set;
+        }
+    }
+        
+    /**
+     * Creates a new service dependency.
+     * 
+     * @param context the bundle context
+     * @param logger the logger
+     */
+    public ServiceDependency(BundleContext context, Logger logger) {
+        m_context = context;
+        m_logger = logger;
+        m_autoConfig = true;
+    }
+
+    public synchronized boolean isRequired() {
+        return m_isRequired;
+    }
+
+    public synchronized boolean isAvailable() {
+        return m_isAvailable;
+    }
+    
+    public synchronized boolean isAutoConfig() {
+        return m_autoConfig;
+    }
+
+    public synchronized Object getService() {
+        Object service = null;
+        if (m_isStarted) {
+            service = m_tracker.getService();
+        }
+        if (service == null) {
+            service = getDefaultImplementation();
+            if (service == null) {
+                service = getNullObject();
+            }
+        }
+        return service;
+    }
+
+    public Object lookupService() {
+        Object service = null;
+        if (m_isStarted) {
+            service = m_tracker.getService();
+        }
+        else {
+            ServiceReference[] refs = null;
+            ServiceReference ref = null;
+            if (m_trackedServiceName != null) {
+                if (m_trackedServiceFilter != null) {
+                    try {
+                        refs = m_context.getServiceReferences(m_trackedServiceName.getName(), m_trackedServiceFilter);
+                        if (refs != null) {
+                            Arrays.sort(refs, COMPARATOR);
+                            ref = refs[0];
+                        }
+                    }
+                    catch (InvalidSyntaxException e) {
+                        throw new IllegalStateException("Invalid filter definition for dependency.");
+                    }
+                }
+                else if (m_trackedServiceReference != null) {
+                    ref = m_trackedServiceReference;
+                }
+                else {
+                    ref = m_context.getServiceReference(m_trackedServiceName.getName());
+                }
+                if (ref != null) {
+                    service = m_context.getService(ref);
+                }
+            }
+            else {
+                throw new IllegalStateException("Could not lookup dependency, no service name specified.");
+            }
+        }
+        if (service == null) {
+            service = getDefaultImplementation();
+            if (service == null) {
+                service = getNullObject();
+            }
+        }
+        return service;
+    }
+
+    private Object getNullObject() {
+        if (m_nullObject == null) {
+            Class trackedServiceName;
+            synchronized (this) {
+                trackedServiceName = m_trackedServiceName;
+            }
+            try {
+                m_nullObject = Proxy.newProxyInstance(trackedServiceName.getClassLoader(), new Class[] {trackedServiceName}, new DefaultNullObject()); 
+            }
+            catch (Exception e) {
+                m_logger.log(Logger.LOG_ERROR, "Could not create null object for " + trackedServiceName + ".", e);
+            }
+        }
+        return m_nullObject;
+    }
+    
+    private Object getDefaultImplementation() {
+        if (m_defaultImplementation != null) {
+            if (m_defaultImplementation instanceof Class) {
+                try {
+                    m_defaultImplementationInstance = ((Class) m_defaultImplementation).newInstance();
+                }
+                catch (Exception e) {
+                    m_logger.log(Logger.LOG_ERROR, "Could not create default implementation instance of class " + m_defaultImplementation + ".", e);
+                }
+            }
+            else {
+                m_defaultImplementationInstance = m_defaultImplementation;
+            }
+        }
+        return m_defaultImplementationInstance;
+    }
+    
+    public synchronized Class getInterface() {
+        return m_trackedServiceName;
+    }
+
+    public void start(Service service) {
+        synchronized (this) {
+            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 void stop(Service service) {
+        synchronized (this) {
+            if (!m_isStarted) {
+                throw new IllegalStateException("Service dependency was not started.");
+            }
+            m_isStarted = false;
+        }
+        m_tracker.close();
+        m_tracker = null;
+    }
+
+    public Object addingService(ServiceReference ref) {
+        Object service = m_context.getService(ref);
+        // first check to make sure the service is actually an instance of our service
+        if (!m_trackedServiceName.isInstance(service)) {
+            return null;
+        }
+            
+        // 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);
+            // try to invoke callback, if specified, but only for optional dependencies
+            // because callbacks for required dependencies are handled differently
+            if (!isRequired()) {
+                invokeAdded(ref, service);
+            }
+        }
+        else {
+            m_service.dependencyChanged(this);
+            invokeAdded(ref, service);
+        }
+    }
+
+    public void invokeAdded() {
+        invokeAdded(m_reference, m_serviceInstance);
+    }
+    
+    public void invokeAdded(ServiceReference reference, Object serviceInstance) {
+        Object[] callbackInstances = getCallbackInstances();
+        if ((callbackInstances != null) && (m_callbackAdded != null)) {
+            invokeCallbackMethod(callbackInstances, m_callbackAdded, reference, serviceInstance);
+        }
+    }
+
+    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[] callbackInstances = getCallbackInstances();
+        if ((callbackInstances != null) && (m_callbackChanged != null)) {
+            invokeCallbackMethod(callbackInstances, m_callbackChanged, reference, serviceInstance);
+        }
+    }
+
+    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);
+            }
+        }
+        else {
+            m_service.dependencyChanged(this);
+            invokeRemoved(ref, service);
+        }
+        
+        // unget what we got in addingService (see ServiceTracker 701.4.1)
+        m_context.ungetService(ref);
+    }
+
+    public void invokeRemoved() {
+        invokeRemoved(m_reference, m_serviceInstance);
+    }
+    
+    public void invokeRemoved(ServiceReference reference, Object serviceInstance) {
+        Object[] callbackInstances = getCallbackInstances();
+        if ((callbackInstances != null) && (m_callbackRemoved != null)) {
+            invokeCallbackMethod(callbackInstances, m_callbackRemoved, reference, serviceInstance);
+        }
+    }
+    
+    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 synchronized Object[] getCallbackInstances() {
+        return m_callbackInstance != null ? new Object[] { m_callbackInstance } : ((ServiceImpl) m_service).getCompositionInstances();
+    }
+
+    private void invokeCallbackMethod(Object[] instances, String methodName, ServiceReference reference, Object service) {
+        for (int i = 0; i < instances.length; i++) {
+            try {
+                invokeCallbackMethod(instances[i], methodName, reference, service);
+            }
+            catch (NoSuchMethodException e) {
+                m_logger.log(Logger.LOG_DEBUG, "Method '" + methodName + "' does not exist on " + instances[i] + ". Callback skipped.");
+            }
+        }
+    }
+
+    private void invokeCallbackMethod(Object instance, String methodName, ServiceReference reference, Object service) throws NoSuchMethodException {
+        Class currentClazz = instance.getClass();
+        boolean done = false;
+        while (!done && currentClazz != null) {
+            Class trackedServiceName;
+            synchronized (this) {
+                trackedServiceName = m_trackedServiceName;
+            }
+            done = invokeMethod(instance, currentClazz, methodName,
+                new Class[][] {{ServiceReference.class, trackedServiceName}, {ServiceReference.class, Object.class}, {ServiceReference.class}, {trackedServiceName}, {Object.class}, {}, {Map.class, trackedServiceName}},
+                new Object[][] {{reference, service}, {reference, service}, {reference}, {service}, {service}, {}, {new ServicePropertiesMap(reference), service}},
+                false);
+            if (!done) {
+                currentClazz = currentClazz.getSuperclass();
+            }
+        }
+        if (!done && currentClazz == null) {
+            throw new NoSuchMethodException(methodName);
+        }
+    }
+
+    private boolean invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) {
+        Method m = null;
+        for (int i = 0; i < signatures.length; i++) {
+            Class[] signature = signatures[i];
+            try {
+                m = clazz.getDeclaredMethod(name, signature);
+                if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
+                    m.setAccessible(true);
+                    try {
+                        m.invoke(object, parameters[i]);
+                    }
+                    catch (InvocationTargetException e) {
+                        m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + m + ".", e);
+                    }
+                    // we did find and invoke the method, so we return true
+                    return true;
+                }
+            }
+            catch (NoSuchMethodException e) {
+                // ignore this and keep looking
+            }
+            catch (Exception e) {
+                // could not even try to invoke the method
+                m_logger.log(Logger.LOG_ERROR, "Exception while trying to invoke method " + m + ".", e);
+            }
+        }
+        return false;
+    }
+    
+    // ----- 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. To make sure of this, the filter is actually extended internally to
+     * filter on the correct 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;
+        if (serviceFilter != null) {
+            m_trackedServiceFilterUnmodified = serviceFilter;
+            m_trackedServiceFilter ="(&(" + Constants.OBJECTCLASS + "=" + serviceName.getName() + ")" + serviceFilter + ")";
+        }
+        else {
+            m_trackedServiceFilterUnmodified = null;
+            m_trackedServiceFilter = null;
+        }
+        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_trackedServiceFilterUnmodified = null;
+        m_trackedServiceFilter = null;
+        return this;
+    }
+    
+    /**
+     * Sets the default implementation for this service dependency. You can use this to supply
+     * your own implementation that will be used instead of a Null Object when the dependency is
+     * not available. This is also convenient if the service dependency is not an interface
+     * (which would cause the Null Object creation to fail) but a class.
+     * 
+     * @param implementation the instance to use or the class to instantiate if you want to lazily
+     *     instantiate this implementation
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setDefaultImplementation(Object implementation) {
+        ensureNotActive();
+        m_defaultImplementation = implementation;
+        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;
+        m_autoConfigInvoked = true;
+        return this;
+    }
+    
+    /**
+     * Sets auto configuration for this service. Auto configuration allows the
+     * dependency to fill in the attribute in the service implementation that
+     * has the same type and instance name.
+     * 
+     * @param instanceName the name of attribute to auto config
+     * @return this service dependency
+     */
+    public synchronized ServiceDependency setAutoConfig(String instanceName) {
+        ensureNotActive();
+        m_autoConfig = (instanceName != null);
+        m_autoConfigInstance = instanceName;
+        m_autoConfigInvoked = true;
+        return this;
+    }
+    
+    /**
+     * Sets the callbacks for this service. These callbacks can be used as hooks whenever a
+     * dependency is added or removed. When you specify callbacks, the auto configuration 
+     * feature is automatically turned off, because we're assuming you don't need it in this 
+     * case.
+     * 
+     * @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);
+    }
+
+    /**
+     * Sets the callbacks for this service. These callbacks can be used as hooks whenever a
+     * dependency is added, changed or removed. When you specify callbacks, the auto 
+     * configuration feature is automatically turned off, because we're assuming you don't 
+     * need it in this case.
+     * 
+     * @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(String added, String changed, String removed) {
+        return setCallbacks(null, added, changed, 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. When you
+     * specify callbacks, the auto configuration feature is automatically turned off, because
+     * we're assuming you don't need it in this case.
+     * 
+     * @param instance the instance to call the callbacks on
+     * @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(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, changed or removed. They are called on the instance you provide. When you
+     * specify callbacks, the auto configuration feature is automatically turned off, because
+     * we're assuming you don't need it in this case.
+     * 
+     * @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();
+        // if at least one valid callback is specified, we turn off auto configuration, unless
+        // someone already explicitly invoked autoConfig
+        if ((added != null || removed != null || changed != null) && ! m_autoConfigInvoked) {
+            setAutoConfig(false);
+        }
+        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 synchronized String toString() {
+        return "ServiceDependency[" + m_trackedServiceName + " " + m_trackedServiceFilterUnmodified + "]";
+    }
+
+    public String getAutoConfigName() {
+        return m_autoConfigInstance;
+    }
+
+    public String getName() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(m_trackedServiceName.getName());
+        if (m_trackedServiceFilterUnmodified != null) {
+            sb.append(m_trackedServiceFilterUnmodified);
+        }
+        return sb.toString();
+    }
+
+    public int getState() {
+        return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
+    }
+
+    public String getType() {
+        return "service";
+    }
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
new file mode 100644
index 0000000..f5f4c90
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
@@ -0,0 +1,921 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Service implementation.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceImpl implements Service, ServiceComponent {
+    private static final Class[] VOID = new Class[] {};
+	private static final ServiceRegistration NULL_REGISTRATION;
+    private static final ServiceStateListener[] SERVICE_STATE_LISTENER_TYPE = new ServiceStateListener[] {};
+
+    private final BundleContext m_context;
+    private final DependencyManager m_manager;
+
+    // configuration (static)
+    private String m_callbackInit;
+    private String m_callbackStart;
+    private String m_callbackStop;
+    private String m_callbackDestroy;
+    private Object m_serviceName;
+    private Object m_implementation;
+
+    // configuration (dynamic, but does not affect state)
+    private Dictionary m_serviceProperties;
+
+    // configuration (dynamic, and affects state)
+    private ArrayList m_dependencies = new ArrayList();
+
+    // runtime state (calculated from dependencies)
+    private State m_state;
+
+    // runtime state (changes because of state changes)
+    private Object m_serviceInstance;
+    private ServiceRegistration m_registration;
+
+    // service state listeners
+    private final List m_stateListeners = new ArrayList();
+
+    // work queue
+    private final SerialExecutor m_executor = new SerialExecutor();
+
+    // instance factory
+	private Object m_instanceFactory;
+	private String m_instanceFactoryCreateMethod;
+
+	// composition manager
+	private Object m_compositionManager;
+	private String m_compositionManagerGetMethod;
+	private Object m_compositionManagerInstance;
+	
+	// internal logging
+    private final Logger m_logger;
+    private ServiceRegistration m_serviceRegistration;
+    private Map m_autoConfig = new HashMap();
+    private Map m_autoConfigInstance = new HashMap();
+
+    public ServiceImpl(BundleContext context, DependencyManager manager, Logger logger) {
+    	m_logger = logger;
+        m_state = new State((List) m_dependencies.clone(), false);
+        m_context = context;
+        m_manager = manager;
+        m_callbackInit = "init";
+        m_callbackStart = "start";
+        m_callbackStop = "stop";
+        m_callbackDestroy = "destroy";
+        m_implementation = null;
+        m_autoConfig.put(BundleContext.class, Boolean.TRUE);
+        m_autoConfig.put(ServiceRegistration.class, Boolean.TRUE);
+        m_autoConfig.put(DependencyManager.class, Boolean.TRUE);
+    }
+
+    private void calculateStateChanges(final State oldState, final State newState) {
+    	if (oldState.isWaitingForRequired() && newState.isTrackingOptional()) {
+        	m_executor.enqueue(new Runnable() {
+				public void run() {
+					activateService(newState);
+				}});
+    	}
+    	if (oldState.isTrackingOptional() && newState.isWaitingForRequired()) {
+    		m_executor.enqueue(new Runnable() {
+				public void run() {
+					deactivateService(oldState);
+				}});
+    	}
+    	if (oldState.isInactive() && (newState.isTrackingOptional())) {
+    		m_executor.enqueue(new Runnable() {
+				public void run() {
+					activateService(newState);
+				}});
+    	}
+    	if (oldState.isInactive() && (newState.isWaitingForRequired())) {
+    		m_executor.enqueue(new Runnable() {
+				public void run() {
+					startTrackingRequired(newState);
+				}});
+    	}
+    	if ((oldState.isWaitingForRequired()) && newState.isInactive()) {
+    		m_executor.enqueue(new Runnable() {
+				public void run() {
+					stopTrackingRequired(oldState);
+				}});
+    	}
+    	if ((oldState.isTrackingOptional()) && newState.isInactive()) {
+    		m_executor.enqueue(new Runnable() {
+				public void run() {
+					deactivateService(oldState);
+					stopTrackingRequired(oldState);
+				}});
+    	}
+    	m_executor.execute();
+    }
+
+    public Service add(final Dependency dependency) {
+    	State oldState, newState;
+        synchronized (m_dependencies) {
+        	oldState = m_state;
+            m_dependencies.add(dependency);
+        }
+        if (oldState.isTrackingOptional() || (oldState.isWaitingForRequired() && dependency.isRequired())) {
+        	dependency.start(this);
+        }
+        synchronized (m_dependencies) {
+            newState = new State((List) m_dependencies.clone(), !oldState.isInactive());
+            m_state = newState;
+            calculateStateChanges(oldState, newState);
+        }
+        return this;
+    }
+
+    public Service remove(Dependency dependency) {
+    	State oldState, newState;
+        synchronized (m_dependencies) {
+        	oldState = m_state;
+            m_dependencies.remove(dependency);
+        }
+        if (oldState.isTrackingOptional() || (oldState.isWaitingForRequired() && dependency.isRequired())) {
+        	dependency.stop(this);
+        }
+        synchronized (m_dependencies) {
+            newState = new State((List) m_dependencies.clone(), !oldState.isInactive());
+            m_state = newState;
+        }
+        calculateStateChanges(oldState, newState);
+        return this;
+    }
+
+    public List getDependencies() {
+        synchronized (m_dependencies) {
+            return (List) m_dependencies.clone();
+        }
+    }
+
+    public ServiceRegistration getServiceRegistration() {
+        return m_registration;
+    }
+
+    public Object getService() {
+        return m_serviceInstance;
+    }
+
+    public void dependencyAvailable(final Dependency dependency) {
+    	State oldState, newState;
+        synchronized (m_dependencies) {
+        	oldState = m_state;
+            newState = new State((List) m_dependencies.clone(), !oldState.isInactive());
+            m_state = newState;
+        }
+        calculateStateChanges(oldState, newState);
+        if (newState.isTrackingOptional()) {
+        	m_executor.enqueue(new Runnable() {
+        		public void run() {
+        			updateInstance(dependency);
+        		}
+        	});
+        	m_executor.execute();
+        }
+    }
+
+    public void dependencyChanged(final Dependency dependency) {
+    	State state;
+        synchronized (m_dependencies) {
+        	state = m_state;
+        }
+        if (state.isTrackingOptional()) {
+        	m_executor.enqueue(new Runnable() {
+        		public void run() {
+        			updateInstance(dependency);
+        		}
+        	});
+        	m_executor.execute();
+        }
+    }
+
+    public void dependencyUnavailable(final Dependency dependency) {
+    	State oldState, newState;
+        synchronized (m_dependencies) {
+        	oldState = m_state;
+            newState = new State((List) m_dependencies.clone(), !oldState.isInactive());
+            m_state = newState;
+        }
+        calculateStateChanges(oldState, newState);
+        if (newState.isTrackingOptional()) {
+        	m_executor.enqueue(new Runnable() {
+        		public void run() {
+        			updateInstance(dependency);
+        		}
+        	});
+        	m_executor.execute();
+        }
+    }
+
+    public synchronized void start() {
+        m_serviceRegistration = m_context.registerService(ServiceComponent.class.getName(), this, null);
+    	State oldState, newState;
+        synchronized (m_dependencies) {
+        	oldState = m_state;
+            newState = new State((List) m_dependencies.clone(), true);
+            m_state = newState;
+        }
+        calculateStateChanges(oldState, newState);
+    }
+
+    public synchronized void stop() {
+    	State oldState, newState;
+        synchronized (m_dependencies) {
+        	oldState = m_state;
+            newState = new State((List) m_dependencies.clone(), false);
+            m_state = newState;
+        }
+        calculateStateChanges(oldState, newState);
+        m_serviceRegistration.unregister();
+    }
+
+    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;
+	}
+
+	public synchronized Service setFactory(Object factory, String createMethod) {
+	    ensureNotActive();
+		m_instanceFactory = factory;
+		m_instanceFactoryCreateMethod = createMethod;
+		return this;
+	}
+
+	public synchronized Service setFactory(String createMethod) {
+		return setFactory(null, createMethod);
+	}
+
+	public synchronized Service setComposition(Object instance, String getMethod) {
+	    ensureNotActive();
+		m_compositionManager = instance;
+		m_compositionManagerGetMethod = getMethod;
+		return this;
+	}
+
+	public synchronized Service setComposition(String getMethod) {
+		return setComposition(null, getMethod);
+	}
+
+	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_registration.setProperties(calculateServiceProperties());
+	    }
+	}
+
+	// service state listener methods
+	public void addStateListener(ServiceStateListener listener) {
+    	synchronized (m_stateListeners) {
+		    m_stateListeners.add(listener);
+    	}
+    	// when we register as a listener and the service is already started
+    	// make sure we invoke the right callbacks so the listener knows
+    	State state;
+    	synchronized (m_dependencies) {
+    		state = m_state;
+    	}
+    	if (state.isTrackingOptional()) {
+    		listener.starting(this);
+    		listener.started(this);
+    	}
+	}
+
+	public void removeStateListener(ServiceStateListener listener) {
+    	synchronized (m_stateListeners) {
+    		m_stateListeners.remove(listener);
+    	}
+	}
+
+	void removeStateListeners() {
+    	synchronized (m_stateListeners) {
+    		m_stateListeners.clear();
+    	}
+	}
+
+	private void stateListenersStarting() {
+		ServiceStateListener[] list = getListeners();
+		for (int i = 0; i < list.length; i++) {
+		    try {
+		        list[i].starting(this);
+		    }
+		    catch (Throwable t) {
+		        m_logger.log(Logger.LOG_ERROR, "Error invoking listener starting method.", t);
+		    }
+		}
+	}
+
+	private void stateListenersStarted() {
+        ServiceStateListener[] list = getListeners();
+        for (int i = 0; i < list.length; i++) {
+            try {
+                list[i].started(this);
+            }
+            catch (Throwable t) {
+                m_logger.log(Logger.LOG_ERROR, "Error invoking listener started method.", t);
+            }
+        }
+    }
+
+    private void stateListenersStopping() {
+        ServiceStateListener[] list = getListeners();
+        for (int i = 0; i < list.length; i++) {
+            try {
+                list[i].stopping(this);
+            }
+            catch (Throwable t) {
+                m_logger.log(Logger.LOG_ERROR, "Error invoking listener stopping method.", t);
+            }
+        }
+    }
+
+    private void stateListenersStopped() {
+        ServiceStateListener[] list = getListeners();
+        for (int i = 0; i < list.length; i++) {
+            try {
+                list[i].stopped(this);
+            }
+            catch (Throwable t) {
+                m_logger.log(Logger.LOG_ERROR, "Error invoking listener stopped method.", t);
+            }
+        }
+    }
+
+	private ServiceStateListener[] getListeners() {
+		synchronized (m_stateListeners) {
+			return (ServiceStateListener[]) m_stateListeners.toArray(SERVICE_STATE_LISTENER_TYPE);
+		}
+	}
+
+	private void activateService(State state) {
+		String init, start;
+		synchronized (this) {
+			init = m_callbackInit;
+			start = m_callbackStart;
+		}
+        // 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(init);
+        // now is the time to configure the service, meaning all required
+        // dependencies will be set and any callbacks called
+        configureService(state);
+        // inform the state listeners we're starting
+        stateListenersStarting();
+        // invoke the start callback, since we're now ready to be used
+        invoke(start);
+        // start tracking optional services
+        startTrackingOptional(state);
+        // register the service in the framework's service registry
+        registerService();
+        // inform the state listeners we've started
+        stateListenersStarted();
+    }
+
+    private void deactivateService(State state) {
+    	String stop, destroy;
+    	synchronized (this) {
+    		stop = m_callbackStop;
+    		destroy = m_callbackDestroy;
+    	}
+        // service deactivation logic, first inform the state listeners
+        // we're stopping
+        stateListenersStopping();
+        // then, unregister the service from the framework
+        unregisterService();
+        // stop tracking optional services
+        stopTrackingOptional(state);
+        // invoke the stop callback
+        invoke(stop);
+        // inform the state listeners we've stopped
+        stateListenersStopped();
+        // invoke the destroy callback
+        invoke(destroy);
+        // destroy the service instance
+        destroyService(state);
+    }
+
+    private void invoke(String name) {
+        if (name != null) {
+            // invoke method if it exists
+            try {
+                Class clazz = m_serviceInstance.getClass();
+                while (clazz != null) {
+                	try {
+                	Method method = clazz.getDeclaredMethod(name, null);
+	                	if (method != null) {
+	                		method.setAccessible(true);
+	                		try {
+    	                		method.invoke(m_serviceInstance, null);
+	                		}
+	                		catch (InvocationTargetException e) {
+	                		    m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + method + ".", e);
+	                		}
+	                		return;
+	                	}
+                	}
+                	catch (NoSuchMethodException e) {
+                		// ignore this, we keep searching if the method does not exist
+                	}
+                	clazz = clazz.getSuperclass();
+                }
+            }
+            catch (Exception e) {
+                m_logger.log(Logger.LOG_ERROR, "Error trying to invoke method named " + name + ".", e);
+            }
+        }
+    }
+
+    private void startTrackingOptional(State state) {
+        Iterator i = state.getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (!dependency.isRequired()) {
+                dependency.start(this);
+            }
+        }
+    }
+    
+    private void stopTrackingOptional(State state) {
+        Iterator i = state.getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (!dependency.isRequired()) {
+                dependency.stop(this);
+            }
+        }
+    }
+
+    private void startTrackingRequired(State state) {
+        Iterator i = state.getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (dependency.isRequired()) {
+                dependency.start(this);
+            }
+        }
+    }
+
+    private void stopTrackingRequired(State state) {
+        Iterator i = state.getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (dependency.isRequired()) {
+                dependency.stop(this);
+            }
+        }
+    }
+
+    private Object createInstance(Class clazz) throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException {
+		Constructor constructor = clazz.getConstructor(VOID);
+		constructor.setAccessible(true);
+        return clazz.newInstance();
+    }
+
+    void initService() {
+    	if (m_serviceInstance == null) {
+	        if (m_implementation instanceof Class) {
+	            // instantiate
+	            try {
+	            	m_serviceInstance = createInstance((Class) m_implementation);
+	            }
+	            catch (Exception e) {
+	                m_logger.log(Logger.LOG_ERROR, "Could not create service instance of class " + m_implementation + ".", e);
+				}
+	        }
+	        else {
+	        	if (m_instanceFactoryCreateMethod != null) {
+	        		Object factory = null;
+		        	if (m_instanceFactory != null) {
+		        		if (m_instanceFactory instanceof Class) {
+		        			try {
+								factory = createInstance((Class) m_instanceFactory);
+							}
+		                    catch (Exception e) {
+		                        m_logger.log(Logger.LOG_ERROR, "Could not create factory instance of class " + m_instanceFactory + ".", e);
+		                    }
+		        		}
+		        		else {
+		        			factory = m_instanceFactory;
+		        		}
+		        	}
+		        	else {
+		        		// TODO review if we want to try to default to something if not specified
+		        	    // for now the JavaDoc of setFactory(method) reflects the fact that we need
+		        	    // to review it
+		        	}
+		        	if (factory == null) {
+                        m_logger.log(Logger.LOG_ERROR, "Factory cannot be null.");
+		        	}
+		        	else {
+    		        	try {
+    						Method m = factory.getClass().getDeclaredMethod(m_instanceFactoryCreateMethod, null);
+    						m_serviceInstance = m.invoke(factory, null);
+    					}
+    		        	catch (Exception e) {
+    	                    m_logger.log(Logger.LOG_ERROR, "Could not create service instance using factory " + factory + " method " + m_instanceFactoryCreateMethod + ".", e);
+    					}
+		        	}
+	        	}
+	        	if (m_implementation == null) {
+                    m_logger.log(Logger.LOG_ERROR, "Implementation cannot be null.");
+	        	}
+	        	if (m_serviceInstance == null) {
+	        	    m_serviceInstance = m_implementation;
+	        	}
+	        }
+	        // configure the bundle context
+	        if (((Boolean) m_autoConfig.get(BundleContext.class)).booleanValue()) {
+	            configureImplementation(BundleContext.class, m_context, (String) m_autoConfigInstance.get(BundleContext.class));
+	        }
+            if (((Boolean) m_autoConfig.get(ServiceRegistration.class)).booleanValue()) {
+                configureImplementation(ServiceRegistration.class, NULL_REGISTRATION, (String) m_autoConfigInstance.get(ServiceRegistration.class));
+            }
+            if (((Boolean) m_autoConfig.get(DependencyManager.class)).booleanValue()) {
+                configureImplementation(DependencyManager.class, m_manager, (String) m_autoConfigInstance.get(DependencyManager.class));
+            }
+    	}
+    }
+
+    public void setAutoConfig(Class clazz, boolean autoConfig) {
+        m_autoConfig.put(clazz, Boolean.valueOf(autoConfig));
+    }
+    
+    public void setAutoConfig(Class clazz, String instanceName) {
+        m_autoConfig.put(clazz, Boolean.valueOf(instanceName != null));
+        m_autoConfigInstance.put(clazz, instanceName);
+    }
+    
+    private void configureService(State state) {
+        // configure all services (the optional dependencies might be configured
+        // as null objects but that's what we want at this point)
+        configureServices(state);
+    }
+
+    private void destroyService(State state) {
+        unconfigureServices(state);
+        m_serviceInstance = null;
+    }
+
+    private void registerService() {
+        if (m_serviceName != null) {
+            ServiceRegistrationImpl wrapper = new ServiceRegistrationImpl();
+            m_registration = wrapper;
+            if (((Boolean) m_autoConfig.get(ServiceRegistration.class)).booleanValue()) {
+                configureImplementation(ServiceRegistration.class, m_registration, (String) m_autoConfigInstance.get(ServiceRegistration.class));
+            }
+            
+            // service name can either be a string or an array of strings
+            ServiceRegistration registration;
+
+            // determine service properties
+            Dictionary properties = calculateServiceProperties();
+
+            // register the service
+            try {
+                if (m_serviceName instanceof String) {
+                    registration = m_context.registerService((String) m_serviceName, m_serviceInstance, properties);
+                }
+                else {
+                    registration = m_context.registerService((String[]) m_serviceName, m_serviceInstance, properties);
+                }
+                wrapper.setServiceRegistration(registration);
+            }
+            catch (IllegalArgumentException iae) {
+                m_logger.log(Logger.LOG_ERROR, "Could not register service " + m_serviceInstance, iae);
+                // set the registration to an illegal state object, which will make all invocations on this
+                // wrapper fail with an ISE (which also occurs when the SR becomes invalid)
+                wrapper.setIllegalState();
+            }
+        }
+    }
+
+	private Dictionary calculateServiceProperties() {
+		Dictionary properties = new Properties();
+		addTo(properties, m_serviceProperties);
+		for (int i = 0; i < m_dependencies.size(); i++) {
+			Dependency d = (Dependency) m_dependencies.get(i);
+			if (d instanceof ConfigurationDependency) {
+				ConfigurationDependency cd = (ConfigurationDependency) d;
+				if (cd.isPropagated()) {
+					Dictionary dict = cd.getConfiguration();
+					addTo(properties, dict);
+				}
+			}
+		}
+		if (properties.size() == 0) {
+			properties = null;
+		}
+		return properties;
+	}
+
+	private void addTo(Dictionary properties, Dictionary additional) {
+		if (properties == null) {
+			throw new IllegalArgumentException("Dictionary to add to cannot be null.");
+		}
+		if (additional != null) {
+			Enumeration e = additional.keys();
+			while (e.hasMoreElements()) {
+				Object key = e.nextElement();
+				properties.put(key, additional.get(key));
+			}
+		}
+	}
+
+    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(), sd.getAutoConfigName());
+            }
+        }
+        else if (dependency instanceof ConfigurationDependency) {
+        	ConfigurationDependency cd = (ConfigurationDependency) dependency;
+        	if (cd.isPropagated()) {
+        		// change service properties accordingly
+        		Dictionary props = calculateServiceProperties();
+        		m_registration.setProperties(props);
+        	}
+        }
+    }
+
+    /**
+     * 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
+     * @param instanceName the name of the instance to fill in, or <code>null</code> if not used
+     */
+    private void configureImplementation(Class clazz, Object instance, String instanceName) {
+    	Object[] instances = getCompositionInstances();
+    	if (instances != null) {
+	    	for (int i = 0; i < instances.length; i++) {
+	    		Object serviceInstance = instances[i];
+		        Class serviceClazz = serviceInstance.getClass();
+		        while (serviceClazz != null) {
+		            Field[] fields = serviceClazz.getDeclaredFields();
+		            for (int j = 0; j < fields.length; j++) {
+		                if (fields[j].getType().equals(clazz) && (instanceName == null || fields[j].getName().equals(instanceName))) {
+		                    try {
+		                    	fields[j].setAccessible(true);
+		                        // synchronized makes sure the field is actually written to immediately
+		                        synchronized (new Object()) {
+		                            fields[j].set(serviceInstance, instance);
+		                        }
+		                    }
+		                    catch (Exception e) {
+		                        m_logger.log(Logger.LOG_ERROR, "Could not set field " + fields[j], e);
+		                        return;
+		                    }
+		                }
+		            }
+		            serviceClazz = serviceClazz.getSuperclass();
+		        }
+	    	}
+    	}
+    }
+    
+    public Object[] getCompositionInstances() {
+      Object[] instances = null;
+      if (m_compositionManagerGetMethod != null) {
+	if (m_compositionManager != null) {
+	  m_compositionManagerInstance = m_compositionManager;
+	}
+	else {
+	  m_compositionManagerInstance = m_serviceInstance;
+	}
+	if (m_compositionManagerInstance != null) {
+	  try {
+	    Method m = m_compositionManagerInstance.getClass().getDeclaredMethod(m_compositionManagerGetMethod, null);
+	    m.setAccessible(true);
+	    instances = (Object[]) m.invoke(m_compositionManagerInstance, null);
+	  }
+	  catch (Exception e) {
+	    m_logger.log(Logger.LOG_ERROR, "Could not obtain instances from the composition manager.", e);
+	    instances = new Object[] { m_serviceInstance };
+	  }
+	}
+      }
+      else {
+	instances = new Object[] { m_serviceInstance };
+      }
+      return instances;
+    }
+
+    private void configureImplementation(Class clazz, Object instance) {
+        configureImplementation(clazz, instance, null);
+    }
+
+    private void configureServices(State state) {
+        Iterator i = state.getDependencies().iterator();
+        while (i.hasNext()) {
+            Dependency dependency = (Dependency) i.next();
+            if (dependency instanceof ServiceDependency) {
+                ServiceDependency sd = (ServiceDependency) dependency;
+                if (sd.isAutoConfig()) {
+                    if (sd.isRequired()) {
+                        configureImplementation(sd.getInterface(), sd.getService(), sd.getAutoConfigName());
+                    }
+                    else {
+                        // for optional services, we do an "ad-hoc" lookup to inject the service if it is
+                        // already available even though the tracker has not yet been started
+                        configureImplementation(sd.getInterface(), sd.lookupService(), sd.getAutoConfigName());
+                    }
+                }
+                // for required dependencies, we invoke any callbacks here
+                if (sd.isRequired()) {
+                    sd.invokeAdded();
+                }
+            }
+        }
+    }
+
+    private void unconfigureServices(State state) {
+        Iterator i = state.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();
+                }
+            }
+        }
+    }
+
+    private void ensureNotActive() {
+    	State state;
+    	synchronized (m_dependencies) {
+    		state = m_state;
+    	}
+    	if (!state.isInactive()) {
+            throw new IllegalStateException("Cannot modify state while active.");
+        }
+    }
+    boolean isRegistered() {
+    	State state;
+    	synchronized (m_dependencies) {
+    		state = m_state;
+    	}
+        return (state.isTrackingOptional());
+    }
+
+    // ServiceComponent interface
+    
+    static class SCDImpl implements ServiceComponentDependency {
+        private final String m_name;
+        private final int m_state;
+        private final String m_type;
+
+        public SCDImpl(String name, int state, String type) {
+            m_name = name;
+            m_state = state;
+            m_type = type;
+        }
+
+        public String getName() {
+            return m_name;
+        }
+
+        public int getState() {
+            return m_state;
+        }
+
+        public String getType() {
+            return m_type;
+        }
+    }
+    
+    public ServiceComponentDependency[] getComponentDependencies() {
+        List deps = getDependencies();
+        if (deps != null) {
+            ServiceComponentDependency[] result = new ServiceComponentDependency[deps.size()];
+            for (int i = 0; i < result.length; i++) {
+                Dependency dep = (Dependency) deps.get(i);
+                if (dep instanceof ServiceComponentDependency) {
+                    result[i] = (ServiceComponentDependency) dep;
+                }
+                else {
+                    result[i] = new SCDImpl(dep.toString(), (dep.isAvailable() ? 1 : 0) + (dep.isRequired() ? 2 : 0), dep.getClass().getName());
+                }
+            }
+            return result;
+        }
+        return null;
+    }
+
+    public String getName() {
+        if (m_serviceName instanceof String[]) {
+            StringBuffer sb = new StringBuffer();
+            String[] names = (String[]) m_serviceName;
+            for (int i = 0; i < names.length; i++) {
+                if (i > 0) {
+                    sb.append(", ");
+                }
+                sb.append(names[i]);
+            }
+            return sb.toString();
+        }
+        else if (m_serviceName instanceof String) {
+            return m_serviceName.toString();
+        }
+        else {
+            return m_implementation.toString();
+        }
+    }
+
+    public int getState() {
+        return (isRegistered() ? 1 : 0);
+    }
+    
+    static {
+        NULL_REGISTRATION = (ServiceRegistration) Proxy.newProxyInstance(ServiceImpl.class.getClassLoader(), new Class[] {ServiceRegistration.class}, new DefaultNullObject());
+    }
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java
new file mode 100644
index 0000000..0ff8473
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public final class ServiceRegistrationImpl implements ServiceRegistration {
+    public static final ServiceRegistrationImpl ILLEGAL_STATE = new ServiceRegistrationImpl();
+    private volatile ServiceRegistration m_registration;
+
+    public ServiceRegistrationImpl() {
+        m_registration = null;
+    }
+    
+    public ServiceReference getReference() {
+        return ensureRegistration().getReference();
+    }
+
+    public void setProperties(Dictionary dictionary) {
+        ensureRegistration().setProperties(dictionary);
+    }
+
+    public void unregister() {
+        ensureRegistration().unregister();
+    }
+
+    public boolean equals(Object obj) {
+        return ensureRegistration().equals(obj);
+    }
+
+    public int hashCode() {
+        return ensureRegistration().hashCode();
+    }
+
+    public String toString() {
+        return ensureRegistration().toString();
+    }
+    
+    private synchronized ServiceRegistration 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
+            }
+        }
+        // check if we're in an illegal state and throw an exception
+        if (ILLEGAL_STATE == m_registration) {
+            throw new IllegalStateException("Service is not registered.");
+        }
+        return m_registration;
+    }
+
+    /**
+     * Sets the service registration and notifies all waiting parties.
+     */
+    void setServiceRegistration(ServiceRegistration registration) {
+        synchronized (this) {
+        	m_registration = registration;
+            notifyAll();
+        }
+    }
+
+    /**
+     * Sets this wrapper to an illegal state, which will cause all threads
+     * that are waiting for this service registration to fail.
+     */
+	void setIllegalState() {
+        setServiceRegistration(ServiceRegistrationImpl.ILLEGAL_STATE);
+	}
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java
new file mode 100644
index 0000000..a655633
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ServiceStateListener {
+    /**
+     * Called when the service is starting. At this point, the required
+     * dependencies have been injected, but the service has not been registered
+     * yet.
+     * 
+     * @param service the service
+     */
+    public void starting(Service service);
+    
+    /**
+     * Called when the service is started. At this point, the service has been
+     * registered.
+     * 
+     * @param service the service
+     */
+    public void started(Service service);
+    
+    /**
+     * Called when the service is stopping. At this point, the service is still
+     * registered.
+     * 
+     * @param service the service
+     */
+    public void stopping(Service service);
+    
+    /**
+     * Called when the service is stopped. At this point, the service has been
+     * unregistered.
+     * 
+     * @param service the service
+     */
+    public void stopped(Service service);
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java
new file mode 100644
index 0000000..83c4b4b
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/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.apache.felix.dependencymanager;
+
+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 + ")"; //$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.temp/src/main/java/org/apache/felix/dependencymanager/ServiceTrackerCustomizer.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/ServiceTrackerCustomizer.java
new file mode 100644
index 0000000..44f7590
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/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.apache.felix.dependencymanager;
+
+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);
+}
diff --git a/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/State.java b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/State.java
new file mode 100644
index 0000000..bd960b6
--- /dev/null
+++ b/dependencymanager.temp/src/main/java/org/apache/felix/dependencymanager/State.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dependencymanager;
+
+import java.util.List;
+
+/**
+ * Encapsulates the current state of the dependencies of a service. A state is
+ * basically an immutable value object.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public final class State {
+    private static final String[] STATES = { "?", "inactive", "waiting for required", "tracking optional" };
+    private static final int INACTIVE = 1;
+    private static final int WAITING_FOR_REQUIRED = 2;
+    private static final int TRACKING_OPTIONAL = 3;
+	private final List m_deps;
+	private final int m_state;
+    private String m_stringValue;
+	
+	/**
+	 * Creates a new state instance.
+	 * 
+	 * @param deps the dependencies that determine the state
+	 * @param isActive <code>true</code> if the service is active (started)
+	 */
+	public State(List deps, boolean isActive) {
+		m_deps = deps;
+		// only bother calculating dependencies if we're active
+    	if (isActive) {
+    		boolean allRequiredAvailable = true;
+    		for (int i = 0; i < deps.size(); i++) {
+    			Dependency dep = (Dependency) deps.get(i);
+    			if (dep.isRequired()) {
+    				if (!dep.isAvailable()) {
+    					allRequiredAvailable = false;
+    				}
+    			}
+    		}
+	    	if (allRequiredAvailable) {
+	    		m_state = TRACKING_OPTIONAL;
+	    	}
+	    	else {
+	    		m_state = WAITING_FOR_REQUIRED;
+	    	}
+    	}
+    	else {
+    		m_state = INACTIVE;
+    	}
+	}
+	
+	public boolean isInactive() {
+		return m_state == INACTIVE;
+	}
+	
+	public boolean isWaitingForRequired() {
+		return m_state == WAITING_FOR_REQUIRED;
+	}
+	
+	public boolean isTrackingOptional() {
+		return m_state == TRACKING_OPTIONAL;
+	}
+	
+	public List getDependencies() {
+		return m_deps;
+	}
+	
+	public synchronized String toString() {
+	    if (m_stringValue == null) {
+	        // we only need to determine this once, but we do it lazily
+	        StringBuffer buf = new StringBuffer();
+    		buf.append("State[" + STATES[m_state] + "|");
+    		List deps = m_deps;
+        	for (int i = 0; i < deps.size(); i++) {
+        		Dependency dep = (Dependency) deps.get(i);
+        		buf.append("(" + dep + (dep.isRequired() ? " R" : " O") + (dep.isAvailable() ? " +" : " -") + ")");
+        	}
+        	m_stringValue = buf.toString();
+	    }
+        return m_stringValue;
+	}
+}
diff --git a/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/ComponentLifeCycleTest.java b/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/ComponentLifeCycleTest.java
new file mode 100644
index 0000000..f836184
--- /dev/null
+++ b/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/ComponentLifeCycleTest.java
@@ -0,0 +1,98 @@
+package org.apache.felix.dependencymanager.test;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import org.apache.felix.dependencymanager.DependencyManager;
+import org.apache.felix.dependencymanager.Logger;
+import org.apache.felix.dependencymanager.Service;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+
+@RunWith( JUnit4TestRunner.class )
+public class ComponentLifeCycleTest {
+    @Configuration
+    public static Option[] configuration() {
+        return options(
+            provision(
+                mavenBundle().groupId("org.apache.felix").artifactId("org.osgi.compendium").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject()
+            )
+        );
+    }    
+    
+    @Test
+    public void testComponentLifeCycleCallbacks(BundleContext context) {
+        DependencyManager m = new DependencyManager(context, new Logger(context));
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a simple service component
+        Service s = m.createService().setImplementation(new ComponentInstance(e));
+        // add it, and since it has no dependencies, it should be activated immediately
+        m.add(s);
+        // remove it so it gets destroyed
+        m.remove(s);
+        // ensure we executed all steps inside the component instance
+        e.step(6);
+    }
+    
+    @Test
+    public void testCustomComponentLifeCycleCallbacks(BundleContext context) {
+        DependencyManager m = new DependencyManager(context, new Logger(context));
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a simple service component
+        Service s = m.createService().setImplementation(new CustomComponentInstance(e)).setCallbacks("a", "b", "c", "d");
+        // add it, and since it has no dependencies, it should be activated immediately
+        m.add(s);
+        // remove it so it gets destroyed
+        m.remove(s);
+        // ensure we executed all steps inside the component instance
+        e.step(6);
+    }
+}
+
+class ComponentInstance {
+    private final Ensure m_ensure;
+    public ComponentInstance(Ensure e) {
+        m_ensure = e;
+        m_ensure.step(1);
+    }
+    public void init() {
+        m_ensure.step(2);
+    }
+    public void start() {
+        m_ensure.step(3);
+    }
+    public void stop() {
+        m_ensure.step(4);
+    }
+    public void destroy() {
+        m_ensure.step(5);
+    }
+}
+
+class CustomComponentInstance {
+    private final Ensure m_ensure;
+    public CustomComponentInstance(Ensure e) {
+        m_ensure = e;
+        m_ensure.step(1);
+    }
+    public void a() {
+        m_ensure.step(2);
+    }
+    public void b() {
+        m_ensure.step(3);
+    }
+    public void c() {
+        m_ensure.step(4);
+    }
+    public void d() {
+        m_ensure.step(5);
+    }
+}
diff --git a/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/Ensure.java b/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/Ensure.java
new file mode 100644
index 0000000..c27e246
--- /dev/null
+++ b/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/Ensure.java
@@ -0,0 +1,11 @@
+package org.apache.felix.dependencymanager.test;
+
+import junit.framework.Assert;
+
+public class Ensure {
+    int step = 1;
+    public synchronized void step(int nr) {
+        Assert.assertEquals(nr, step);
+        step++;
+    }
+}
diff --git a/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/ServiceDependencyTest.java b/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/ServiceDependencyTest.java
new file mode 100644
index 0000000..ddd5af6
--- /dev/null
+++ b/dependencymanager.temp/src/test/java/org/apache/felix/dependencymanager/test/ServiceDependencyTest.java
@@ -0,0 +1,76 @@
+package org.apache.felix.dependencymanager.test;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import org.apache.felix.dependencymanager.DependencyManager;
+import org.apache.felix.dependencymanager.Logger;
+import org.apache.felix.dependencymanager.Service;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+
+@RunWith( JUnit4TestRunner.class )
+public class ServiceDependencyTest {
+    @Configuration
+    public static Option[] configuration() {
+        return options(
+            provision(
+                mavenBundle().groupId("org.apache.felix").artifactId("org.osgi.compendium").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject()
+            )
+        );
+    }    
+
+    @Test
+    public void testServiceRegistrationAndConsumption(BundleContext context) {
+        DependencyManager m = new DependencyManager(context, new Logger(context));
+        // helper class that ensures certain steps get executed in sequence
+        Ensure e = new Ensure();
+        // create a service provider and consumer
+        Service sp = m.createService().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
+        Service sc = m.createService().setImplementation(new ServiceConsumer(e)).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true));
+        m.add(sp);
+        m.add(sc);
+        m.remove(sp);
+        m.remove(sc);
+        // ensure we executed all steps inside the component instance
+        e.step(4);
+    }
+}
+
+interface ServiceInterface {
+    public void invoke();
+}
+
+class ServiceProvider implements ServiceInterface {
+    private final Ensure m_ensure;
+    public ServiceProvider(Ensure e) {
+        m_ensure = e;
+    }
+    public void invoke() {
+        m_ensure.step(2);
+    }
+}
+
+class ServiceConsumer {
+    private volatile ServiceInterface m_service;
+    private final Ensure m_ensure;
+
+    public ServiceConsumer(Ensure e) {
+        m_ensure = e;
+    }
+    
+    public void start() {
+        m_ensure.step(1);
+        m_service.invoke();
+    }
+    
+    public void stop() {
+        m_ensure.step(3);
+    }
+}
