diff --git a/dependencymanager/org.apache.felix.dependencymanager/.classpath b/dependencymanager/org.apache.felix.dependencymanager/.classpath
new file mode 100644
index 0000000..f89ae43
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/dependencymanager/org.apache.felix.dependencymanager/.gitignore b/dependencymanager/org.apache.felix.dependencymanager/.gitignore
new file mode 100644
index 0000000..90dde36
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/bin_test/
+/generated/
diff --git a/dependencymanager/org.apache.felix.dependencymanager/.project b/dependencymanager/org.apache.felix.dependencymanager/.project
new file mode 100644
index 0000000..8640bab
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.apache.felix.dependencymanager</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/dependencymanager/org.apache.felix.dependencymanager/.settings/org.eclipse.jdt.core.prefs b/dependencymanager/org.apache.felix.dependencymanager/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..7341ab1
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd
new file mode 100644
index 0000000..435bc97
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+-buildpath:  \
+	osgi.core;version=4.2,\
+	osgi.cmpn;version=4.2,\
+	org.mockito.mockito-all;version=1.9,\
+	${junit}
+Private-Package: \
+	org.apache.felix.dm.impl,\
+	org.apache.felix.dm.impl.index,\
+	org.apache.felix.dm.impl.index.multiproperty,\
+	org.apache.felix.dm.impl.metatype
+Export-Package: \
+	org.apache.felix.dm,\
+	org.apache.felix.dm.tracker,\
+	org.apache.felix.dm.context
+Include-Resource: META-INF/=resources/LICENSE,\
+	META-INF/=resources/NOTICE,\
+	META-INF/=resources/DEPENDENCIES,\
+	META-INF/=resources/changelog.txt
+Import-Package: !org.junit,!org.mockito.*,*
+Bundle-Activator: org.apache.felix.dm.impl.Activator
+Bundle-Version: 4.0.0
+Bundle-Name: Apache Felix Dependency Manager
+Bundle-Description: Provides dynamic service and component dependency management
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-DocURL: http://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager.html
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Category: osgi
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager/design.txt b/dependencymanager/org.apache.felix.dependencymanager/design.txt
new file mode 100644
index 0000000..94dfce7
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/design.txt
@@ -0,0 +1,47 @@
+7 feb 2014 (marrs & uiterlix):
+
+This prototype demonstrates the new concurrency principles that form the basis for the DM:
+
+ * All external events that influence the state of dependencies are recorded and given 
+   to the serial executor of the component. We record whatever data comes in, so when the
+   actual job is run by the serial executor, we still have access to the original data
+   without having to access other sources whose state might have changed since.
+ * The serial executor of a component will execute a job immediately if it is being called
+   by the thread that is already executing jobs.
+ * If the serial executor of a component had not yet started a job, it will queue and start
+   it on the current thread.
+ * If the serial executor gets invoked from a different thread than the one currently
+   executing jobs, the job will be put at the end of the queue. As mentioned before, any
+   data associated with the event will also be recorded so it is available when the job
+   executes.
+ * State in the component and dependency can only be modified via the serial executor
+   thread. This means we don't need explicit synchronization anywhere.
+
+20 sept 2014 (pderop):
+
+ * Added support for parallelism: To allow components to be started and handled in parallel, you can
+   now register in the OSGi service registry a ComponentExecutorFactory service that is used to get
+   an Executor for the management of all components dependencies/lifecycle callbacks. See javadoc
+   from the org.apache.felix.dm.ComponentExecutorFactory interface for more informations.
+   
+   You can also take a look at the the org.apache.felix.dependencymanager.samples project, which is
+   registering a ComponentExecutorFactory from org.apache.felix.dependencymanager.samples.tpool
+   bundle.
+  
+   See also the following property in the org.apache.felix.dependencymanager.samples/bnd.bnd 
+
+	org.apache.felix.dependencymanager.parallel=\
+		'!org.apache.felix.dependencymanager.samples.tpool, *',\
+
+  Here, all components will be handled by Executors provided by the ComponentExecutorFactory,
+  except those having a package starting with "org.apache.felix.dependencymanager.samples.tpool"
+  (because the threadpool is itself defined using the Dependency Manager API).
+
+
+
+
+
+
+
+
+
diff --git a/dependencymanager/org.apache.felix.dependencymanager/resources/DEPENDENCIES b/dependencymanager/org.apache.felix.dependencymanager/resources/DEPENDENCIES
new file mode 100644
index 0000000..bb3ee11
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/resources/DEPENDENCIES
@@ -0,0 +1,24 @@
+Apache Felix Dependency Manager
+Copyright 2011-2015 The Apache Software Foundation
+
+This software was developed at the Apache Software Foundation
+(http://www.apache.org) and may have dependencies on other
+Apache software licensed under Apache License 2.0.
+
+I. Included Third-Party Software
+
+This product includes software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2014).
+Licensed under the Apache License 2.0.
+
+II. Used Third-Party Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2014).
+Licensed under the Apache License 2.0.
+
+III. Overall License Summary
+
+- Apache License 2.0
diff --git a/dependencymanager/org.apache.felix.dependencymanager/resources/LICENSE b/dependencymanager/org.apache.felix.dependencymanager/resources/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/resources/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/org.apache.felix.dependencymanager/resources/NOTICE b/dependencymanager/org.apache.felix.dependencymanager/resources/NOTICE
new file mode 100644
index 0000000..7df085c
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/resources/NOTICE
@@ -0,0 +1,12 @@
+Apache Felix Dependency Manager
+Copyright 2011-2015 The Apache Software Foundation
+
+
+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, 2015).
+Licensed under the Apache License 2.0.
diff --git a/dependencymanager/org.apache.felix.dependencymanager/resources/changelog.txt b/dependencymanager/org.apache.felix.dependencymanager/resources/changelog.txt
new file mode 100644
index 0000000..3cda464
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/resources/changelog.txt
@@ -0,0 +1,85 @@
+Release 4.0.0:
+-------------
+
+FELIX-2706: Support callback delegation for Configuration Dependencies
+FELIX-3914: Log unsuccessful field injections
+FELIX-4158: ComponentDeclaration should give access to component information
+FELIX-4304: DependencyManager ComponentImpl should not assume all service properties are stored in a Hashtable
+FELIX-4394: Race problems in DependencyManager Configuration Dependency
+FELIX-4426: Allow DM to manage collections of services
+FELIX-4588: createCopy method ConfigurationDependency produces a malfunctioning clone
+FELIX-4594: Propagation from dependencies overwrites service properties
+FELIX-4598: BundleDependency can effectively track only one bundle
+FELIX-4600: Cherrypicking of propagated properties
+FELIX-4602: TemporalServiceDependency does not properly propagate RuntimeExceptions
+FELIX-4667: "top" command for the Dependency Manager Shell
+FELIX-4672: Allow callbacks to third party instance for adapters
+FELIX-4673: Log any error thrown when trying to create a null object
+FELIX-4680: Add more DM ServiceDependency callback signatures
+FELIX-4807: New thread model for Dependency Manager
+
+Release 3.2.0:
+--------------
+
+FELIX-3910: Race conditions in DependencyManager
+FELIX-4334: ServiceDependency properties change callback issue
+FELIX-4285: Remove abstract modifier from DependencyActivatorBase.destroy()
+FELIX-4294: Dependency Manager Shell improvements
+FELIX-4305: DependencyMananer Adapters - service properties propagation
+FELIX-4002: ComponentStateListener.started is invoked twice when the listener is added in the start method.
+FELIX-4395: DependencyManager Configuration Dependency does not clone some class fields.
+FELIX-4014: handleAspectAwareRemoved in ServiceDependencyImpl can cause a possible deadlock
+FELIX-4097: Allow debug logging for specific instances of service dependencies to debug wiring issues.
+FELIX-4098: Aspect swap sometimes invokes the callbacks in the wrong order in a multithreaded application.
+FELIX-4099: Add support for negations in the multi property filter index.
+FELIX-4186: NPE in DependencyManager Logger
+FELIX-4226: Add option to have the dependency manager log against a single BundleContext's LogService.
+FELIX-4361: Possible ConcurrentModificationException in DependencyManager.getComponents()
+
+Release 3.1.0
+-------------
+
+FELIX-303 - Support for compositions
+FELIX-1201 - Issue with DM and CM
+FELIX-1278 - DM/ AutoConfig is active event if setCallbacks method has been invoked
+FELIX-1464 - issue when using a negation in ldap service dependency filter
+FELIX-1546 - DM/Temporal Dependency/Bound Service Replacement features
+FELIX-2078 - Not all callbacks invoked when declaring a service as required and starting it after dependencies
+FELIX-2344 - DM / callback method is not invoked when an extra dependency is defined within an "init" component method.
+FELIX-2348 - DM/ ResourceAdapter NPE
+FELIX-2369 - DM/ Service start method is invoked even if an extra required dependency is unavailable
+FELIX-2816 - dependency manager calls init() twice
+FELIX-2947 - Filter indices must use service trackers that track all services and aspects.
+FELIX-2953 - Make the cache that InvocationUtil uses configurable.
+FELIX-2954 - DM/ annotated component factory does not allow to provide a component instance explicitly
+FELIX-2955 - IllegalStateException when doing a 'dm notavail' shell command.
+FELIX-2956 - DM/ json should be embedded in the annotation scanner plugin
+FELIX-2964 - DM/ NPE on some dependency manager adapters, when "auto-configuration" mode is disabled.
+FELIX-2970 - DM/ Factory Configuration Adapter Service does not copy adapter dependencies
+FELIX-2976 - InvocationUtil cache is not used properly for determining that methods do not exist in a class
+FELIX-2987 - DependencyManager ConfigurationDependency update isn't propagated to super classes
+FELIX-3008 - NPE in ServiceRegistryCache when dependency manager bundle is not started first
+FELIX-3042 - [PATCH] Add a convenience clear() method on DependencyManager
+FELIX-3057 - getServiceReferences() should not return an empty array
+FELIX-3186 - Adapter services do not get their adapted services transparently replaced when an aspect is added to them.
+FELIX-3201 - Offer more functional callback methods for services that have aspects on them.
+FELIX-3218 - ServiceTracker performance is not optimal with a service dependency that results in n-thousands of injected services.
+FELIX-3264 - Dependency manager shell should not print the state of optional dependencies when not all required ones are available
+FELIX-3292 - Allow passing of resource properties to a resource handler for use with resource adapters.
+FELIX-3337 - DependencyManager/Updated configuration dependency does not propagate to provided service properties
+FELIX-3402 - DependencyManager stop can trigger IndexOutOfBoundsException
+FELIX-3423 - AdapterImpl copies the DependencyManager.ASPECT service property when adapting an aspect.
+FELIX-3424 - Add support for changed callbacks on Aspect services.
+FELIX-3425 - Provide a filter index for adapter services.
+FELIX-3475 - DependencyManager compatibility bundle - ServiceDependencyImpl does not override toString
+FELIX-3564 - Memory leak in Filterindex / ServiceRegistryCache
+FELIX-3592 - ServiceDependencyImpl does not copy the swapped callback in it's constructor.
+FELIX-3617 - Missing toString methods in DependencyManager compat bundle
+FELIX-3682 - Dependency Manager Annotation-3.0.0 module doesn't expose OSGI meta information in MANIFEST.MF
+FELIX-3828 - Aspect and Adapter filter indices to not handle components that have been bound with multiple interfaces correctly.
+
+
+Release 3.0.0
+-------------
+
+Major, backward incompatible release. Start of recorded changes.
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/.gitignore b/dependencymanager/org.apache.felix.dependencymanager/src/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/.gitignore
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/BundleDependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/BundleDependency.java
new file mode 100644
index 0000000..76bb73b
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/BundleDependency.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface BundleDependency extends Dependency, ComponentDependencyDeclaration {
+    /**
+     * Sets the callbacks for this dependency. 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 bundle was added
+     * @param removed the method to call when a bundle was removed
+     * @return the bundle dependency
+     */
+    public BundleDependency setCallbacks(String added, String removed);
+
+    /**
+     * Sets the callbacks for this dependency. 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 bundle was added
+     * @param changed the method to call when a bundle was changed
+     * @param removed the method to call when a bundle was removed
+     * @return the bundle dependency
+     */
+    public BundleDependency setCallbacks(String added, String changed, String removed);
+
+    /**
+     * Sets the callbacks for this dependency. 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 bundle was added
+     * @param removed the method to call when a bundle was removed
+     * @return the bundle dependency
+     */
+    public BundleDependency setCallbacks(Object instance, String added, String removed);
+
+    /**
+     * Sets the callbacks for this dependency. 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 bundle was added
+     * @param changed the method to call when a bundle was changed
+     * @param removed the method to call when a bundle was removed
+     * @return the bundle dependency
+     */
+    public BundleDependency setCallbacks(Object instance, String added, String changed, String removed);
+
+    /**
+     * Enables auto configuration for this dependency. This means the component implementation (composition) will be
+     * injected with this bundle dependency automatically.
+     * 
+     * @param autoConfig <code>true</code> to enable auto configuration
+     * @return the bundle dependency
+     */
+    public BundleDependency setAutoConfig(boolean autoConfig);
+
+    /**
+     * Sets the dependency to be required.
+     * 
+     * @param required <code>true</code> if this bundle dependency is required
+     * @return the bundle dependency
+     */
+    public BundleDependency setRequired(boolean required);
+
+    /**
+     * Sets the bundle to depend on directly.
+     * 
+     * @param bundle the bundle to depend on
+     * @return the bundle dependency
+     */
+    public BundleDependency setBundle(Bundle bundle);
+
+    /**
+     * Sets the filter condition to depend on. Filters are matched against the full manifest of a bundle.
+     * 
+     * @param filter the filter condition
+     * @return the bundle dependency
+     * @throws IllegalArgumentException if the filter is invalid
+     */
+    public BundleDependency setFilter(String filter) throws IllegalArgumentException;
+
+    /**
+     * Sets the bundle state mask to depend on. The OSGi BundleTracker explains this mask in more detail, but
+     * it is basically a mask with flags for each potential state a bundle can be in.
+     * 
+     * @param mask the mask to use
+     * @return the bundle dependency
+     */
+    public BundleDependency setStateMask(int mask);
+
+    /**
+     * Sets property propagation. If set to <code>true</code> any bundle manifest properties will be added
+     * to the service properties of the component that has this dependency (if it registers as a service).
+     * 
+     * @param propagate <code>true</code> to propagate the bundle manifest properties
+     * @return the bundle dependency
+     */
+    public BundleDependency setPropagate(boolean propagate);
+    
+    /**
+     * Sets an Object instance and a callback method used to propagate some properties to the provided service properties.
+     * The method will be invoked on the specified object instance and must have one of the following signatures:
+     * <ul><li>Dictionary callback(ServiceReference, Object service) 
+     * <li>Dictionary callback(ServiceReference)
+     * </ul>
+     * @param instance the Object instance which is used to retrieve propagated service properties 
+     * @param method the method to invoke for retrieving the properties to be propagated to the service properties.
+     * @return this service dependency.
+     */
+    public BundleDependency setPropagate(Object instance, String method);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Component.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Component.java
new file mode 100644
index 0000000..0b618ad
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Component.java
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.ServiceRegistration;
+
+
+/**
+ * Component interface. Components are the main building blocks for OSGi applications.
+ * They can publish themselves as a service, and they can have dependencies. These
+ * dependencies will influence their life cycle as component will only be activated
+ * when all required dependencies are available.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Component {
+    /**
+     * Sets the implementation for this component. 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 life cycle management options:
+     * <ol>
+     * <li><code>init()</code> is invoked after the instance has been
+     * created and dependencies have been resolved, and can be used to
+     * initialize the internal state of the instance or even to add more
+     * dependencies based on runtime state</li>
+     * <li><code>start()</code> is invoked right 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 component
+     * @see ComponentStateListener
+     */
+	public Component setImplementation(Object implementation);
+
+    /**
+     * Adds dependency(ies) to this component, atomically. If the component is already active or if you add
+     * dependencies from the init method, then you should add all the dependencies in one single add method call 
+     * (using the varargs argument), because this method may trigger component activation (like
+     * the ServiceTracker.open() method does).
+     * 
+     * @param dependencies the dependencies to add.
+     * @return this component
+     */
+	public Component add(Dependency ... dependencies);
+	
+	/**
+	 * Removes a dependency from the component.
+	 * @param d the dependency to remove
+	 * @return this component
+	 */
+	public Component remove(Dependency d);
+
+    /**
+     * Adds a component state listener to this component.
+     * 
+     * @param listener the state listener
+     */
+	public Component add(ComponentStateListener listener);
+
+    /**
+     * Removes a component state listener from this component.
+     * 
+     * @param listener the state listener
+     */
+	public Component remove(ComponentStateListener listener);
+
+    /**
+     * Sets the public interface under which this component 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 component
+     */
+	public Component setInterface(String serviceName, Dictionary<?,?> properties);
+
+    /**
+     * Sets the public interfaces under which this component should be registered
+     * in the OSGi service registry.
+     *  
+     * @param serviceNames the names of the service interface
+     * @param properties the properties for these services
+     * @return this component
+     */
+	public Component setInterface(String[] serviceNames, Dictionary<?, ?> properties);
+
+    /**
+     * Configures auto configuration of injected classes in the component instance.
+     * The following injections are currently performed, unless you explicitly
+     * turn them off:
+     * <dl>
+     * <dt>BundleContext</dt><dd>the bundle context of the bundle</dd>
+     * <dt>ServiceRegistration</dt><dd>the service registration used to register your service</dd>
+     * <dt>DependencyManager</dt><dd>the dependency manager instance</dd>
+     * <dt>Component</dt><dd>the component instance of the dependency manager</dd>
+     * </dl>
+     * 
+     * @param clazz the class (from the list above)
+     * @param autoConfig <code>false</code> to turn off auto configuration
+     */
+	public Component setAutoConfig(Class<?> clazz, boolean autoConfig);
+
+    /**
+     * Configures auto configuration of injected classes in the component instance.
+     * 
+     * @param clazz the class (from the list above)
+     * @param instanceName the name of the instance to inject the class into
+     * @see #setAutoConfig(Class, boolean)
+     */
+	public Component setAutoConfig(Class<?> clazz, String instanceName);
+
+    /**
+     * Returns the service registration for this component. The method
+     * will return <code>null</code> if no service registration is
+     * available, for example if this component is not registered as a
+     * service at all.
+     * 
+     * @return the service registration
+     */
+	public ServiceRegistration getServiceRegistration();
+
+    /**
+     * Returns the instance that make up this component. If the component has a composition of instances,
+     * then the first instance of the composition is returned. Null is returned if the component has not 
+     * even been instantiated.
+     * 
+     * @return the component instances
+     */
+	public <T> T getInstance();
+
+    /**
+     * Returns the composition instances that make up this component, or just the
+     * component instance if it does not have a composition, or an empty array if
+     * the component has not even been instantiated.
+     * 
+     * @return the component instances
+     */
+	public Object[] getInstances();
+
+    /**
+     * Returns the service properties associated with the component.
+     * 
+     * @return the properties or <code>null</code> if there are none
+     */
+	public <K,V> Dictionary<K,V> getServiceProperties();
+
+    /**
+     * Sets the service properties associated with the component. If the service
+     * was already registered, it will be updated.
+     * 
+     * @param serviceProperties the properties
+     */
+	public Component 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 component implementation. The
+     * dependency manager will look for a method of this name with the following signatures,
+     * in this order:
+     * <ol>
+     * <li>method(Component component)</li>
+     * <li>method()</li>
+     * </ol>
+     * 
+     * @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 component
+     */
+	public Component setCallbacks(String init, String start, String stop, String destroy);
+
+    /**
+     * Sets the names of the methods used as callbacks. These methods, when found, are
+     * invoked on the specified instance as part of the life cycle management of the component
+     * implementation.
+     * <p>
+     * See setCallbacks(String init, String start, String stop, String destroy) for more
+     * information on the signatures. Specifying an instance means you can create a manager
+     * that will be invoked whenever the life cycle of a component changes and this manager
+     * can then decide how to expose this life cycle to the actual component, offering an
+     * important indirection when developing your own component models.
+     *
+     * @return this component
+     */
+	public Component setCallbacks(Object instance, String init, String start, String stop, String destroy);
+
+    /**
+     * 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 component. 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
+     * @return this component
+     */
+	public Component 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 component.
+     * <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
+     * @return this component
+     */
+	public Component 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
+     * @return this component
+     */
+	public Component 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
+     * @return this component
+     */
+	public Component setComposition(String getMethod);
+
+    /**
+     * Returns the dependency manager associated with this component.
+     * @return the dependency manager associated with this component.
+     */
+	public DependencyManager getDependencyManager();
+
+	/**
+	 * Returns the component description (dependencies, service provided, etc ...).
+	 * @return the component description (dependencies, service provided, etc ...).
+	 */
+	public ComponentDeclaration getComponentDeclaration();
+	
+	/**
+	 * Activate debug for this component. Informations related to dependency processing will be displayed
+	 * using osgi log service, our to standard output if no log service is currently available.
+	 * @param label
+	 */
+	public Component setDebug(String label);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDeclaration.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDeclaration.java
new file mode 100644
index 0000000..85353ef
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDeclaration.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.util.Dictionary;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * Describes a component. Component declarations form descriptions of components
+ * 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 ComponentDeclaration {
+    /** 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 component. */
+    public ComponentDependencyDeclaration[] getComponentDependencies();
+    /** Returns the description of this component (the classname or the provided service(s)) */
+    public String getName();
+    /** Returns the class name of the Component implementation. */
+    public String getClassName();
+    /** Returns the service optionally provided by this component, or null */
+    public String[] getServices();
+    /** Returns the service properties, or null */
+    public <K,V> Dictionary<K, V> getServiceProperties();     
+    /** Returns the state of this component. */
+    public int getState();
+    /** Returns the instance id of this component. */
+    public long getId();
+    /** Returns the bundle context associated with this component. */
+    public BundleContext getBundleContext();
+    /** Returns the dependency manager for this component */
+    public DependencyManager getDependencyManager();
+    /** Returns the execution time in nanos for each component callbacks (init/start/stop/destroy) */
+    public Map<String, Long> getCallbacksTime(); 
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDependencyDeclaration.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDependencyDeclaration.java
new file mode 100644
index 0000000..b86f390
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentDependencyDeclaration.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+/**
+ * Describes a 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 ComponentDependencyDeclaration {
+    /** Names for the states of this dependency. */
+    public static final String[] STATE_NAMES = { 
+        "optional unavailable", 
+        "optional available", 
+        "required unavailable", 
+        "required available",
+        "optional (not tracking)",
+        "required (not tracking)"
+        };
+    /** 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;
+    /** State constant for an optional dependency that has not been started yet. */
+    public static final int STATE_OPTIONAL = 4;
+    /** State constant for a required dependency that has not been started yet. */
+    public static final int STATE_REQUIRED = 5;
+    /** Returns the name of this dependency (a generic name with optional info separated by spaces)*/
+    public String getName();
+    /** Returns the simple dependency name (service classname for example) */
+    public String getSimpleName();
+    /** Returns the Dependency filter or null */
+    public String getFilter();
+    /** 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/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentExecutorFactory.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentExecutorFactory.java
new file mode 100644
index 0000000..17bdbfd
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentExecutorFactory.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.util.concurrent.Executor;
+
+/**
+ * A <code>ComponentExecutorFactory</code> service can be registered by any management agent bundle 
+ * in order to enable parallel activation of Components.<p>
+ * 
+ * A <code>ComponentExecutorFactory</code> is part of the new concurrency model that forms the basis 
+ * of Dependency Manager 4.0. Let's first give a brief overview of the default thread model used when 
+ * no ComponentExecutorFactory is used. Then we'll explain the rationale and the usage of a 
+ * <code>ComponentExecutorFactory</code> service.
+ * <p> 
+ * 
+ * <h3>Default Thread Model</h3>
+ * 
+ * By default, Dependency Manager uses a <b>lock-free/single thread</b> model:
+ * <p><ul>
+ * 
+ * <li> When an external event that influence the state of a Component is taking place (for example, 
+ * when a service dependency on which the Component is depending on is registered in the registry by 
+ * a given thread), then DependencyManager does not perform any locking for the handling of the event. 
+ * Instead of that, a job that will handle the event is inserted in an internal lock-free 
+ * <b><code>Serial Queue</code></b> which is internally maintained in each Component.
+ * 
+ * <li> all jobs scheduled in the <code>Serial Queue</code> are then executed in FIFO order, by the first
+ * thread which has triggered the first event. This avoid to use some blocking locks in DM internals, and 
+ * also it simplifies the development of DM components, because all lifecycle callbacks 
+ * (init/start/stop/destroy) and dependency injections are scheduled through the <code>Serial Queue</code>: 
+ * This means that your component is not concurrently called in lifecycle callbacks and in dependency injection 
+ * methods.
+ * 
+ * <li> Now let's describe which thread is executing the jobs scheduled in a Component <code>Serial Queue</code>: 
+ * When a job (J1) is scheduled in the queue while it is empty, then the current thread becomes the "master"
+ * and will immediately execute the </code>Serial Queue</code> tasks (synchronously). And if another thread 
+ * triggers another event concurrently while the "master" thread is executing the job J1, then a job (J2) 
+ * for this new event is just enqueued in the <code>Serial Queue</code>, but the other thread returns 
+ * immediately to the caller, and the job J2 will then be executed by the "master" thread (after J1).
+ * </ul>
+ * 
+ * <p>
+ * This mechanism allows to serially handle all Component events (service dependencies) in FIFO order 
+ * without maintaining any locks.
+ * 
+ * <h3>Enabling parallelism with a <code>ComponentExecutorFactory</code></h3>
+ *  
+ * As described above, all the external events that influence the state of a given component are handed by 
+ * jobs scheduled in the <code>Serial Queue</code> of the Component, and the jobs are getting executed serially 
+ * by a single "master" thread. So usually, bundles are started from a single thread, meaning that all Components
+ * are then activated synchronously.
+ * <p>
+ * 
+ * But when you register in the OSGi service registry a <code>ComponentExecutorFactory</code>, that factory 
+ * will be used by DependencyManager to create an Executor of your choice for each Component, typically a shared 
+ * threadpool configured by yourself. And all the Component <code>Serial Queues</code> will be executed using 
+ * the Executor returned by the {@link #getExecutorFor(Component)} method.
+ * However, jobs scheduled in the <code>Serial Queue</code> of a given Component are still executed one at a 
+ * time, in FIFO order and the Component remains single threaded, and <b>independent Components 
+ * may then each be managed and activated concurrently with respect to each other</b>.
+ * <p>
+ * If you want to ensure that all Components are initialized <b>after</b> the ComponentExecutorFactory is 
+ * registered in the OSGI registry, you can use the "org.apache.felix.dependencymanager.parallel" OSGi 
+ * system property which specifies the list of components which must wait for the ComponentExecutorFactory 
+ * service. This property value can be set to a wildcard ("*"), or a list of components implementation class 
+ * prefixes (comma separated). So, all components whose class name starts with the specified prefixes will be cached 
+ * until the ComponentExecutorFactory service is registered (In this way, it is not necessary to use
+ * the StartLevel service if you want to ensure that all components are started concurrently).
+ * <p>
+ * 
+ * Some class name prefixes can also be negated (using "!"), in order to exclude some components from the 
+ * list of components using the ComponentExecutorFactory service.
+ * <p>
+ * 
+ * Notice that if the ComponentExecutorFactory itself and all its dependent services are defined using 
+ * the Dependency Manager API, then you have to list the package of such components with a "!" 
+ * prefix, in order to indicate that those components must not wait for a ComponentExecutorFactory service
+ * (since they are part of the ComponentExecutorFactory implementation !).
+ * <p>
+ * 
+ * <h3>Examples for the usage of the "org.apache.felix.dependencymanager.parallel" property:</h3>
+ * 
+ * <blockquote><pre>
+ * org.apache.felix.dependencymanager.parallel=*   
+ *      -> means all components must be cached until a ComponentExecutorFactory comes up.
+ * 
+ * org.apache.felix.dependencymanager.parallel=foo.bar, foo.zoo
+ *      -> means only components whose implementation class names are starting with "foo.bar" or "foo.zoo" 
+ *      must be handled using an Executor returned by the ComponentExecutorFactory service. Other Components
+ *      will be handled normally, as when there is no ComponentExecutorFactory available.
+ * 
+ * org.apache.felix.dependencymanager.parallel=!foo.threadpool, *
+ *      -> means all components must be delayed until the ComponentExecutorFactory comes up, except the 
+ *      components whose implementations class names are starting with "foo.threadpool" prefix). 
+ * </pre></blockquote>
+ * 
+ * <h3>Examples of a ComponentExecutorFactory that provides a shared threadpool:</h3>
+ * 
+ * First, we define the OSGi bundle context system property to enable parallelism for all DM Components
+ * excepts the one which declares the ComponentExecutorFactory:
+ * 
+ * <blockquote> <pre>
+ *   org.apache.felix.dependencymanager.parallel=!com.acme.management.threadpool, *
+ * </pre></blockquote>
+ * 
+ * Next, here is the Activator which declares the ComponentExecutorFactory:
+ * 
+ * <blockquote> <pre>
+ *   package com.acme.management.threadpool;
+ *   import org.apache.felix.dm.*;
+ *   
+ *   public class Activator extends DependencyActivatorBase {      
+ *      public void init(BundleContext context, DependencyManager mgr) throws Exception {
+ *         mgr.add(createComponent()
+ *            .setInterface(ComponentExecutorFactory.class.getName(), null)
+ *            .setImplementation(ComponentExecutorFactoryImpl.class)
+ *            .add(createConfigurationDependency()
+ *                 .setPid("com.acme.management.threadpool.ComponentExecutorFactoryImpl")));
+ *      }
+ *   }
+ * </pre></blockquote>
+ * 
+ * And here is the implementation for our ComponentExecutorFactory:
+ * 
+ * <blockquote> <pre>
+ *   package com.acme.management.threadpool;
+ *   import org.apache.felix.dm.*;
+ *
+ *  public class ComponentExecutorFactoryImpl implements ComponentExecutorFactory {
+ *      volatile Executor m_threadPool;
+ *      
+ *      void updated(Dictionary conf) {
+ *          m_sharedThreadPool = Executors.newFixedThreadPool(Integer.parseInt("threadpool.size"));
+ *      }
+ *
+ *      &#64;Override
+ *      public Executor getExecutorFor(Component component) {
+ *          return m_sharedThreadPool; // Use a shared threadpool for all Components
+ *      }
+ *  }
+ * </pre></blockquote>
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @since 4.0.0
+ */
+public interface ComponentExecutorFactory {
+    /**
+     * Returns an Executor (typically a shared thread pool) used to manage a given DependencyManager Component.
+     * 
+     * @param component the Component to be managed by the returned Executor
+     * @return an Executor used to manage the given component, or null if the component must not be managed using any executor.
+     */
+    Executor getExecutorFor(Component component);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentState.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentState.java
new file mode 100644
index 0000000..1afb437
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentState.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+/**
+ * Component states. Any state listeners registered using @link {@link Component#add(ComponentStateListener)} method
+ * are notified with the following stated whenever the component state changes.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public enum ComponentState {
+    /**
+     * The component is not currently started, and is inactive.
+     */
+	INACTIVE, 
+	
+	/**
+	 * The component is waiting for some required dependencies.
+	 */
+	WAITING_FOR_REQUIRED, 
+	
+	/**
+	 * The component has all its initial required dependencies available, but is now waiting for some extra required
+	 * dependencies which have been added after the component have been started (like from the component init method for example).
+	 */
+	INSTANTIATED_AND_WAITING_FOR_REQUIRED, 
+	
+	/**
+	 * The component is active, and is now tracking available optional dependencies.
+	 */
+	TRACKING_OPTIONAL
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentStateListener.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentStateListener.java
new file mode 100644
index 0000000..f3d3291
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ComponentStateListener.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+/**
+ * This interface can be used to register a component state listener. Component
+ * state listeners are called whenever a component state changes. You get notified
+ * when the component is starting, started, stopping and stopped. Each callback
+ * includes a reference to the component in question.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ComponentStateListener {
+    public void changed(Component c, ComponentState state);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
new file mode 100644
index 0000000..a58b2ef
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ConfigurationDependency.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+/**
+ * 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 component 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 interface ConfigurationDependency extends Dependency, ComponentDependencyDeclaration {
+    /**
+     * Sets the name of the callback method that should be invoked when a configuration
+     * is available. The contract for this method is identical to that of
+     * <code>ManagedService.updated(Dictionary) throws ConfigurationException</code>.
+     * 
+     * @param callback the name of the callback method
+     */
+	ConfigurationDependency setCallback(String callback);
+
+    /**
+     * Sets the name of the callback method that should be invoked when a configuration
+     * is available. The contract for this method is identical to that of
+     * <code>ManagedService.updated(Dictionary) throws ConfigurationException</code>.
+     * 
+     * @param instance the instance to call the callbacks on
+     * @param callback the name of the callback method
+     */
+    ConfigurationDependency setCallback(Object instance, String callback);
+
+    /**
+     * Sets the <code>service.pid</code> of the configuration you are depending
+     * on.
+     */
+	ConfigurationDependency setPid(String pid);
+
+    /**
+     * Sets propagation of the configuration properties to the service
+     * properties. Any additional service properties specified directly are
+     * merged with these.
+     */
+	ConfigurationDependency setPropagate(boolean propagate);
+
+    /**
+     * The label used to display the tab name (or section) where the properties
+     * are displayed. Example: "Printer Service".
+     * 
+     * @return The label used to display the tab name where the properties are
+     *         displayed (may be localized)
+     */
+	ConfigurationDependency setHeading(String heading);
+
+    /**
+     * A human readable description of the PID this configuration is associated
+     * with. Example: "Configuration for the PrinterService bundle".
+     * 
+     * @return A human readable description of the PID this configuration is
+     *         associated with (may be localized)
+     */
+	ConfigurationDependency setDescription(String description);
+
+    /**
+     * Points to the basename of the Properties file that can localize the Meta
+     * Type informations. The default localization base name for the properties
+     * is OSGI-INF/l10n/bundle, but can be overridden by the manifest
+     * Bundle-Localization header (see core specification, in section
+     * Localization on page 68). You can specify a specific localization
+     * basename file using this method (e.g.
+     * <code>setLocalization("person")</code> will match person_du_NL.properties
+     * in the root bundle directory.
+     */
+	ConfigurationDependency setLocalization(String path);
+
+    /**
+     * Adds a MetaData regarding a given configuration property.
+     */
+	ConfigurationDependency add(PropertyMetaData properties);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Dependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Dependency.java
new file mode 100644
index 0000000..7014ebb
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Dependency.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.util.Dictionary;
+
+/**
+ * Generic dependency for a component. 
+ * Can be added to a single component. Can be available, or not.. 
+ * 
+ * @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 component 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();
+
+    /**
+     * Returns <code>true</code> if auto configuration is enabled for this dependency.
+     * Auto configuration means that a dependency is injected in the component instance
+     * when it's available, and if it's unavailable, a "null object" will be inserted
+     * instead.
+     * 
+     * @return true if auto configuration is enabled for this dependency
+     */
+    public boolean isAutoConfig();
+    
+    /**
+     * Returns the name of the member in the class of the component instance
+     * to inject into. If you specify this, not all members of the right
+     * type will be injected, only the member whose name matches.
+     * 
+     * @return the name of the member in the class of the component instance to inject into
+     */
+    public String getAutoConfigName();
+    
+    /**
+     * Determines if the properties associated with this dependency should be propagated to
+     * the properties of the service registered by the component they belong to.
+     * 
+     * @see Dependency#getProperties()
+     * 
+     * @return <code>true</code> if the properties should be propagated
+     */
+    public boolean isPropagated();
+
+    /**
+     * Returns the properties associated with this dependency.
+     * 
+     * @see Dependency#isPropagated()
+     * 
+     * @return the properties
+     */
+    public <K,V> Dictionary<K,V> getProperties();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java
new file mode 100644
index 0000000..d06b91a
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyActivatorBase.java
@@ -0,0 +1,345 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+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 components 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 components 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.
+     * <p>
+     * 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 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);
+        m_manager.clear();
+        m_manager = null;
+        m_context = null;
+    }
+    
+    /**
+     * Returns the bundle context that is associated with this bundle.
+     * 
+     * @return the bundle context
+     */
+    public BundleContext getBundleContext() {
+        return m_context;
+    }
+
+    /**
+     * Returns the dependency manager that is associated with this bundle.
+     * 
+     * @return the dependency manager
+     */
+    public DependencyManager getDependencyManager() {
+        return m_manager;
+    }
+    
+    /**
+     * Returns the logger that is associated with this bundle. A logger instance
+     * is a proxy that will log to a real OSGi logservice if available and standard
+     * out if not.
+     * 
+     * @return the logger
+     */
+    public Logger getLogger() {
+        return m_logger;
+    }
+    
+    /**
+     * Creates a new component.
+     * 
+     * @return the new component
+     */
+    public Component createComponent() {
+        return m_manager.createComponent();
+    }
+    
+    /**
+     * Creates a new service dependency.
+     * 
+     * @return the service dependency
+     */
+    public ServiceDependency createServiceDependency() {
+        return m_manager.createServiceDependency();
+    }
+    
+    /**
+     * Creates a new temporal service dependency.
+     * 
+     * @param timeout the max number of milliseconds to wait for a service availability.
+     * @return the service dependency
+     */
+    public ServiceDependency createTemporalServiceDependency(long timeout) {
+        return m_manager.createTemporalServiceDependency(timeout);
+    }
+    
+    /**
+     * Creates a new configuration dependency.
+     * 
+     * @return the configuration dependency
+     */
+    public ConfigurationDependency createConfigurationDependency() {
+    	return m_manager.createConfigurationDependency();
+    }
+    
+    /**
+     * Creates a new configuration property metadata.
+     * 
+     * @return the configuration property metadata
+     */
+    public PropertyMetaData createPropertyMetaData() {
+        return m_manager.createPropertyMetaData();
+    }
+
+    /**
+     * Creates a new bundle dependency.
+     * 
+     * @return the bundle dependency
+     */
+    public BundleDependency createBundleDependency() {
+        return m_manager.createBundleDependency();
+    }
+
+    /**
+     * Creates a new resource dependency.
+     * 
+     * @return the resource dependency
+     */
+    public ResourceDependency createResourceDependency() {
+        return m_manager.createResourceDependency();
+    }
+
+    /**
+     * Creates a new aspect service.
+     * 
+     * @return the aspect service
+     * @see DependencyManager#createAspectService(Class, String, int, String)
+     */
+    public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String attributeName) {
+        return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, attributeName);
+    }
+    
+    /**
+     * Creates a new aspect service.
+     * 
+     * @return the aspect service
+     * @see DependencyManager#createAspectService(Class, String, int)
+     */
+    public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking) {
+        return m_manager.createAspectService(serviceInterface, serviceFilter, ranking);
+    }
+    
+    /**
+     * Creates a new aspect service.
+     * 
+     * @return the aspect service
+     * @see DependencyManager#createAspectService(Class, String, int, String, String, String)
+     */
+    public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String add, String change, String remove) {
+        return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, add, change, remove);
+    }
+
+    /**
+     * Creates a new aspect service.
+     * 
+     * @return the aspect service
+     * @see DependencyManager#createAspectService(Class, String, int, String, String, String, String)
+     */
+    public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String add, String change, String remove, String swap) {    
+        return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, add, change, remove, swap);
+    }
+    	
+    /**
+     * Creates a new adapter service.
+     * 
+     * @return the adapter service
+     * @see DependencyManager#createAdapterService(Class, String)
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter) {
+        return m_manager.createAdapterService(serviceInterface, serviceFilter);
+    }
+    
+    /**
+     * Creates a new adapter service.
+     * 
+     * @return the adapter service
+     * @see DependencyManager#createAdapterService(Class, String, String)
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String autoConfig) {
+        return m_manager.createAdapterService(serviceInterface, serviceFilter, autoConfig);
+    }
+    
+    /**
+     * Creates a new adapter service.
+     * 
+     * @return the adapter service
+     * @see DependencyManager#createAdapterService(Class, String, String, String, String)
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String add, String change, String remove) {
+        return m_manager.createAdapterService(serviceInterface, serviceFilter, add, change, remove);
+    }
+    
+    /**
+     * Creates a new adapter service.
+     * @return the adapter service
+     * @see DependencyManager#createAdapterService(Class, String, String, String, String, String)
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String add, String change, String remove, String swap) {
+        return m_manager.createAdapterService(serviceInterface, serviceFilter, add, change, remove, swap);
+    }  
+    
+    /**
+     * Creates a new adapter service.
+     * @return the adapter service
+     * @see DependencyManager#createAdapterService(Class, String, String, Object, String, String, String, String, boolean)
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, 
+        String autoConfig, Object callbackInstance, String add, String change, String remove, String swap) {
+       return m_manager.createAdapterService(serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap, true);
+    }
+
+    /**
+     * Creates a new adapter service.
+     * @return the adapter service
+     * @see DependencyManager#createAdapterService(Class, String, String, Object, String, String, String, String, boolean)
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, 
+        String autoConfig, Object callbackInstance, String add, String change, String remove, String swap, boolean propagate) {
+       return m_manager.createAdapterService(serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap, propagate);
+    }
+
+   /**
+     * Creates a new resource adapter service.
+     * 
+     * @return the resource adapter service
+     */
+    public Component createResourceAdapter(String resourceFilter, boolean propagate, Object callbackInstance, String callbackChanged) {
+        return m_manager.createResourceAdapterService(resourceFilter, propagate, callbackInstance, callbackChanged);
+    }
+
+    /**
+     * Creates a new resource adapter service.
+     * 
+     * @return the resource adapter service
+     */
+    public Component createResourceAdapter(String resourceFilter, boolean propagate, Object callbackInstance, String callbackSet, String callbackChanged) {
+        return m_manager.createResourceAdapterService(resourceFilter, propagate, callbackInstance, callbackSet, callbackChanged);
+    }
+    
+    /**
+     * Creates a new resource adapter service.
+     * 
+     * @return the resource adapter service
+     */
+    public Component createResourceAdapter(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackChanged) {
+        return m_manager.createResourceAdapterService(resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, null, callbackChanged);
+    }
+    
+    /**
+     * Creates a new resource adapter service.
+     * 
+     * @return the resource adapter service
+     */
+    public Component createResourceAdapter(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackSet, String callbackChanged) {
+        return m_manager.createResourceAdapterService(resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, callbackSet, callbackChanged);
+    }
+    
+    /**
+     * Creates a new bundle adapter service.
+     * 
+     * @return the bundle adapter service
+     */
+    public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
+        return m_manager.createBundleAdapterService(bundleStateMask, bundleFilter, propagate);
+    }
+
+    /**
+     * Creates a new factory configuration adapter service.
+     * 
+     * @return the factory configuration adapter service
+     */
+    public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate) {
+        return m_manager.createFactoryConfigurationAdapterService(factoryPid, update, propagate);
+    }
+    
+    /**
+     * Creates a new factory configuration adapter service.
+     * 
+     * @return the factory configuration adapter service
+     */
+    public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate, String heading, String desc, String localization, PropertyMetaData[] propertiesMetaData) {
+        return m_manager.createAdapterFactoryConfigurationService(factoryPid, update, propagate, heading, desc, localization, propertiesMetaData);
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java
new file mode 100644
index 0000000..336f8ae
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/DependencyManager.java
@@ -0,0 +1,707 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.dm.impl.AdapterServiceImpl;
+import org.apache.felix.dm.impl.AspectServiceImpl;
+import org.apache.felix.dm.impl.BundleAdapterImpl;
+import org.apache.felix.dm.impl.BundleDependencyImpl;
+import org.apache.felix.dm.impl.ComponentImpl;
+import org.apache.felix.dm.impl.ComponentScheduler;
+import org.apache.felix.dm.impl.ConfigurationDependencyImpl;
+import org.apache.felix.dm.impl.FactoryConfigurationAdapterImpl;
+import org.apache.felix.dm.impl.ResourceAdapterImpl;
+import org.apache.felix.dm.impl.ResourceDependencyImpl;
+import org.apache.felix.dm.impl.ServiceDependencyImpl;
+import org.apache.felix.dm.impl.TemporalServiceDependencyImpl;
+import org.apache.felix.dm.impl.index.AdapterFilterIndex;
+import org.apache.felix.dm.impl.index.AspectFilterIndex;
+import org.apache.felix.dm.impl.index.ServiceRegistryCache;
+import org.apache.felix.dm.impl.index.multiproperty.MultiPropertyFilterIndex;
+import org.apache.felix.dm.impl.metatype.PropertyMetaDataImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * The dependency manager manages all components and their dependencies. Using 
+ * this API you can declare all components and their dependencies. Under normal
+ * circumstances, you get passed an instance of this class through the
+ * <code>DependencyActivatorBase</code> subclass you use as your
+ * <code>BundleActivator</code>, but it is also possible to create your
+ * own instance.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DependencyManager {    
+    /**
+     * The DependencyManager Activator will wait for a threadpool before creating any DM components if the following
+     * OSGi system property is set to true.
+     */
+    public final static String PARALLEL = "org.apache.felix.dependencymanager.parallel";
+
+    public static final String ASPECT = "org.apache.felix.dependencymanager.aspect";
+    public static final String SERVICEREGISTRY_CACHE_INDICES = "org.apache.felix.dependencymanager.filterindex";
+    public static final String METHOD_CACHE_SIZE = "org.apache.felix.dependencymanager.methodcache";
+    
+    private final BundleContext m_context;
+    private final Logger m_logger;
+    private final ConcurrentHashMap<Component, Component> m_components = new ConcurrentHashMap<>();
+
+    // service registry cache
+    private static ServiceRegistryCache m_serviceRegistryCache;
+    private static final Set<WeakReference<DependencyManager>> m_dependencyManagers = new HashSet<>();
+    static {
+        try {
+	    	Bundle bundle = FrameworkUtil.getBundle(DependencyManager.class);
+	        if (bundle != null && bundle.getState() != Bundle.ACTIVE) {
+	            bundle.start();
+	            BundleContext bundleContext = bundle.getBundleContext();
+	            String index = bundleContext.getProperty(SERVICEREGISTRY_CACHE_INDICES);
+	            if (index != null) {
+	            	m_serviceRegistryCache = new ServiceRegistryCache(bundleContext);
+	            	m_serviceRegistryCache.open(); // TODO close it somewhere
+	            	String[] props = index.split(";");
+	            	for (int i = 0; i < props.length; i++) {
+	            		if (props[i].equals("*aspect*")) {
+	            			m_serviceRegistryCache.addFilterIndex(new AspectFilterIndex());
+	            		}
+	            		else if (props[i].equals("*adapter*")) {
+	            			m_serviceRegistryCache.addFilterIndex(new AdapterFilterIndex());
+	            		}
+	            		else {
+	            			m_serviceRegistryCache.addFilterIndex(new MultiPropertyFilterIndex(props[i]));
+	            		}
+	            	}
+	            }
+	        }
+        }
+        catch (BundleException e) {
+        	// if we cannot start ourselves, we cannot use the indices
+        	e.printStackTrace();
+        }
+    }
+
+    /**
+     * Creates a new dependency manager. You need to supply the
+     * <code>BundleContext</code> to be used by the dependency
+     * manager to register services and communicate with the 
+     * framework.
+     * 
+     * @param context the bundle context
+     */
+    public DependencyManager(BundleContext context) {
+        this(context, new Logger(context));
+    }
+
+    DependencyManager(BundleContext context, Logger logger) {
+        m_context = createContext(context);
+        m_logger = logger;
+        synchronized (m_dependencyManagers) {
+            m_dependencyManagers.add(new WeakReference<DependencyManager>(this));
+        }
+    }
+    
+    /**
+     * Returns the list of currently created dependency managers.
+     * @return the list of currently created dependency managers
+     */
+    public static List<DependencyManager> getDependencyManagers() {
+        List<DependencyManager> result = new ArrayList<>();
+        synchronized (m_dependencyManagers) {
+            Iterator<WeakReference<DependencyManager>> iterator = m_dependencyManagers.iterator();
+            while (iterator.hasNext()) {
+                WeakReference<DependencyManager> reference = iterator.next();
+                DependencyManager manager = reference.get();
+                if (manager != null) {
+                    try {
+                        manager.getBundleContext().getBundle();
+                        result.add(manager);
+                        continue;
+                    }
+                    catch (IllegalStateException e) {
+                    }
+                }
+                iterator.remove();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the bundle context associated with this dependency manager.
+     * @return the bundle context associated with this dependency manager.
+     */
+    public BundleContext getBundleContext() {
+        return m_context;
+    }
+
+    /**
+     * Adds a new component to the dependency manager. After the service is added
+     * it will be started immediately.
+     * 
+     * @param c the service to add
+     */
+    public void add(Component c) {
+        m_components.put(c, c);
+        ComponentScheduler.instance().add(c);
+    }
+
+    /**
+     * Removes a service from the dependency manager. Before the service is removed
+     * it is stopped first.
+     * 
+     * @param c the component to remove
+     */
+    public void remove(Component c) {
+        ComponentScheduler.instance().remove(c);
+        m_components.remove(c);
+    }
+
+    /**
+     * Creates a new component.
+     * 
+     * @return the new component
+     */
+    public Component createComponent() {
+        return new ComponentImpl(m_context, this, m_logger);
+    }
+
+    /**
+     * Creates a new service dependency.
+     * 
+     * @return the service dependency
+     */
+    public ServiceDependency createServiceDependency() {
+        return new ServiceDependencyImpl();
+    }
+
+    /**
+     * Creates a new configuration dependency.
+     * 
+     * @return the configuration dependency
+     */
+    public ConfigurationDependency createConfigurationDependency() {
+        return new ConfigurationDependencyImpl(m_context, m_logger);
+    }
+
+    /**
+     * Creates a new bundle dependency.
+     * 
+     * @return a new BundleDependency instance.
+     */
+    public BundleDependency createBundleDependency() {
+        return new BundleDependencyImpl();
+    }
+
+    /**
+     * Creates a new resource dependency.
+     * 
+     * @return the resource dependency
+     */
+    public ResourceDependency createResourceDependency() {
+        return new ResourceDependencyImpl();
+    }
+
+    /**
+     * Creates a new timed required service dependency. A timed dependency blocks the invoker thread is the required dependency
+     * is currently unavailable, until it comes up again. 
+     * 
+     * @return a new timed service dependency
+     */
+    public ServiceDependency createTemporalServiceDependency(long timeout) {
+        return new TemporalServiceDependencyImpl(m_context, timeout);
+    }
+
+    /**
+     * Creates a new adapter. The adapter will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an adapter will be created based on the adapter implementation class.
+     * The adapter will be registered with the specified interface and existing properties
+     * from the original service plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the adapter to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @return a service that acts as a factory for generating adapters
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter) {
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null, null, null, true);
+    }
+
+    /**
+     * Creates a new adapter. The adapter will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an adapter will be created based on the adapter implementation class.
+     * The adapter will be registered with the specified interface and existing properties
+     * from the original service plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "m_service")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the adapter to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @param autoConfig the name of the member to inject the service into
+     * @return a service that acts as a factory for generating adapters
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String autoConfig) {
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null, null, null, true);
+    }
+
+    /**
+     * Creates a new adapter. The adapter will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an adapter will be created based on the adapter implementation class.
+     * The adapter will be registered with the specified interface and existing properties
+     * from the original service plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the adapter to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @param add name of the callback method to invoke on add
+     * @param change name of the callback method to invoke on change
+     * @param remove name of the callback method to invoke on remove
+     * @return a service that acts as a factory for generating adapters
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String add, String change,
+        String remove)
+    {
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, add, change, remove, null, true);
+    }
+
+    /**
+     * Creates a new adapter. The adapter will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an adapter will be created based on the adapter implementation class.
+     * The adapter will be registered with the specified interface and existing properties
+     * from the original service plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove", "swap")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the adapter to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @param add name of the callback method to invoke on add
+     * @param change name of the callback method to invoke on change
+     * @param remove name of the callback method to invoke on remove
+     * @param swap name of the callback method to invoke on swap
+     * @return a service that acts as a factory for generating adapters
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String add, String change,
+        String remove, String swap)
+    {
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, add, change, remove, swap, true);
+    }
+
+    /**
+     * Creates a new adapter. The adapter will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an adapter will be created based on the adapter implementation class.
+     * The adapter will be registered with the specified interface (and existing properties
+     * from the original service if you set the propagate flag) plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove", "swap")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the adapter to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @param autoConfig the name of the member to inject the service into, or null.
+     * @param callbackInstance the instance to invoke the callbacks on, or null if the callbacks have to be invoked on the adapter itself
+     * @param add name of the callback method to invoke on add
+     * @param change name of the callback method to invoke on change
+     * @param remove name of the callback method to invoke on remove
+     * @param swap name of the callback method to invoke on swap
+     * @param propagate true if the adaptee service properties should be propagated to the adapter service consumers
+     * @return a service that acts as a factory for generating adapters
+     */
+    public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, 
+        String autoConfig, Object callbackInstance, String add, String change, String remove, 
+        String swap, boolean propagate)
+    {
+        return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap, propagate);
+    }
+
+    /**
+     * Creates a new Managed Service Factory Configuration Adapter. For each new Config Admin factory configuration matching
+     * the factoryPid, an adapter will be created based on the adapter implementation class.
+     * The adapter will be registered with the specified interface, and with the specified adapter service properties.
+     * Depending on the <code>propagate</code> parameter, every public factory configuration properties 
+     * (which don't start with ".") will be propagated along with the adapter service properties. 
+     * It will also inherit all dependencies.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     *  manager.createFactoryConfigurationAdapterService("MyFactoryPid",  "update", true)
+     *         // The interface to use when registering adapter
+     *         .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
+     *         // the implementation of the adapter
+     *         .setImplementation(AdapterServiceImpl.class);
+     * </pre></blockquote>
+     * 
+     * @param factoryPid the pid matching the factory configuration
+     * @param update the adapter method name that will be notified when the factory configuration is created/updated.
+     * @param propagate true if public factory configuration should be propagated to the adapter service properties
+     * @return a service that acts as a factory for generating the managed service factory configuration adapter
+     */
+    public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate) {
+        return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate);
+    }
+
+    /**
+     * Creates a new Managed Service Factory Configuration Adapter with meta type support. For each new Config Admin 
+     * factory configuration matching the factoryPid, an adapter will be created based on the adapter implementation 
+     * class. The adapter will be registered with the specified interface, and with the specified adapter service 
+     * properties. Depending on the <code>propagate</code> parameter, every public factory configuration properties 
+     * (which don't start with ".") will be propagated along with the adapter service properties. 
+     * It will also inherit all dependencies.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     *       PropertyMetaData[] propertiesMetaData = new PropertyMetaData[] {
+     *            manager.createPropertyMetaData()
+     *               .setCardinality(Integer.MAX_VALUE)
+     *               .setType(String.class)
+     *               .setHeading("English words")
+     *               .setDescription("Declare here some valid english words")
+     *               .setDefaults(new String[] {"hello", "world"})
+     *               .setId("words")
+     *       };
+     * 
+     *       manager.add(createFactoryConfigurationAdapterService("FactoryPid", 
+     *                                                            "updated",
+     *                                                            true, // propagate CM settings
+     *                                                            "EnglishDictionary",
+     *                                                            "English dictionary configuration properties",
+     *                                                            null,
+     *                                                            propertiesMetaData)
+     *               .setImplementation(Adapter.class));
+     * </pre></blockquote>
+     * 
+     * @param factoryPid the pid matching the factory configuration
+     * @param update the adapter method name that will be notified when the factory configuration is created/updated.
+     * @param propagate true if public factory configuration should be propagated to the adapter service properties
+     * @param heading The label used to display the tab name (or section) where the properties are displayed. 
+     *        Example: "Printer Service"
+     * @param desc A human readable description of the factory PID this configuration is associated with. 
+     *        Example: "Configuration for the PrinterService bundle"
+     * @param localization Points to the basename of the Properties file that can localize the Meta Type informations.
+     *        The default localization base name for the properties is OSGI-INF/l10n/bundle, but can
+     *        be overridden by the manifest Bundle-Localization header (see core specification, in section Localization 
+     *        on page 68). You can specify a specific localization basename file using this parameter 
+     *        (e.g. <code>"person"</code> will match person_du_NL.properties in the root bundle directory).
+     * @param propertiesMetaData Array of MetaData regarding configuration properties
+     * @return a service that acts as a factory for generating the managed service factory configuration adapter
+     */
+    public Component createAdapterFactoryConfigurationService(String factoryPid, String update, boolean propagate,
+        String heading, String desc, String localization, PropertyMetaData[] propertiesMetaData)
+    {
+        return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate, m_context, m_logger, heading,
+            desc, localization, propertiesMetaData);
+    }
+
+    /**
+     * Creates a new bundle adapter. The adapter will be applied to any bundle that
+     * matches the specified bundle state mask and filter condition. For each matching
+     * bundle an adapter will be created based on the adapter implementation class.
+     * The adapter will be registered with the specified interface
+     * 
+     * TODO and existing properties from the original resource plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     *  manager.createBundleAdapterService(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE, 
+     *                                     "(Bundle-SymbolicName=org.apache.felix.dependencymanager)",
+     *                                     true)
+     *         // The interface to use when registering adapter
+     *         .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
+     *         // the implementation of the adapter
+     *         .setImplementation(AdapterServiceImpl.class);
+     * </pre></blockquote>
+     * 
+     * @param bundleStateMask the bundle state mask to apply
+     * @param bundleFilter the filter to apply to the bundle manifest
+     * @param propagate <code>true</code> if properties from the bundle should be propagated to the service
+     * @return a service that acts as a factory for generating bundle adapters
+     */
+    public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
+        return new BundleAdapterImpl(this, bundleStateMask, bundleFilter, propagate);
+    }
+
+    /**
+     * Creates a new resource adapter. The adapter will be applied to any resource that
+     * matches the specified filter condition. For each matching resource
+     * an adapter will be created based on the adapter implementation class.
+     * The adapter will be registered with the specified interface and existing properties
+     * from the original resource plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     *  manager.createResourceAdapterService("(&(path=/test)(repository=TestRepository))", true)
+     *         // The interface to use when registering adapter
+     *         .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
+     *         // the implementation of the adapter
+     *         .setImplementation(AdapterServiceImpl.class);
+     * </pre></blockquote>
+     *
+     * @param resourceFilter the filter condition to use with the resource
+     * @param propagate <code>true</code> if properties from the resource should be propagated to the service
+     * @param callbackInstance instance to invoke the callback on
+     * @param callbackChanged the name of the callback method
+     * @return a service that acts as a factory for generating resource adapters
+     */
+    public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance,
+        String callbackChanged)
+    {
+        return new ResourceAdapterImpl(this, resourceFilter, propagate, callbackInstance, null, callbackChanged);
+    }
+
+    /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */
+    public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance,
+        String callbackSet, String callbackChanged)
+    {
+        return new ResourceAdapterImpl(this, resourceFilter, propagate, callbackInstance, callbackSet, callbackChanged);
+    }
+
+    /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */
+    public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance,
+        String propagateCallbackMethod, Object callbackInstance, String callbackChanged)
+    {
+        return new ResourceAdapterImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod,
+            callbackInstance, null, callbackChanged);
+    }
+
+    /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */
+    public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance,
+        String propagateCallbackMethod, Object callbackInstance, String callbackSet, String callbackChanged)
+    {
+        return new ResourceAdapterImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod,
+            callbackInstance, callbackSet, callbackChanged);
+    }
+
+    /**
+     * Returns a list of components.
+     * 
+     * @return a list of components
+     */
+    public List<Component> getComponents() {
+        return Collections.list(m_components.elements());
+    }
+
+    /**
+     * Creates a new aspect. The aspect will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an aspect will be created based on the aspect implementation class.
+     * The aspect will be registered with the same interface and properties
+     * as the original service, plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_service")
+     *     .setImplementation(ExistingServiceAspect.class)
+     * );
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the aspect to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @param ranking the level used to organize the aspect chain ordering
+     * @param autoConfig the aspect implementation field name where to inject original service. 
+     *     If null, any field matching the original service will be injected.
+     * @return a service that acts as a factory for generating aspects
+     */
+    public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String autoConfig) {
+        return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, autoConfig, null, null, null, null);
+    }
+
+    /**
+     * Creates a new aspect. The aspect will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an aspect will be created based on the aspect implementation class.
+     * The aspect will be registered with the same interface and properties
+     * as the original service, plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAspectService(ExistingService.class, "(foo=bar)", 10)
+     *     .setImplementation(ExistingServiceAspect.class)
+     * );
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the aspect to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @param ranking the level used to organize the aspect chain ordering
+     * @return a service that acts as a factory for generating aspects
+     */
+    public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking) {
+        return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, null, null, null, null);
+    }
+
+    /**
+     * Creates a new aspect. The aspect will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an aspect will be created based on the aspect implementation class.
+     * The aspect will be registered with the same interface and properties
+     * as the original service, plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
+     *     .setImplementation(ExistingServiceAspect.class)
+     * );
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the aspect to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @param ranking the level used to organize the aspect chain ordering
+     * @param add name of the callback method to invoke on add
+     * @param change name of the callback method to invoke on change
+     * @param remove name of the callback method to invoke on remove
+     * @return a service that acts as a factory for generating aspects
+     */
+    public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String add,
+        String change, String remove)
+    {
+        return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, null);
+    }
+
+    /**
+     * Creates a new aspect. The aspect will be applied to any service that
+     * matches the specified interface and filter. For each matching service
+     * an aspect will be created based on the aspect implementation class.
+     * The aspect will be registered with the same interface and properties
+     * as the original service, plus any extra properties you supply here.
+     * It will also inherit all dependencies, and if you declare the original
+     * service as a member it will be injected.
+     * 
+     * <h3>Usage Example</h3>
+     * 
+     * <blockquote><pre>
+     * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
+     *     .setImplementation(ExistingServiceAspect.class)
+     * );
+     * </pre></blockquote>
+     * 
+     * @param serviceInterface the service interface to apply the aspect to
+     * @param serviceFilter the filter condition to use with the service interface
+     * @param ranking the level used to organize the aspect chain ordering
+     * @param add name of the callback method to invoke on add
+     * @param change name of the callback method to invoke on change
+     * @param remove name of the callback method to invoke on remove
+     * @param swap name of the callback method to invoke on swap
+     * @return a service that acts as a factory for generating aspects
+     */
+    public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String add,
+        String change, String remove, String swap)
+    {
+        return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, swap);
+    }
+
+    /**
+     * Removes all components and their dependencies.
+     */
+    public void clear() {
+        for (Component component : m_components.keySet()) {
+            remove(component);
+        }
+        m_components.clear();
+    }
+
+    /**
+     * Creates a new configuration property metadata.
+     * 
+     * @return the configuration property metadata.
+     */
+    public PropertyMetaData createPropertyMetaData() {
+        return new PropertyMetaDataImpl();
+    }
+
+    private BundleContext createContext(BundleContext context) {
+        if (m_serviceRegistryCache != null) {
+            return m_serviceRegistryCache.createBundleContextInterceptor(context);
+        }
+        else {
+            return context;
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/FilterIndex.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/FilterIndex.java
new file mode 100644
index 0000000..23a4b07
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/FilterIndex.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.util.List;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A filter index is an interface you can implement to create your own, optimized index for specific filter expressions.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface FilterIndex {
+    /** Opens this filter index. */
+    public void open(BundleContext context);
+    /** Closes this filter index. */
+    public void close();
+    /** Determines if the combination of class and filter is applicable for this filter index. */
+    public boolean isApplicable(String clazz, String filter);
+    /** Returns all service references that match the specified class and filter. Never returns null. */
+    public List<ServiceReference> getAllServiceReferences(String clazz, String filter);
+    /** Invoked whenever a service event occurs. */
+    public void serviceChanged(ServiceEvent event);
+    /** Adds a service listener to this filter index. */
+    public void addServiceListener(ServiceListener listener, String filter);
+    /** Removes a service listener from this filter index. If the listener is not present in the filter index, this method does nothing. */
+    public void removeServiceListener(ServiceListener listener);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Logger.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Logger.java
new file mode 100644
index 0000000..65d6e9f
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/Logger.java
@@ -0,0 +1,310 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+/**
+ * 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, which is also why it does not
+ * actually implement <code>LogService</code>. 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 {
+	private static final String LOG_SINGLE_CONTEXT = "org.apache.felix.dependencymanager.singleContextLog";
+    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 static final String ENABLED_LOG_LEVEL = "org.apache.felix.dependencymanager.loglevel";
+    private ServiceReference m_logRef = null;
+    private Object[] m_logger = null;
+    private int m_enabledLevel = LogService.LOG_WARNING;
+    private String m_debugKey;
+
+    public Logger(BundleContext context) {
+    	if (context != null && "true".equals(context.getProperty(LOG_SINGLE_CONTEXT))) {
+    		m_context = FrameworkUtil.getBundle(DependencyManager.class).getBundleContext();
+    	} else {
+    		m_context = context;
+    	}
+		if (m_context != null) {
+		    String enabledLevel = m_context.getProperty(ENABLED_LOG_LEVEL);
+		    if (enabledLevel != null) {
+		        try {
+		            m_enabledLevel = Integer.valueOf(enabledLevel);
+		        } catch (NumberFormatException e) {}
+		    }
+		    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) {
+        if (level <= m_enabledLevel) {
+            StringBuilder sb = new StringBuilder("[");
+            if (m_debugKey != null) {
+                sb.append(m_debugKey).append(" - ");
+            }
+            sb.append(Thread.currentThread().getName());
+            sb.append("] ");
+            sb.append(msg);
+            
+            // 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, sb.toString(), throwable);
+            }
+            // Otherwise, default logging action.
+            else {
+                doLog(sr, level, sb.toString(), 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() {
+        try {
+            // add a service listener for log services, carefully avoiding any code dependency on it
+            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 != null && 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;
+            }
+        }
+    }
+
+    public void setEnabledLevel(int enabledLevel) {
+        m_enabledLevel = enabledLevel;
+    }
+    
+    public void setDebugKey(String debugKey) {
+        m_debugKey = debugKey;
+    }
+    
+    public String getDebugKey() {
+        return m_debugKey;
+    }
+
+    // --------------- Convenient helper log methods --------------------------------------------
+    
+    public void err(String format, Object... params) {
+        log(LogService.LOG_ERROR, String.format(format, params));        
+    }
+
+    public void err(String format, Throwable err, Object... params) {
+        log(LogService.LOG_ERROR, String.format(format, params), err);        
+    }
+
+    public void warn(String format, Object... params) {
+        log(LogService.LOG_WARNING, String.format(format, params));        
+    }
+
+    public void warn(String format, Throwable err, Object... params) {
+        log(LogService.LOG_WARNING, String.format(format, params), err);        
+    }
+
+    public boolean info() {
+        return m_enabledLevel >= LogService.LOG_INFO;
+    }
+
+    public void info(String format, Object... params) {
+        log(LogService.LOG_INFO, String.format(format, params));        
+    }
+
+    public void info(String format, Throwable err, Object... params) {
+        log(LogService.LOG_INFO, String.format(format, params), err);        
+    }
+
+    public boolean debug() {
+        return m_enabledLevel >= LogService.LOG_DEBUG;
+    }
+
+    public void debug(String format, Object... params) {
+        log(LogService.LOG_DEBUG, String.format(format, params));        
+    }
+
+    public void debug(String format, Throwable err, Object... params) {
+        log(LogService.LOG_DEBUG, String.format(format, params), err);        
+    }
+}
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/PropertyMetaData.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/PropertyMetaData.java
new file mode 100644
index 0000000..66a4a41
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/PropertyMetaData.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
+ * required by applicable law or agreed to in writing, software distributed under the License is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+/**
+ * This interface defines meta data regarding a given configuration property.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface PropertyMetaData {
+    /**
+     * The label used to display the property. Example: "Log Level".
+     * 
+     * @return The label used to display the property (may be localized)
+     */
+    public PropertyMetaData setHeading(String heading);
+
+    /**
+     * The key of a ConfigurationAdmin property. Example: "printer.logLevel"
+     * 
+     * @return The Configuration Admin property name
+     */
+    public PropertyMetaData setId(String id);
+
+    /**
+     * Returns the property primitive type. If must be either one of the following types:<p>
+     * <ul>
+     *    <li>String.class</li>
+     *    <li>Long.class</li>
+     *    <li>Integer.class</li>
+     *    <li>Character.class</li>
+     *    <li>Byte.class</li>
+     *    <li>Double.class</li>
+     *    <li>Float.class</li>
+     *    <li>Boolean.class</li>
+     * </ul>
+     */
+    public PropertyMetaData setType(Class<?> type);
+
+    /**
+     * Returns a default for this property. The object must be of the appropriate type as defined by the cardinality and getType(). 
+     * The return type is a list of String  objects that can be converted to the appropriate type. The cardinality of the return 
+     * array must follow the absolute cardinality of this type. E.g. if the cardinality = 0, the array must contain 1 element. 
+     * If the cardinality is 1, it must contain 0 or 1 elements. If it is -5, it must contain from 0 to max 5 elements. Note that 
+     * the special case of a 0 cardinality, meaning a single value, does not allow arrays or vectors of 0 elements. 
+     */
+    public PropertyMetaData setDefaults(String[] defaults);
+
+    /**
+     * Returns the property description. The description may be localized and must describe the semantics of this type and any 
+     * constraints. Example: "Select the log level for the Printer Service".
+     * 
+     * @return a localizable description of the property.
+     */
+    public PropertyMetaData setDescription(String description);
+
+    /**
+     * Return the cardinality of this property. The OSGi environment handles multi valued properties in arrays ([]) or in Vector objects. 
+     * The return value is defined as follows:<p>
+     *
+     * <ul>
+     * <li> x = Integer.MIN_VALUE    no limit, but use Vector</li>
+     * <li> x < 0                    -x = max occurrences, store in Vector</li>
+     * <li> x > 0                     x = max occurrences, store in array []</li>
+     * <li> x = Integer.MAX_VALUE    no limit, but use array []</li>
+     * <li> x = 0                     1 occurrence required</li>
+     * </ul>
+     */
+    public PropertyMetaData setCardinality(int cardinality);
+
+    /**
+     * Tells if this property is required or not.
+     */
+    public PropertyMetaData setRequired(boolean required);
+
+    /**
+     * Return a list of valid options for this property (the labels may be localized).
+     * 
+     * @return the list of valid options for this property.
+     */
+    public PropertyMetaData addOption(String optionLabel, String optionValue);
+}
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceDependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceDependency.java
new file mode 100644
index 0000000..d14cc19
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceDependency.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.net.URL;
+
+/**
+ * A resource dependency is a dependency on a resource. A resource in this context is an object that is
+ * identified by a URL. Resources should somehow be provided by an external component, the resource
+ * provider. These dependencies then react on them becoming available or not. Use cases for such dependencies
+ * are resources that are embedded in bundles, in a workspace or some remote or local repository, etc.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ResourceDependency extends Dependency, ComponentDependencyDeclaration, ResourceHandler {
+    /**
+     * 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 ResourceDependency setCallbacks(String added, String 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 ResourceDependency setCallbacks(String added, String changed, String 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 ResourceDependency setCallbacks(Object instance, String added, String 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 ResourceDependency setCallbacks(Object instance, String added, String changed, String removed);
+        
+    /**
+     * 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 ResourceDependency setAutoConfig(boolean autoConfig);
+    
+    /**
+     * 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 ResourceDependency setAutoConfig(String instanceName);
+
+     /**
+      * Sets the resource for this dependency.
+      * 
+      * @param resource the URL of the resource
+      */
+     public ResourceDependency setResource(URL resource);
+
+     /**
+      * Determines if this is a required dependency or not.
+      * 
+      * @param required <code>true</code> if the dependency is required
+      */
+     public ResourceDependency setRequired(boolean required);
+
+     /**
+      * Sets the filter condition for this resource dependency.
+      * 
+      * @param resourceFilter the filter condition
+      */
+     public ResourceDependency setFilter(String resourceFilter);
+
+     /** @see ResourceDependency#setPropagate(Object, String) */
+     public ResourceDependency setPropagate(boolean propagate);
+
+     /**
+      * Sets an Object instance and a callback method used to propagate some properties to the provided service properties.
+      * The method will be invoked on the specified object instance and must have one of the following signatures:<p>
+      * <ul><li>Dictionary callback(ServiceReference, Object service) 
+      * <li>Dictionary callback(ServiceReference)
+      * </ul>
+      * @param instance the Object instance which is used to retrieve propagated service properties 
+      * @param method the method to invoke for retrieving the properties to be propagated to the service properties.
+      * @return this service dependency.
+      */
+     public ResourceDependency setPropagate(Object instance, String method);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceHandler.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceHandler.java
new file mode 100644
index 0000000..5534580
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceHandler.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.net.URL;
+import java.util.Dictionary;
+
+/** 
+ * Service interface for anybody wanting to be notified of changes to resources. 
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ResourceHandler {
+    /** Name of the property that's used to describe the filter condition for a resource. */
+    public static final String FILTER = "filter";
+    /** Exact URL that this handler is looking for. Can be used instead of a filter to be very explicit about the resource you're looking for. */
+    public static final String URL = "url";
+    /** The host part of the URL. */
+    public static final String HOST = "host";
+    /** The path part of the URL. */
+    public static final String PATH = "path";
+    /** The protocol part of the URL. */
+    public static final String PROTOCOL = "protocol";
+    /** The port part of the URL. */
+    public static final String PORT = "port";
+
+    /**
+     * @deprecated Please use {@link #added(URL, Dictionary)} instead. When both are specified,
+     *     the new method takes precedence and the deprecated one is not invoked.
+     */
+    public void added(URL resource);
+    
+    /**
+     * Invoked whenever a new resource is added.
+     */
+    public void added(URL resource, Dictionary<?, ?> resourceProperties);
+    
+    /**
+     * @deprecated Please use {@link #changed(URL, Dictionary)} instead. When both are specified,
+     *     the new method takes precedence and the deprecated one is not invoked.
+     */
+    public void changed(URL resource);
+    
+    /**
+     * Invoked whenever an existing resource changes.
+     */
+    public void changed(URL resource, Dictionary<?, ?> resourceProperties);
+    
+    /**
+     * @deprecated Please use {@link #removed(URL, Dictionary)} instead. When both are specified,
+     *     the new method takes precedence and the deprecated one is not invoked.
+     */
+    public void removed(URL resource);
+    
+    /**
+     * Invoked whenever an existing resource is removed.
+     */
+    public void removed(URL resource, Dictionary<?, ?> resourceProperties);
+}
+
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceUtil.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceUtil.java
new file mode 100644
index 0000000..2112ffe
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ResourceUtil.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+/**
+ * Utility class for resource handling.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResourceUtil {
+	/**
+	 * Creates a set of properties for a resource based on its URL.
+	 * 
+	 * @param url the URL
+	 * @return a set of properties
+	 */
+    public static Dictionary<?, ?> createProperties(URL url) {
+        Hashtable<String, Object> props = new Hashtable<>();
+        props.put(ResourceHandler.PROTOCOL, url.getProtocol());
+        props.put(ResourceHandler.HOST, url.getHost());
+        props.put(ResourceHandler.PORT, Integer.toString(url.getPort()));
+        props.put(ResourceHandler.PATH, url.getPath());
+        return props;
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ServiceDependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ServiceDependency.java
new file mode 100644
index 0000000..7cda8a8
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/ServiceDependency.java
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm;
+
+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 interface ServiceDependency extends Dependency, ComponentDependencyDeclaration {
+    /**
+     * 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 add the method to call when a service was added
+     * @param remove the method to call when a service was removed
+     * @return this service dependency
+     */
+	public ServiceDependency setCallbacks(String add, String remove);
+
+    /**
+     * 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 add the method to call when a service was added
+     * @param change the method to call when a service was changed
+     * @param remove the method to call when a service was removed
+     * @return this service dependency
+     */
+	public ServiceDependency setCallbacks(String add, String change, String remove);
+
+    /**
+     * 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 add the method to call when a service was added
+     * @param change the method to call when a service was changed
+     * @param remove the method to call when a service was removed
+     * @param swap the method to call when the service was swapped due to addition or 
+     * removal of an aspect
+     * @return this service dependency
+     */
+	public ServiceDependency setCallbacks(String add, String change, String remove, String swap);
+
+    /**
+     * 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 add the method to call when a service was added
+     * @param remove the method to call when a service was removed
+     * @return this service dependency
+     */
+	public ServiceDependency setCallbacks(Object instance, String add, String remove);
+
+    /**
+     * 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 add the method to call when a service was added
+     * @param change the method to call when a service was changed
+     * @param remove the method to call when a service was removed
+     * @return this service dependency
+     */
+	public ServiceDependency setCallbacks(Object instance, String add, String change, String remove);
+
+    /**
+     * 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 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
+     * @param swapped the method to call when the service was swapped due to addition or 
+     * removal of an aspect
+     * @return this service dependency
+     */    
+	public ServiceDependency setCallbacks(Object instance, String added, String changed, String removed, String swapped);
+
+    /**
+     * Sets the required flag which determines if this service is required or not.
+     * A ServiceDependency is false by default.
+     * 
+     * @param required the required flag
+     * @return this service dependency
+     */
+	public ServiceDependency setRequired(boolean required);
+
+    /**
+     * 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. Dependency services will be injected
+     * in the following kind of fields:<p>
+     * <ul>
+     * <li> a field having the same type as the dependency. If the field may be accessed by anythread, then
+     * the field should be declared volatile, in order to ensure visibility when the field is auto injected concurrently.
+     * 
+     * <li> a field which is assignable to an <code>Iterable&#60;T&#62;</code> where T must match the dependency type. 
+     * In this case, an Iterable will be injected by DependencyManager before the start callback is called.
+     * The Iterable field may then be traversed to inspect the currently available dependency services. The Iterable 
+     * can possibly be set to a final value so you can choose the Iterable implementation of your choice
+     * (for example, a CopyOnWrite ArrayList, or a ConcurrentLinkedQueue).
+     * 
+     * <li> a <code>Map&#60;K,V&#62;</code> where K must match the dependency type and V must exactly equals <code>Dictionary</code>. 
+     * In this case, a ConcurrentHashMap will be injected by DependencyManager before the start callback is called.
+     * The Map may then be consulted to lookup current available dependency services, including the dependency service
+     * properties (the map key holds the dependency service, and the map value holds the dependency service properties).
+     * 
+     * The Map field may be set to a final value so you can choose a Map of your choice (Typically a ConcurrentHashMap).
+     * 
+     * A ConcurrentHashMap is "weakly consistent", meaning that when traversing 
+     * the elements, you may or may not see any concurrent updates made on the map. So, take care to traverse 
+     * the map using an iterator on the map entry set, which allows to atomically lookup pairs of Dependency service/Service properties.
+     * </ul> 
+     * 
+     * <p> Here are some example using an Iterable:
+     * <blockquote>
+     * 
+     * <pre>
+     * 
+     * public class SpellChecker {
+     *    // can be traversed to inspect currently available dependencies
+     *    final Iterable&#60;DictionaryService&#62; dictionaries = new ConcurrentLinkedQueue<>();
+     *    
+     *    Or
+     *    
+     *    // will be injected by DM automatically and can be traversed any time to inspect all currently available dependencies.
+     *    volatile Iterable&#60;DictionaryService&#62; dictionaries = null;
+     * }
+     * 
+     * </pre>
+     * </blockquote>
+     * 
+     * Here are some example using a Map:
+     * <blockquote>
+     * 
+     * <pre>
+     * 
+     * public class SpellChecker {
+     *    // can be traversed to inspect currently available dependencies
+     *    final Map&#60;DictionaryService, Dictionary&#62; dictionaries = new ConcurrentLinkedQueue<>();
+     *    
+     *    or
+     *    
+     *    // will be injected by DM automatically and can be traversed to inspect currently available dependencies
+     *    volatile Map&#60;DictionaryService, Dictionary&#62; dictionaries = null;
+     *
+     *    void iterateOnAvailableServices() {                 
+     *       for (Map.Entry<MyService, Dictionary> entry : this.services.entrySet()) {
+     *           MyService currentService = entry.getKey();
+     *           Dictionary currentServiceProperties = entry.getValue();
+     *           // ...
+     *       }
+     *    }
+     * }
+     * 
+     * </pre>
+     * </blockquote>
+     * 
+     * @param autoConfig the name of attribute to auto configure
+     * @return this service dependency
+     */
+	public ServiceDependency setAutoConfig(boolean autoConfig);
+
+    /**
+     * 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
+     * @see #setAutoConfig(boolean)
+     */
+	public ServiceDependency setAutoConfig(String instanceName);
+
+    /**
+     * Sets the name of the service that should be tracked. 
+     * 
+     * @param serviceName the name of the service
+     * @return this service dependency
+     */
+    public ServiceDependency setService(Class<?> serviceName);
+
+    /**
+     * 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 ServiceDependency setService(Class<?> serviceName, String serviceFilter);
+    
+    /**
+     * Sets the filter for the services that should be tracked. Any service object
+     * matching the filter will be returned, without any additional filter on the
+     * class.
+     * 
+     * @param serviceFilter the filter condition
+     * @return this service dependency
+     */
+    public ServiceDependency setService(String serviceFilter);
+    
+    /**
+     * 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 ServiceDependency setService(Class<?> serviceName, ServiceReference serviceReference);
+    
+    /**
+     * 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 ServiceDependency setDefaultImplementation(Object implementation);
+    
+    /**
+     * Sets propagation of the service dependency properties to the provided service properties. Any additional
+     * service properties specified directly are merged with these.
+     */
+    public ServiceDependency setPropagate(boolean propagate);
+    
+    /**
+     * Sets an Object instance and a callback method used to propagate some properties to the provided service properties.
+     * The method will be invoked on the specified object instance and must have one of the following signatures:<p>
+     * <ul><li>Dictionary callback(ServiceReference, Object service) 
+     * <li>Dictionary callback(ServiceReference)
+     * </ul>
+     * @param instance the Object instance which is used to retrieve propagated service properties 
+     * @param method the method to invoke for retrieving the properties to be propagated to the service properties.
+     * @return this service dependency.
+     */
+    public ServiceDependency setPropagate(Object instance, String method);
+    
+    /**
+     * Enabled debug logging for this dependency instance. The logging is prefixed with the given identifier.
+     * @param debugKey a prefix log identifier
+     * @return this service dependency.
+     */
+    public ServiceDependency setDebug(String debugKey);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/AbstractDependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/AbstractDependency.java
new file mode 100644
index 0000000..d3890bd
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/AbstractDependency.java
@@ -0,0 +1,559 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.context;
+
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.dm.ComponentDependencyDeclaration;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.ServiceDependency;
+
+/**
+ * Abstract class for implementing Dependencies.
+ * You can extends this class in order to supply your own custom dependencies to any Dependency Manager Component.
+ *
+ * @param <T> The type of the interface representing a Dependency Manager Dependency (must extends the Dependency interface).
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class AbstractDependency<T extends Dependency> implements
+    Dependency, DependencyContext, ComponentDependencyDeclaration {
+
+    /**
+     * The Component implementation is exposed to Dependencies through this interface.
+     */
+    protected ComponentContext m_component;
+
+    /**
+     * Is this Dependency available ? Volatile because the getState method (part of the 
+     * {@link ComponentDependencyDeclaration} interface) may be called by any thread, at any time.
+     */
+    protected volatile boolean m_available;
+
+    /**
+     * Is this Dependency "instance bound" ? A dependency is "instance bound" if it is defined within the component's 
+     * init method, meaning that it won't deactivate the component if it is not currently available when being added
+     * from the component's init method.
+     */
+    protected boolean m_instanceBound;
+
+    /**
+     * Is this dependency required (false by default) ?
+     */
+    protected volatile boolean m_required;
+
+    /**
+     * Component callback used to inject an added dependency.
+     */
+    protected String m_add;
+
+    /**
+     * Component callback invoked when the dependency has changed.
+     */
+    protected String m_change;
+
+    /**
+     * Component callback invoked when the dependency becomes unavailable.
+     */
+    protected String m_remove;
+
+    /**
+     * Can this Dependency be auto configured in the component instance fields ?
+     */
+    protected boolean m_autoConfig = true;
+
+    /**
+     * The Component field name where the Dependency can be injected (null means any field with a compatible type
+     * will be injected).
+     */
+    protected String m_autoConfigInstance;
+
+    /**
+     * Indicates if the setAutoConfig method has been invoked. This flag is used to force autoconfig to "false" 
+     * when the setCallbacks method is invoked, unless the setAutoConfig method has been called.
+     */
+    protected boolean m_autoConfigInvoked;
+
+    /**
+     * Has this Dependency been started by the Component implementation ? Volatile because the getState method 
+     * (part of the {@link ComponentDependencyDeclaration} interface) may be called by any thread, at any time.
+     */
+    protected volatile boolean m_isStarted;
+
+    /**
+     * The object instance on which the dependency callbacks are invoked on. Null means the dependency will be
+     * injected to the Component implementation instance(s).
+     */
+    protected Object m_callbackInstance;
+
+    /**
+     * Tells if the dependency service properties have to be propagated to the Component service properties.
+     */
+    protected boolean m_propagate;
+
+    /**
+     * The propagate callback instance that is invoked in order to supply dynamically some dependency service properties.
+     */
+    protected Object m_propagateCallbackInstance;
+
+    /**
+     * The propagate callback method that is invoked in order to supply dynamically some dependency service properties.
+     * @see {@link #m_propagateCallbackInstance}
+     */
+    protected volatile String m_propagateCallbackMethod;
+
+    /**
+     * Default empty dependency properties.
+     */
+    protected final static Dictionary<Object, Object> EMPTY_PROPERTIES = new Hashtable<>(0);
+
+    /**
+     * Creates a new Dependency. By default, the dependency is optional and autoconfig.
+     */
+    public AbstractDependency() {
+    }
+
+    /**
+     * Create a clone of a given Dependency.
+     * @param prototype all the fields of the prototype will be copied to this dependency.
+     */
+    public AbstractDependency(AbstractDependency<T> prototype) {
+        m_instanceBound = prototype.m_instanceBound;
+        m_required = prototype.m_required;
+        m_add = prototype.m_add;
+        m_change = prototype.m_change;
+        m_remove = prototype.m_remove;
+        m_autoConfig = prototype.m_autoConfig;
+        m_autoConfigInstance = prototype.m_autoConfigInstance;
+        m_autoConfigInvoked = prototype.m_autoConfigInvoked;
+        m_callbackInstance = prototype.m_callbackInstance;
+        m_propagate = prototype.m_propagate;
+        m_propagateCallbackInstance = prototype.m_propagateCallbackInstance;
+        m_propagateCallbackMethod = prototype.m_propagateCallbackMethod;
+    }
+    
+    @Override
+    public String toString() {
+        return new StringBuilder(getType()).append(" dependency [").append(getName()).append("]").toString();
+    }
+
+    // ----------------------- Dependency interface -----------------------------
+
+    /**
+     * Is this Dependency required (false by default) ?
+     */
+    @Override
+    public boolean isRequired() {
+        return m_required;
+    }
+
+    /**
+     * Is this Dependency satisfied and available ?
+     */
+    @Override
+    public boolean isAvailable() {
+        return m_available;
+    }
+
+    /**
+     * Can this dependency be injected in a component class field (by reflexion, true by default) ?
+     */
+    @Override
+    public boolean isAutoConfig() {
+        return m_autoConfig;
+    }
+
+    /**
+     * Returns the field name when the dependency can be injected to.
+     */
+    @Override
+    public String getAutoConfigName() {
+        return m_autoConfigInstance;
+    }
+
+    /**
+     * Returns the propagate callback method that is invoked in order to supply dynamically some dependency service properties.
+     * @see {@link #m_propagateCallbackInstance}
+     */
+    @Override
+    public boolean isPropagated() {
+        return m_propagate;
+    }
+
+    /**
+     * Returns the dependency service properties (empty by default).
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public <K,V> Dictionary<K, V> getProperties() {
+        return (Dictionary<K, V>) EMPTY_PROPERTIES;
+    }
+
+    // -------------- DependencyContext interface -----------------------------------------------
+
+    /**
+     * Called by the Component implementation before the Dependency can be started.
+     */
+    @Override
+    public void setComponentContext(ComponentContext component) {
+        m_component = component;
+    }
+
+    /**
+     * A Component callback must be invoked with dependency event(s).
+     * @param type the dependency event type
+     * @param events the dependency service event to inject in the component. 
+     * The number of events depends on the dependency event type: ADDED/CHANGED/REMOVED types only has one event parameter, 
+     * but the SWAPPED type has two event parameters: the first one is the old event which must be replaced by the second one.
+     */
+    @Override
+    public void invokeCallback(EventType type, Event ... events) {
+    }
+
+    /**
+     * Starts this dependency. Subclasses can override this method but must then call super.start().
+     */
+    @Override
+    public void start() {
+        m_isStarted = true;
+    }
+
+    /**
+     * Starts this dependency. Subclasses can override this method but must then call super.stop().
+     */
+    @Override
+    public void stop() {
+        m_isStarted = false;
+    }
+
+    /**
+     * Indicates if this dependency has been started by the Component implementation.
+     */
+    @Override
+    public boolean isStarted() {
+        return m_isStarted;
+    }
+
+    /**
+     * Called by the Component implementation when the dependency is considered to be available.
+     */
+    @Override
+    public void setAvailable(boolean available) {
+        m_available = available;
+    }
+
+    /**
+     * Is this Dependency "instance bound" (has been defined within the component's init method) ?
+     */
+    public boolean isInstanceBound() {
+        return m_instanceBound;
+    }
+
+    /**
+     * Called by the Component implementation when the dependency is declared within the Component's init method.
+     */
+    public void setInstanceBound(boolean instanceBound) {
+        m_instanceBound = instanceBound;
+    }
+
+    /**
+     * Tells if the Component must be first instantiated before starting this dependency (false by default).
+     */
+    @Override
+    public boolean needsInstance() {
+        return false;
+    }
+
+    /**
+     * Returns the type of the field where this dependency can be injected (auto config), or return null
+     * if autoconfig is not supported.
+     */
+    @Override
+    public abstract Class<?> getAutoConfigType();
+
+    /**
+     * Get the highest ranked available dependency service, or null.
+     */
+    @Override
+    public Event getService() {
+        Event event = m_component.getDependencyEvent(this);
+        if (event == null) {
+            Object defaultService = getDefaultService(true);
+            if (defaultService != null) {
+                event = new Event(defaultService);
+            }
+        }
+        return event;
+    }
+
+    /**
+     * Copy all dependency service instances to the given collection.
+     */
+    @Override
+    public void copyToCollection(Collection<Object> services) {
+        Set<Event> events = m_component.getDependencyEvents(this);
+        if (events.size() > 0) {
+            for (Event e : events) {
+                services.add(e.getEvent());
+            }
+        } else {
+            Object defaultService = getDefaultService(false);
+            if (defaultService != null) {
+                services.add(defaultService);
+            }
+        }
+    }
+
+    /**
+     * Copy all dependency service instances to the given map (key = dependency service, value = dependency service properties.
+     */
+    @Override
+    public void copyToMap(Map<Object, Dictionary<?, ?>> map) {
+        Set<Event> events = m_component.getDependencyEvents(this);
+        if (events.size() > 0) {
+            for (Event e : events) {
+                map.put(e.getEvent(), e.getProperties());
+            }
+        } else {
+            Object defaultService = getDefaultService(false);
+            if (defaultService != null) {
+                map.put(defaultService, EMPTY_PROPERTIES);
+            }
+        }
+    }
+
+    /**
+     * Creates a copy of this Dependency.
+     */
+    @Override
+    public abstract DependencyContext createCopy();
+
+    // -------------- ComponentDependencyDeclaration -----------------------------------------------
+
+    /**
+     * Returns a description of this dependency (like the dependency service class name with associated filters)
+     */
+    @Override
+    public String getName() {
+        return getSimpleName();
+    }
+
+    /**
+     * Returns a simple name for this dependency (like the dependency service class name).
+     */
+    @Override
+    public abstract String getSimpleName();
+
+    /**
+     * Returns the dependency symbolic type.
+     */
+    @Override
+    public abstract String getType();
+
+    /**
+     * Returns the dependency filter, if any.
+     */
+    @Override
+    public String getFilter() {
+        return null;
+    }
+
+    /**
+     * Returns this dependency state.
+     */
+    @Override
+    public int getState() { // Can be called from any threads, but our class attributes are volatile
+        if (m_isStarted) {
+            return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
+        } else {
+            return isRequired() ? ComponentDependencyDeclaration.STATE_REQUIRED
+                : ComponentDependencyDeclaration.STATE_OPTIONAL;
+        }
+    }
+
+    // -------------- Methods common to sub interfaces of Dependendency
+
+    /**
+     * Activates Dependency service properties propagation (to the service properties of the component to which this
+     * dependency is added).
+     * 
+     * @param propagate true if the dependency service properties must be propagated to the service properties of 
+     * the component to which this dependency is added. 
+     * @return this dependency instance
+     */
+    @SuppressWarnings("unchecked")
+    public T setPropagate(boolean propagate) {
+        ensureNotActive();
+        m_propagate = propagate;
+        return (T) this;
+    }
+
+    /**
+     * Sets a callback instance which can ba invoked with the given method in order to dynamically retrieve the 
+     * dependency service properties. 
+     * 
+     * @param instance the callback instance
+     * @param method the method to invoke on the callback instance
+     * @return this dependency instance
+     */
+    @SuppressWarnings("unchecked")
+    public T setPropagate(Object instance, String method) {
+        setPropagate(instance != null && method != null);
+        m_propagateCallbackInstance = instance;
+        m_propagateCallbackMethod = method;
+        return (T) this;
+    }
+
+    /**
+     * Sets the add/remove callbacks.
+     * @param add the callback to invoke when a dependency is added
+     * @param remove the callback to invoke when a dependency is removed
+     * @return this dependency instance
+     */
+    public T setCallbacks(String add, String remove) {
+        return setCallbacks(add, null, remove);
+    }
+
+    /**
+     * Sets the add/change/remove callbacks.
+     * @param add the callback to invoke when a dependency is added
+     * @param change the callback to invoke when a dependency has changed
+     * @param remove the callback to invoke when a dependency is removed
+     * @return this dependency instance
+     */
+    public T setCallbacks(String add, String change, String remove) {
+        return setCallbacks(null, add, change, remove);
+    }
+
+    /**
+     * 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 add the method to call when a service was added
+     * @param remove the method to call when a service was removed
+     * @return this service dependency
+     */
+    public T setCallbacks(Object instance, String add, String remove) {
+        return setCallbacks(instance, add, null, remove);
+    }
+
+    /**
+     * 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 add the method to call when a service was added
+     * @param change the method to call when a service was changed
+     * @param remove the method to call when a service was removed
+     * @return this service dependency
+     */
+    @SuppressWarnings("unchecked")
+    public T setCallbacks(Object instance, String add, String change, String remove) {
+        if ((add != null || change != null || remove != null) && !m_autoConfigInvoked) {
+            setAutoConfig(false);
+        }
+        m_callbackInstance = instance;
+        m_add = add;
+        m_change = change;
+        m_remove = remove;
+        return (T) this;
+    }
+
+    /**
+     * Returns the dependency callback instances
+     * @return the dependency callback instances
+     */
+    public Object[] getInstances() {
+        if (m_callbackInstance == null) {
+            return m_component.getInstances();
+        } else {
+            return new Object[] { m_callbackInstance };
+        }
+    }
+
+    /**
+     * @see {@link ServiceDependency#setRequired(boolean)}
+     */
+    @SuppressWarnings("unchecked")
+    public T setRequired(boolean required) {
+        m_required = required;
+        return (T) this;
+    }
+
+    /**
+     * @see {@link ServiceDependency#setAutoConfig(boolean)}
+     */
+    @SuppressWarnings("unchecked")
+    public T setAutoConfig(boolean autoConfig) {
+        if (autoConfig && getAutoConfigType() == null) {
+            throw new IllegalStateException("Dependency does not support auto config mode");
+        }
+        m_autoConfig = autoConfig;
+        m_autoConfigInvoked = true;
+        return (T) this;
+    }
+
+    /**
+     * @see {@link ServiceDependency#setAutoConfig(String instanceName)}
+     */
+    @SuppressWarnings("unchecked")
+    public T setAutoConfig(String instanceName) {
+        if (instanceName != null && getAutoConfigType() == null) {
+            throw new IllegalStateException("Dependency does not support auto config mode");
+        }
+        m_autoConfig = (instanceName != null);
+        m_autoConfigInstance = instanceName;
+        m_autoConfigInvoked = true;
+        return (T) this;
+    }
+
+    /**
+     * Returns the component implementation context
+     * @return the component implementation context
+     */
+    public ComponentContext getComponentContext() {
+        return m_component;
+    }
+
+    /**
+     * Returns the default service, or null.
+     * @param nullObject if true, a null object may be returned.
+     * @return the default service
+     */
+    protected Object getDefaultService(boolean nullObject) {
+        return null;
+    }
+
+    /**
+     * Checks if the component dependency is not started.
+     */
+    protected void ensureNotActive() {
+        if (isStarted()) {
+            throw new IllegalStateException("Cannot modify state while active.");
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/ComponentContext.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/ComponentContext.java
new file mode 100644
index 0000000..a62619c
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/ComponentContext.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.context;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.Logger;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This interface is the entry point to the Component implementation context.
+ * It is used by all DependencyManager Dependency implementations.
+ * 
+ * @see DependencyContext interface
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ComponentContext extends Component {
+    /**
+     * Returns the logger which can be used by the DependencyManager Dependencies implementations.
+     */
+    public Logger getLogger();
+    
+    /**
+     * Returns the Component's bundle context
+     * @return the Component's bundle context
+     */
+    public BundleContext getBundleContext();
+    
+    /**
+     * Returns the Compoent's bundle.
+     * @return the Compoent's bundle.
+     */
+    public Bundle getBundle();
+    
+    /**
+     * Sets a threadpool that the component will use when handling external events
+     * @param threadPool a threadpool used to handle component events and invoke the component's lifecycle callbacks
+     */
+    public void setThreadPool(Executor threadPool);
+    
+    /**
+     * Starts the component. All initial dependencies previously added to the component will be started.
+     */
+    public void start();
+    
+    /**
+     * Stops the component.
+     */
+    public void stop();
+    
+    /**
+     * Is this component already started ?
+     * @return true if this component has been started
+     */
+    public boolean isActive();
+    
+    /**
+     * Is this component available (all required dependencies are available) ?
+     * @return true if this component is available (all dependencies are available), or false
+     */
+    public boolean isAvailable();
+    
+    /**
+     * Notifies the Component about a dependency event.
+     * An event is for example fired when:<p>
+     * <ul>
+     * <li> a dependency service becomes available {@link EventType#ADDED}) 
+     * <li> a dependenc service has changed is changed {@link EventType#CHANGED}) 
+     * <li> a dependency service has been lost {@link EventType#REMOVED}) 
+     * <li> a dependency service has been swapped by another {@link EventType#SWAPPED}) 
+     * </ul> 
+     * @param dc the dependency
+     * @param type the dependency event type
+     * @param e the dependency event
+     * @see EventType
+     */
+    public void handleEvent(DependencyContext dc, EventType type, Event ... event);
+   
+    /**
+     * Returns the list of dependencies that has been registered on this component
+     * @return the list of dependencies that has been registered on this component
+     */
+    public List<DependencyContext> getDependencies();
+    
+    /**
+     * Invoke a component callback method with a given dependency service instance
+     * @param instances the component instances
+     * @param methodName the method name
+     * @param signatures the method signatures (types)
+     * @param parameters the method parameters
+     */
+    public void invokeCallbackMethod(Object[] instances, String methodName, Class<?>[][] signatures, Object[][] parameters);
+    
+    /**
+     * Returns the component instances
+     * @return the component instances
+     */
+    public Object[] getInstances();
+    
+    /**
+     * Returns the component instance field that is assignable to a given class type
+     * @param clazz the type of an object that has to be injected in the component instance field
+     * @return the name of the component instance field that can be assigned to an object having the same type as 
+     * the "clazz" parameter
+     */
+    public String getAutoConfigInstance(Class<?> clazz);
+    
+    /**
+     * Indicates if an object of the given class can be injected in one field of the component
+     * @param clazz the class of an object that has to be injected in one of the component fields
+     * @return true if the component can be injected with an object having the specified "clazz" type.
+     */
+    public boolean getAutoConfig(Class<?> clazz);
+    
+    /**
+     * Returns the highest ranked dependency service instance for a given dependency
+     * @param dc the dependency 
+     * @return the highest ranked dependency service instance for a given dependency
+     */
+    public Event getDependencyEvent(DependencyContext dc);
+    
+    /**
+     * Returns all the available dependency services for a given dependency
+     * @param dc the dependency 
+     * @return all the available dependency services for a given dependency
+     */
+    public Set<Event> getDependencyEvents(DependencyContext dc);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/DependencyContext.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/DependencyContext.java
new file mode 100644
index 0000000..42043e8
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/DependencyContext.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.context;
+
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Map;
+
+import org.apache.felix.dm.Dependency;
+
+/**
+ * Every DependencyManager Dependency implementations must implement this interface.
+ * 
+ * @see {@link AbstractDependency} which already implements most of the methods from this interface.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface DependencyContext extends Dependency {
+    /**
+     * Stores the Component implementation context in the Dependency Implementation. This object is the entry point to
+     * the Component implementation.
+     * @param component the Component implementation context
+     */
+    public void setComponentContext(ComponentContext component);
+    
+    /**
+     * Returns the Component implementation context associated to this Dependency context.
+     */
+    public ComponentContext getComponentContext();
+    
+    /**
+     * The Component implementation asks this dependency to invoke a component dependency callback.
+     * 
+     * @param type the type of the callback to invoke (add/change/remove/swap ...)
+     * @param events the dependency service event(s) that has previously been submitted to the component implementation using
+     * the ComponentContext.handleEvent method. The number of events depends on the event type: one event for ADDED/CHANGED/REMOVED,
+     * and two events for the SWAPPED event.
+     * @see ComponentContext#handleEvent(DependencyContext, EventType, Event...)
+     * @see EventType
+     */
+	public void invokeCallback(EventType type, Event ... events);
+			
+	/**
+	 *  Invoked by the component context when the dependency should start working. 
+	 **/
+	public void start();
+	
+	/** 
+	 * Invoked by the component context when the dependency should stop working.
+	 **/
+	public void stop();
+	
+	/**
+	 * Returns true if the dependency has been started, false if not
+	 * @return true if the dependency has been started, false if not
+	 */
+	public boolean isStarted();
+	
+	/**
+	 * Sets this dependency as available, meaning that at least one dependency service is available.
+	 * @param available true to mark this dependency as available, false to mark it as unavailable
+	 */
+	public void setAvailable(boolean available);
+		
+	/**
+     * Sets this dependency as "instance bound". A dependency is "instance bound" if it is defined from the 
+     * component's init method. 
+     * @param true if the dependency has to be marked as "intance bound", false if not.
+     */
+	public void setInstanceBound(boolean instanceBound);
+	
+	/**
+	 * Is this dependency instance bound ?
+	 * @return true if this dependency is instance bound, false if not
+	 */
+	public boolean isInstanceBound();
+
+	/** 
+	 * Does this dependency need the component instances to determine if the dependency is available or not.
+	 * @return true if the dependency need the component instances before it can be started, false if not.
+	 **/
+	public boolean needsInstance();
+	
+	/**
+	 * Returns the type of the field which can be injected with the dependency service.
+	 * @return the type of the field which can be injected with the dependency service, or null if the dependency does not 
+	 * support auto config mode.
+	 */
+    public Class<?> getAutoConfigType();
+    
+    /**
+     * Returns the highest ranked available dependency service instance, or null if the dependency is unavailable. 
+     * @return the highest ranked available dependency service instance, or null
+     */
+    public Event getService();
+    
+    /**
+     * Copies all the dependency service instances to the given collection.
+     * @param coll the collection where the dependency service instances will be copied
+     */
+    public void copyToCollection(Collection<Object> coll);
+    
+    /**
+     * Copies all the dependency service instances to the given map (key = dependency service, value = dependency servie properties).
+     * @param map the map where the dependency service instances (with the corresponding service properties)
+     */
+    public void copyToMap(Map<Object, Dictionary<?, ?>> map);
+    
+    /**
+     * Creates a clone of this dependency.
+     * @return a clone of this dependency.
+     */
+    public DependencyContext createCopy();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/Event.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/Event.java
new file mode 100644
index 0000000..1d48eaf
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/Event.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.context;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+/** 
+ * An event holds all data that belongs to some external event as it comes in via
+ * the 'changed' callback of a dependency.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Event implements Comparable<Event> {
+    protected final static Dictionary<Object, Object> EMPTY_PROPERTIES = new Hashtable<>();
+    private final Object m_event;    // the actual event object (a Service, a Bundle, a Configuration, etc ...)
+    
+    public Event(Object event) {
+        m_event = event;
+    }
+    
+    /**
+     * Returns the actual event object wrapped by this event (a Service Dependency, a Bundle for Bundle Dependency, etc...).
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T getEvent() {
+        return (T) m_event;
+    }
+    
+    /**
+     * Returns the properties of the actual event object wrapped by this event (Service Dependency properties, ...).
+     */
+    @SuppressWarnings("unchecked")
+    public <K,V> Dictionary<K,V> getProperties() {
+        return (Dictionary<K,V>) EMPTY_PROPERTIES;
+    }
+
+    @Override
+    public int hashCode() {
+        return m_event.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        // an instanceof check here is not "strong" enough with subclasses overriding the
+        // equals: we need to be sure that a.equals(b) == b.equals(a) at all times
+        if (obj != null && obj.getClass().equals(Event.class)) {
+            return (((Event) obj).m_event).equals(m_event);
+        }
+        return false;
+    }
+    
+    @Override
+    public int compareTo(Event o) {
+        return 0;
+    }
+    
+    /**
+     * Release the resources this event is holding (like service reference for example).
+     */
+    public void close() {
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/EventType.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/EventType.java
new file mode 100644
index 0000000..28f514f
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/EventType.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.context;
+
+/**
+ * Types of dependency events
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public enum EventType {
+    /**
+     * A Dependency service becomes available.
+     */
+    ADDED, 
+    
+    /**
+     * A Dependency service has changed.    
+     */
+    CHANGED, 
+    
+    /**
+     * A Dependency service becomes unavailable.
+     */
+    REMOVED,
+    
+    /**
+     * A Dependency service has been swapped by another one.
+     */
+    SWAPPED
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/packageinfo b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/packageinfo
new file mode 100644
index 0000000..6af07c8
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/context/packageinfo
@@ -0,0 +1 @@
+version 4.0.0
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AbstractDecorator.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AbstractDecorator.java
new file mode 100644
index 0000000..044166b
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AbstractDecorator.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.context.ComponentContext;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationException;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class AbstractDecorator  {
+    protected volatile DependencyManager m_manager;
+    private final Map<Object, Component> m_services = new ConcurrentHashMap<>();
+    
+    public abstract Component createService(Object[] properties);
+    
+    /**
+     * Catches our DependencyManager handle from our component init method.
+     */
+    public void init(Component c) {
+        m_manager = c.getDependencyManager();
+    }
+    
+    /**
+     * Extra method, which may be used by sub-classes, when adaptee has changed.
+     * For now, it's only used by the FactoryConfigurationAdapterImpl class, 
+     * but it might also make sense to use this for Resource Adapters ...
+     */
+    public void updateService(Object[] properties) {
+        throw new NoSuchMethodError("Method updateService not implemented");
+    }
+    
+    /**
+     * Set some service properties to all already instantiated services.
+     */
+    public void setServiceProperties(Dictionary<?,?> serviceProperties) {
+        for (Component component : m_services.values()) {
+            component.setServiceProperties(serviceProperties);
+        }
+    }
+    
+    /**
+     * Remove a StateListener from all already instantiated services.
+     */
+    public void addStateListener(ComponentStateListener listener) {
+        for (Component component : m_services.values()) {
+            component.add(listener);
+        }
+    }
+
+    /**
+     * Remove a StateListener from all already instantiated services.
+     */
+    public void removeStateListener(ComponentStateListener listener) {
+        for (Component component : m_services.values()) {
+            component.remove(listener);
+        }
+    }
+    
+    /**
+     * Add a Dependency to all already instantiated services.
+     */
+    public void addDependency(Dependency ... dependencies) {
+        for (Component component : m_services.values()) {
+            component.add(dependencies);
+        }
+    }
+    
+    /**
+     * Remove a Dependency from all instantiated services.
+     */
+    public void removeDependency(Dependency d) {
+        for (Component component : m_services.values()) {
+            component.remove(d);
+        }
+    }
+    
+    // callbacks for FactoryConfigurationAdapterImpl
+    public void updated(String pid, @SuppressWarnings("rawtypes") Dictionary properties) throws ConfigurationException {
+        try {
+            Component service = m_services.get(pid);
+            if (service == null) { 
+                service = createService(new Object[] { properties });
+                m_services.put(pid, service);
+                m_manager.add(service);
+            }
+            else {
+                updateService(new Object[] { properties, service });
+            }
+        }
+        catch (Throwable t) {
+            if (t instanceof ConfigurationException) {
+                throw (ConfigurationException) t;
+            }
+            else if (t.getCause() instanceof ConfigurationException) {
+                throw (ConfigurationException) t.getCause();
+            }
+            else {
+                throw new ConfigurationException(null, "Could not create service for ManagedServiceFactory Pid " + pid, t);
+            }
+        }
+    }
+
+    public void deleted(String pid) {
+        Component service = m_services.remove(pid);
+        if (service != null) {
+            m_manager.remove(service);
+        }
+    }
+
+    // callbacks for resources
+    public void added(URL resource) {
+        Component newService = createService(new Object[] { resource });
+        m_services.put(resource, newService);
+        m_manager.add(newService);
+    }
+
+    public void removed(URL resource) {
+        Component newService = m_services.remove(resource);
+        if (newService == null) {
+            throw new IllegalStateException("Service should not be null here.");
+        }
+        m_manager.remove(newService);
+    }
+    
+    // callbacks for services
+    public void added(ServiceReference ref, Object service) {
+        Component newService = createService(new Object[] { ref, service });
+        m_services.put(ref, newService);
+        m_manager.add(newService);
+    }
+    
+    public void removed(ServiceReference ref, Object service) {
+        Component newService;
+        newService = (Component) m_services.remove(ref);
+        if (newService == null) {
+            throw new IllegalStateException("Service should not be null here.");
+        }
+        m_manager.remove(newService);
+    }
+    
+    public void swapped(ServiceReference oldRef, Object oldService, ServiceReference newRef, Object newService) {
+        Component service = (Component) m_services.remove(oldRef);
+        if (service == null) {
+            throw new IllegalStateException("Service should not be null here.");
+        }           
+        m_services.put(newRef, service);
+    }
+    
+    // callbacks for bundles
+    public void added(Bundle bundle) {
+        Component newService = createService(new Object[] { bundle });
+        m_services.put(bundle, newService);
+        m_manager.add(newService);
+    }
+    
+    public void removed(Bundle bundle) {
+        Component newService;
+        newService = (Component) m_services.remove(bundle);
+        if (newService == null) {
+            throw new IllegalStateException("Service should not be null here.");
+        }
+        m_manager.remove(newService);
+    }
+      
+    public void stop() {
+        for (Component component : m_services.values()) {
+            m_manager.remove(component);
+        }
+    }    
+    
+    public void configureAutoConfigState(Component target, ComponentContext source) {
+        configureAutoConfigState(target, source, BundleContext.class);
+        configureAutoConfigState(target, source, ServiceRegistration.class);
+        configureAutoConfigState(target, source, DependencyManager.class);
+        configureAutoConfigState(target, source, Component.class);
+    }
+    
+    public Map<Object, Component> getServices() {
+        return m_services;
+    }
+
+    private void configureAutoConfigState(Component target, ComponentContext source, Class<?> clazz) {
+        String name = source.getAutoConfigInstance(clazz);
+        if (name != null) {
+            target.setAutoConfig(clazz, name);
+        }
+        else {
+            target.setAutoConfig(clazz, source.getAutoConfig(clazz));
+        }
+    }    
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/Activator.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/Activator.java
new file mode 100644
index 0000000..a3fa10c
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/Activator.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import org.apache.felix.dm.ComponentExecutorFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * DependencyManager Activator used to track a ComponentExecutorFactory service optionally registered by 
+ * a management agent bundle.
+ * 
+ * @see {@link ComponentExecutorFactory}
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Activator implements BundleActivator, ServiceTrackerCustomizer {
+    private BundleContext m_context;
+    
+	@Override
+	public void start(BundleContext context) throws Exception {
+		m_context = context;
+        Filter filter = context.createFilter("(objectClass=" + ComponentExecutorFactory.class.getName() + ")");
+        ServiceTracker tracker = new ServiceTracker(context, filter, this);
+        tracker.open();
+	}
+
+	@Override
+	public void stop(BundleContext context) throws Exception {
+	}
+
+	@Override
+	public Object addingService(ServiceReference reference) {
+		ComponentExecutorFactory factory = (ComponentExecutorFactory) m_context.getService(reference);
+		ComponentScheduler.instance().bind(factory);
+		return factory;
+	}
+
+	@Override
+	public void modifiedService(ServiceReference reference, Object service) {
+	}
+
+	@Override
+	public void removedService(ServiceReference reference, Object service) {
+		ComponentExecutorFactory factory = (ComponentExecutorFactory) service;
+		ComponentScheduler.instance().unbind(factory);
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java
new file mode 100644
index 0000000..6ee3264
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AdapterServiceImpl.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
+import org.apache.felix.dm.context.DependencyContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Adapter Service implementation. This class extends the FilterService in order to catch
+ * some Service methods for configuring actual adapter service implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class AdapterServiceImpl extends FilterComponent {
+    /**
+     * Creates a new Adapter Service implementation.
+     * 
+     * @param dm the dependency manager used to create our internal adapter service
+     * @param adapteeInterface the service interface to apply the adapter to
+     * @param adapteeFilter the filter condition to use with the service interface
+     * @param autoConfig the name of the member to inject the service into
+     * @param callbackInstance the instance to invoke the callback on, or null 
+     * @param add name of the callback method to invoke on add
+     * @param change name of the callback method to invoke on change
+     * @param remove name of the callback method to invoke on remove
+     * @param swap name of the callback method to invoke on swap
+     * @param propagate true if the adaptee service properties should be propagated to the adapter service consumers
+     */
+    public AdapterServiceImpl(DependencyManager dm, Class<?> adapteeInterface, String adapteeFilter, String autoConfig, 
+        Object callbackInstance, String add, String change, String remove, String swap, boolean propagate)
+    {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_component.setImplementation(new AdapterImpl(adapteeInterface, adapteeFilter, autoConfig, callbackInstance, add, 
+            change, remove, swap, propagate))
+                 .add(dm.createServiceDependency()
+                      .setService(adapteeInterface, adapteeFilter)
+                      .setAutoConfig(false)
+                      .setCallbacks("added", null, "removed", "swapped"))
+                 .setCallbacks("init", null, "stop", null);
+    }	
+	    
+    public class AdapterImpl extends AbstractDecorator {
+        private final Class<?> m_adapteeInterface;
+        private final String m_adapteeFilter;
+        private final Object m_dependencyCallbackInstance;
+        private final String m_add;
+        private final String m_change;
+        private final String m_remove;
+        private final String m_swap;
+        private final String m_autoConfig;
+        private final boolean m_propagate;
+        
+        public AdapterImpl(Class<?> adapteeInterface, String adapteeFilter, String autoConfig, Object callbackInstance, String add, 
+            String change, String remove, String swap, boolean propagate) {
+            m_adapteeInterface = adapteeInterface;
+            m_adapteeFilter = adapteeFilter;
+            m_autoConfig = autoConfig;
+            m_dependencyCallbackInstance = callbackInstance;
+            m_add = add;
+            m_change = change;
+            m_swap = swap;
+            m_remove = remove;
+            m_propagate = propagate;
+        }
+        
+        public Component createService(Object[] properties) {
+            ServiceReference ref = (ServiceReference) properties[0]; 
+            Object aspect = ref.getProperty(DependencyManager.ASPECT);            
+            String serviceIdToTrack = (aspect != null) ? aspect.toString() : ref.getProperty(Constants.SERVICE_ID).toString();
+            List<DependencyContext> dependencies = m_component.getDependencies();
+            dependencies.remove(0);
+            ServiceDependency dependency = m_manager.createServiceDependency()
+            	 // create a dependency on both the service id we're adapting and possible aspects for this given service id
+            	 .setService(m_adapteeInterface, "(|(" + Constants.SERVICE_ID + "=" + serviceIdToTrack 
+            			 	+ ")(" + DependencyManager.ASPECT + "=" + serviceIdToTrack + "))")
+                 .setRequired(true);
+            if (m_add != null || m_change != null || m_remove != null || m_swap != null) {
+                dependency.setCallbacks(m_dependencyCallbackInstance, m_add, m_change, m_remove, m_swap);
+            }
+            if (m_autoConfig != null) {
+                dependency.setAutoConfig(m_autoConfig);
+            } else {
+                // enable auto configuration if there is no add callback or if there is one on a callbackInstance
+                dependency.setAutoConfig(m_add == null || (m_add != null && m_dependencyCallbackInstance != null));
+            }
+            
+            if (m_propagate) {
+                dependency.setPropagate(this, "propagateAdapteeProperties");
+            }
+            
+//            dependency.setDebug("AdapterDependency#" + m_adapteeInterface.getSimpleName());
+
+            Component service = m_manager.createComponent()
+                .setInterface(m_serviceInterfaces, getServiceProperties(ref))
+                .setImplementation(m_serviceImpl)
+                .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
+                .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
+                .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
+                .add(dependency);
+            
+            configureAutoConfigState(service, m_component);
+            
+            for (DependencyContext dc : dependencies) {
+                service.add((Dependency) dc.createCopy());
+            }
+            
+            for (ComponentStateListener stateListener : m_stateListeners) {
+                service.add(stateListener);
+            }
+            return service;
+        }
+        
+        public String toString() {
+            return "Adapter for " + m_adapteeInterface + ((m_adapteeFilter != null) ? " with filter " + m_adapteeFilter : "");
+        }
+        
+        public Dictionary<String, Object> getServiceProperties(ServiceReference ref) {
+            Dictionary<String, Object> props = new Hashtable<>();
+            if (m_serviceProperties != null) {
+                Enumeration<String> e = m_serviceProperties.keys();
+                while (e.hasMoreElements()) {
+                    String key = e.nextElement();
+                    props.put(key, m_serviceProperties.get(key));
+                }
+            }
+            return props;
+        }
+        
+        public Dictionary<String, Object> propagateAdapteeProperties(ServiceReference ref) {
+            Dictionary<String, Object> props = new Hashtable<>();
+            String[] keys = ref.getPropertyKeys();
+            for (int i = 0; i < keys.length; i++) {
+                String key = keys[i];
+                if (key.equals(DependencyManager.ASPECT) || key.equals(Constants.SERVICE_ID) || key.equals(Constants.SERVICE_RANKING) || key.equals(Constants.OBJECTCLASS)) {
+                    // do not copy these either
+                }
+                else {
+                    props.put(key, ref.getProperty(key));
+                }
+            }
+            return props;
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AspectServiceImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AspectServiceImpl.java
new file mode 100644
index 0000000..8adbe12
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/AspectServiceImpl.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
+import org.apache.felix.dm.context.DependencyContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class AspectServiceImpl extends FilterComponent {
+	
+	private final String m_add;
+	private final String m_change;
+	private final String m_remove;
+	private final String m_swap;
+	private int m_ranking;
+
+	public AspectServiceImpl(DependencyManager dm, Class<?> aspectInterface, String aspectFilter, int ranking, String autoConfig, String add, String change, String remove, String swap) {
+		super(dm.createComponent());
+		this.m_ranking = ranking;
+		this.m_add = add;
+		this.m_change = change;
+		this.m_remove = remove;
+		this.m_swap = swap;
+		
+		m_component.setImplementation(new AspectImpl(aspectInterface, autoConfig))
+			.add(dm.createServiceDependency()
+					.setService(aspectInterface, createDependencyFilterForAspect(aspectFilter))
+					.setAutoConfig(false)
+					.setCallbacks("added", "removed"))
+					.setCallbacks("init", null, "stop", null);
+		
+//		m_component.setDebug("aspectfactory-" + m_ranking);
+	}
+	
+	private String createDependencyFilterForAspect(String aspectFilter) {
+        // we only want to match services which are not themselves aspects
+        if (aspectFilter == null || aspectFilter.length() == 0) {
+            return "(!(" + DependencyManager.ASPECT + "=*))";
+        }
+        else {
+            return "(&(!(" + DependencyManager.ASPECT + "=*))" + aspectFilter + ")";
+        }  
+	}
+	
+    private Hashtable<String, Object> getServiceProperties(ServiceReference ref) {
+        Hashtable<String, Object> props = new Hashtable<>();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            String key = keys[i];
+            if (key.equals(Constants.SERVICE_ID) || key.equals(Constants.SERVICE_RANKING) || key.equals(DependencyManager.ASPECT) || key.equals(Constants.OBJECTCLASS)) {
+                // do not copy these
+            }
+            else {
+                props.put(key, ref.getProperty(key));
+            }
+        }
+        if (m_serviceProperties != null) {
+            Enumeration<String> e = m_serviceProperties.keys();
+            while (e.hasMoreElements()) {
+                String key = e.nextElement();
+                props.put(key, m_serviceProperties.get(key));
+            }
+        }
+        // finally add our aspect property
+        props.put(DependencyManager.ASPECT, ref.getProperty(Constants.SERVICE_ID));
+        // and the ranking
+        props.put(Constants.SERVICE_RANKING, Integer.valueOf(m_ranking));
+        return props;
+    }
+    	
+	class AspectImpl extends AbstractDecorator {
+
+		private final Class<?> m_aspectInterface;
+		private final String m_autoConfig;
+
+		public AspectImpl(Class<?> aspectInterface, String autoConfig) {
+			this.m_aspectInterface = aspectInterface;
+			this.m_autoConfig = autoConfig;
+		}
+
+        /**
+         * Creates an aspect implementation component for a new original service.
+         * @param param First entry contains the ref to the original service
+         */
+		@Override
+        public Component createService(Object[] params) {
+            // Get the new original service reference.
+            ServiceReference ref = (ServiceReference) params[0];
+            List<DependencyContext> dependencies = m_component.getDependencies();
+            // remove our internal dependency, replace it with one that points to the specific service that just was passed in.
+            dependencies.remove(0);
+            Hashtable<String, Object> serviceProperties = getServiceProperties(ref);
+            String[] serviceInterfaces = getServiceInterfaces();
+            
+            ServiceDependency aspectDependency = (ServiceDependencyImpl) 
+                    m_manager.createServiceDependency().setService(m_aspectInterface, createAspectFilter(ref)).setRequired(true);
+            //aspectDependency.setDebug("aspect " + m_ranking);
+
+            aspectDependency.setCallbacks(new CallbackProxy(aspectDependency, ref), 
+                            m_add != null ? "addAspect" : null, 
+                            "changeAspect", // We have to propagate in case aspect does not have a change callback
+                            m_remove != null ? "removeAspect" : null, 
+                            m_swap != null ? "swapAspect" : null);
+            
+            if (m_autoConfig != null) {
+                aspectDependency.setAutoConfig(m_autoConfig);
+            } else if (m_add == null && m_change == null && m_remove == null && m_swap == null) {
+                // Since we have set callbacks, we must reactivate setAutoConfig because user has not specified any callbacks.
+                aspectDependency.setAutoConfig(true);
+            }
+            
+            Component service = m_manager.createComponent()
+                .setInterface(serviceInterfaces, serviceProperties)
+                .setImplementation(m_serviceImpl)
+                .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
+                .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
+                .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
+                .add(aspectDependency);
+            
+            //service.setDebug("aspectimpl-" + m_ranking);
+            
+            configureAutoConfigState(service, m_component);
+            
+            for (DependencyContext dc : dependencies) {
+                service.add((Dependency) dc.createCopy());
+            }
+
+            for (int i = 0; i < m_stateListeners.size(); i++) {
+                service.add((ComponentStateListener) m_stateListeners.get(i));
+            }
+            return service;                
+        }
+        
+        /**
+         * Modify some specific aspect service properties.
+         */
+		@Override
+        public void setServiceProperties(Dictionary<?,?> props) {
+		    for (Map.Entry<Object, Component> e : super.getServices().entrySet()) {
+		        ServiceReference originalServiceRef = (ServiceReference) e.getKey();
+                Component c = e.getValue();
+                // m_serviceProperties is already set to the new service properties; and the getServiceProperties will
+                // merge m_serviceProperties with the original service properties.
+                Dictionary<String, Object> newProps = getServiceProperties(originalServiceRef);
+                c.setServiceProperties(newProps);
+            }
+        }
+                
+        private String[] getServiceInterfaces() {
+            List<String> serviceNames = new ArrayList<>();
+            // Of course, we provide the aspect interface.
+            serviceNames.add(m_aspectInterface.getName());
+            // But also append additional aspect implementation interfaces.
+            if (m_serviceInterfaces != null) {
+                for (int i = 0; i < m_serviceInterfaces.length; i ++) {
+                    if (!m_serviceInterfaces[i].equals(m_aspectInterface.getName())) {
+                        serviceNames.add(m_serviceInterfaces[i]);
+                    }
+                }
+            }
+            return (String[]) serviceNames.toArray(new String[serviceNames.size()]);
+        }
+        
+        private String createAspectFilter(ServiceReference ref) {
+            Long sid = (Long) ref.getProperty(Constants.SERVICE_ID);
+            return "(&(|(!(" + Constants.SERVICE_RANKING + "=*))(" + Constants.SERVICE_RANKING + "<=" + (m_ranking - 1) + "))(|(" + Constants.SERVICE_ID + "=" + sid + ")(" + DependencyManager.ASPECT + "=" + sid + ")))";
+        }
+		
+        public String toString() {
+            return "Aspect for " + m_aspectInterface.getName();
+        }
+	}
+	
+    class CallbackProxy {
+        private final ServiceDependencyImpl m_aspectDependency;
+        private final ServiceReference m_originalServiceRef;
+
+        CallbackProxy(ServiceDependency aspectDependency, ServiceReference originalServiceRef) {
+            m_aspectDependency = (ServiceDependencyImpl) aspectDependency;
+            m_originalServiceRef = originalServiceRef;
+        }
+
+        @SuppressWarnings("unused")
+		private void addAspect(Component c, ServiceReference ref, Object service) {
+            // Just forward "add" service dependency callback.
+        	
+        	// Invoke is done on dependency.getInstances() which unfortunately returns this callback instance...
+        	ServiceEventImpl event = new ServiceEventImpl(ref, service);
+        	m_aspectDependency.invoke(m_add, event, m_aspectDependency.getComponentContext().getInstances());
+        }
+
+        @SuppressWarnings("unused")
+		private void changeAspect(Component c, ServiceReference ref, Object service) {
+            // Invoke "change" service dependency callback
+            if (m_change != null) {
+            	ServiceEventImpl event = new ServiceEventImpl(ref, service);
+                m_aspectDependency.invoke(m_change, event, m_aspectDependency.getComponentContext().getInstances());
+            }
+            // Propagate change to immediate higher aspect, or to client using our aspect.
+            // We always propagate our own properties, and the ones from the original service, but we don't inherit
+            // from lower ranked aspect service properties.
+            Dictionary<String, Object> props = getServiceProperties(m_originalServiceRef);
+            c.setServiceProperties(props);
+        }
+
+        @SuppressWarnings("unused")
+		private void removeAspect(Component c, ServiceReference ref, Object service) {
+            // Just forward "remove" service dependency callback.
+        	ServiceEventImpl event = new ServiceEventImpl(ref, service);
+        	m_aspectDependency.invoke(m_remove, event, m_aspectDependency.getComponentContext().getInstances());
+        }
+
+        @SuppressWarnings("unused")
+		private void swapAspect(Component c, ServiceReference prevRef, Object prev, ServiceReference currRef,
+                                Object curr) {
+        	Object[] instances = m_aspectDependency.getComponentContext().getInstances();        	        	
+            // Just forward "swap" service dependency callback.
+        	m_aspectDependency.invokeSwap(m_swap, prevRef, prev, currRef, curr, m_aspectDependency.getComponentContext().getInstances());
+        }
+        
+        @Override
+        public String toString() {
+        	return "CallbackProxy";
+        }
+    }
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
new file mode 100644
index 0000000..c883ebf
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleAdapterImpl.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.context.DependencyContext;
+import org.osgi.framework.Bundle;
+
+/**
+ * Bundle Adapter Service implementation. This class extends the FilterService in order to catch
+ * some Service methods for configuring actual adapter service implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class BundleAdapterImpl extends FilterComponent
+{
+    /**
+     * Creates a new Bundle Adapter Service implementation.
+     */
+    public BundleAdapterImpl(DependencyManager dm, int bundleStateMask, String bundleFilter, boolean propagate)
+    {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_component.setImplementation(new BundleAdapterDecorator(bundleStateMask, propagate))
+                 .add(dm.createBundleDependency()
+                      .setFilter(bundleFilter)
+                      .setStateMask(bundleStateMask)
+                      .setCallbacks("added", "removed"))
+                 .setCallbacks("init", null, "stop", null);
+    }
+
+    public class BundleAdapterDecorator extends AbstractDecorator {
+        private final boolean m_propagate;
+        private final int m_bundleStateMask;
+
+        public BundleAdapterDecorator(int bundleStateMask, boolean propagate) {
+            m_bundleStateMask = bundleStateMask;
+            m_propagate = propagate;
+        }
+        
+        public Component createService(Object[] properties) {
+            Bundle bundle = (Bundle) properties[0];
+            Hashtable<String, Object> props = new Hashtable<>();
+            if (m_serviceProperties != null) {
+                Enumeration<String> e = m_serviceProperties.keys();
+                while (e.hasMoreElements()) {
+                    String key = e.nextElement();
+                    props.put(key, m_serviceProperties.get(key));
+                }
+            }
+            List<DependencyContext> dependencies = m_component.getDependencies();
+            // the first dependency is always the dependency on the bundle, which
+            // will be replaced with a more specific dependency below
+            dependencies.remove(0);
+            Component service = m_manager.createComponent()
+                .setInterface(m_serviceInterfaces, props)
+                .setImplementation(m_serviceImpl)
+                .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
+                .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
+                .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
+                .add(m_manager.createBundleDependency()
+                    .setBundle(bundle)
+                    .setStateMask(m_bundleStateMask)
+                    .setPropagate(m_propagate)
+                    .setCallbacks(null, "changed", null)
+                    .setAutoConfig(true)
+                    .setRequired(true));
+
+            for (DependencyContext dc : dependencies) {
+                service.add((Dependency) dc.createCopy());
+            }
+
+            for (ComponentStateListener stateListener : m_stateListeners) {
+                service.add(stateListener);
+            }
+            configureAutoConfigState(service, m_component);
+            return service;
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleDependencyImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleDependencyImpl.java
new file mode 100644
index 0000000..6e5dbd1
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleDependencyImpl.java
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.util.Dictionary;
+
+import org.apache.felix.dm.BundleDependency;
+import org.apache.felix.dm.ComponentDependencyDeclaration;
+import org.apache.felix.dm.context.AbstractDependency;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.context.Event;
+import org.apache.felix.dm.context.EventType;
+import org.apache.felix.dm.tracker.BundleTracker;
+import org.apache.felix.dm.tracker.BundleTrackerCustomizer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class BundleDependencyImpl extends AbstractDependency<BundleDependency> implements BundleDependency, BundleTrackerCustomizer, ComponentDependencyDeclaration {
+    private BundleTracker m_tracker;
+    private int m_stateMask = Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE;
+    private Bundle m_bundleInstance;
+    private Filter m_filter;
+    private long m_bundleId = -1;
+    private Object m_nullObject;
+    private boolean m_propagate;
+    private Object m_propagateCallbackInstance;
+    private String m_propagateCallbackMethod;
+
+    public BundleDependencyImpl() {
+    }
+    
+    public BundleDependencyImpl(BundleDependencyImpl prototype) {
+        super(prototype);
+        m_stateMask = prototype.m_stateMask;
+        m_nullObject = prototype.m_nullObject;
+        m_bundleInstance = prototype.m_bundleInstance;
+        m_filter = prototype.m_filter;
+        m_bundleId = prototype.m_bundleId;
+        m_propagate = prototype.m_propagate;
+        m_propagateCallbackInstance = prototype.m_propagateCallbackInstance;
+        m_propagateCallbackMethod = prototype.m_propagateCallbackMethod;       
+    }
+    
+    @Override
+    public DependencyContext createCopy() {
+        return new BundleDependencyImpl(this);
+    }
+    
+    @Override
+    public void start() {
+        m_tracker = new BundleTracker(m_component.getBundleContext(), m_stateMask, this);
+        m_tracker.open();
+        super.start();
+    }
+
+    @Override
+    public void stop() {
+        m_tracker.close();
+        m_tracker = null;
+        super.stop();
+    }
+    
+    @Override
+    public String getName() {
+        StringBuilder sb = new StringBuilder();
+        getSimpleName(sb);
+        if (m_filter != null) {
+            sb.append(" ");
+            sb.append(m_filter.toString());
+        }
+        if (m_bundleId != -1) {
+            sb.append("{bundle.id=" + m_bundleId + "}");
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String getSimpleName() {
+        // Return the state mask, but don't include the filter or bundle id.
+        StringBuilder sb = new StringBuilder();
+        if ((m_stateMask & Bundle.ACTIVE) != 0) {
+            sb.append("active");
+        }
+        if ((m_stateMask & Bundle.INSTALLED) != 0) {
+            if (sb.length() > 0) {
+                sb.append(" ");
+            }
+            sb.append("installed");
+        }
+        if ((m_stateMask & Bundle.RESOLVED) != 0) {
+            if (sb.length() > 0) {
+                sb.append(" ");
+            }
+            sb.append("resolved");
+        }
+        return sb.toString();
+    }
+    
+    @Override
+    public String getFilter() {
+        if (m_filter != null || m_bundleId != -1) {
+            StringBuilder sb = new StringBuilder();
+            if (m_filter != null) {
+                sb.append(m_filter.toString());
+            }
+            if (m_bundleId != -1) {
+                sb.append("{bundle.id=" + m_bundleId + "}");
+            }
+            return sb.toString();
+        }
+        return null;
+    }
+
+    @Override
+    public String getType() {
+        return "bundle";
+    }
+
+    public Object addingBundle(Bundle bundle, BundleEvent event) {
+        // if we don't like a bundle, we could reject it here by returning null
+        long bundleId = bundle.getBundleId();
+        if (m_bundleId >= 0 && m_bundleId != bundleId) {
+            return null;
+        }
+        Filter filter = m_filter;
+        if (filter != null) {
+            Dictionary<?,?> headers = bundle.getHeaders();
+            if (!m_filter.match(headers)) {
+                return null;
+            }
+        }
+        return bundle;
+    }
+    
+    public void addedBundle(Bundle bundle, BundleEvent event, Object object) {
+        m_component.handleEvent(this, EventType.ADDED, new BundleEventImpl(bundle, event));
+    }
+        
+    public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+        m_component.handleEvent(this, EventType.CHANGED, new BundleEventImpl(bundle, event));
+    }
+
+    public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+        m_component.handleEvent(this, EventType.REMOVED, new BundleEventImpl(bundle, event));
+    }
+    
+    @Override
+    public void invokeCallback(EventType type, Event ... e) {
+        switch (type) {
+        case ADDED:
+            if (m_add != null) {
+                invoke(m_add, e[0]);
+            }
+            break;
+        case CHANGED:
+            if (m_change != null) {
+                invoke (m_change, e[0]);
+            }
+            break;
+        case REMOVED:
+            if (m_remove != null) {
+                invoke (m_remove, e[0]);
+            }
+            break;
+        default:
+            break;
+        }
+    }
+            
+    private void invoke(String method, Event e) {
+        BundleEventImpl be = (BundleEventImpl) e;
+        m_component.invokeCallbackMethod(getInstances(), method,
+            new Class[][] {{Bundle.class}, {Object.class}, {}},             
+            new Object[][] {{be.getBundle()}, {be.getBundle()}, {}});
+    }
+    
+    public BundleDependency setBundle(Bundle bundle) {
+        m_bundleId = bundle.getBundleId();
+        return this;
+    }
+
+    public BundleDependency setFilter(String filter) throws IllegalArgumentException {
+        if (filter != null) {
+            try {
+                m_filter = FrameworkUtil.createFilter(filter);
+            } 
+            catch (InvalidSyntaxException e) {
+                throw new IllegalArgumentException(e.getMessage());
+            }
+        }
+        return this;
+    }
+    
+    public BundleDependency setStateMask(int mask) {
+        m_stateMask = mask;
+        return this;
+    }
+    
+    @Override
+    public Class<?> getAutoConfigType() {
+        return Bundle.class;
+    }
+        
+    @SuppressWarnings("unchecked")
+    @Override
+    public Dictionary<String, Object> getProperties() {
+        Event event = getService();
+        if (event != null) {
+            Bundle bundle = (Bundle) event.getEvent();
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary<String, Object>) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod, new Class[][] {{ Bundle.class }}, new Object[][] {{ bundle }});
+                }
+                catch (InvocationTargetException e) {
+                    m_component.getLogger().warn("Exception while invoking callback method", e.getCause());
+                }
+                catch (Throwable e) {
+                    m_component.getLogger().warn("Exception while trying to invoke callback method", e);
+                }
+                throw new IllegalStateException("Could not invoke callback");
+            }
+            else {
+                return (Dictionary<String, Object>) bundle.getHeaders();
+            }
+        }
+        else {
+            throw new IllegalStateException("cannot find bundle");
+        }
+    }
+    
+    @Override
+    public Object getDefaultService(boolean nullObject) {
+        Object service = null;
+        if (isAutoConfig()) {
+            // TODO does it make sense to add support for custom bundle impls?
+            // service = getDefaultImplementation();
+            if (service == null && nullObject) {
+                service = getNullObject();
+            }
+        }
+        return service;
+    }
+
+    private Bundle getNullObject() {
+        if (m_nullObject == null) {
+            try {
+                m_nullObject = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Bundle.class }, new DefaultNullObject()); 
+            }
+            catch (Throwable e) {
+                m_component.getLogger().err("Could not create null object for Bundle.", e);
+            }
+        }
+        return (Bundle) m_nullObject;
+    }
+    
+    private void getSimpleName(StringBuilder sb) {
+        if ((m_stateMask & Bundle.ACTIVE) != 0) {
+            sb.append("active");
+        }
+        if ((m_stateMask & Bundle.INSTALLED) != 0) {
+            if (sb.length() > 0) {
+                sb.append(" ");
+            }
+            sb.append("installed");
+        }
+        if ((m_stateMask & Bundle.RESOLVED) != 0) {
+            if (sb.length() > 0) {
+                sb.append(" ");
+            }
+            sb.append("resolved");
+        }
+    }
+}
+
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleEventImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleEventImpl.java
new file mode 100644
index 0000000..187165f
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/BundleEventImpl.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.Dictionary;
+
+import org.apache.felix.dm.context.Event;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class BundleEventImpl extends Event {
+    final BundleEvent m_event;
+    
+    public BundleEventImpl(Bundle bundle, BundleEvent event) {
+        super(bundle);
+        m_event = event;
+    }
+        
+    public Bundle getBundle() {
+        return getEvent();
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public Dictionary<String, Object> getProperties() {
+        return getBundle().getHeaders();
+    }
+    
+    public BundleEvent getBundleEvent() {
+        return m_event;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof BundleEventImpl) {
+            return getBundle().getBundleId() == ((BundleEventImpl) obj).getBundle().getBundleId();
+        }
+        return false;
+    }
+    
+    @Override
+    public int hashCode() {
+        return getBundle().hashCode();
+    }
+
+    @Override
+    public int compareTo(Event b) {
+        return Long.compare(getBundle().getBundleId(), ((BundleEventImpl) b).getBundle().getBundleId());
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
new file mode 100644
index 0000000..f08d4c1
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentImpl.java
@@ -0,0 +1,1345 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import static org.apache.felix.dm.ComponentState.INACTIVE;
+import static org.apache.felix.dm.ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED;
+import static org.apache.felix.dm.ComponentState.TRACKING_OPTIONAL;
+import static org.apache.felix.dm.ComponentState.WAITING_FOR_REQUIRED;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentDeclaration;
+import org.apache.felix.dm.ComponentDependencyDeclaration;
+import org.apache.felix.dm.ComponentState;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.Logger;
+import org.apache.felix.dm.context.ComponentContext;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.context.EventType;
+import org.apache.felix.dm.context.Event;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+
+/**
+ * Dependency Manager Component implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ComponentImpl implements Component, ComponentContext, ComponentDeclaration {
+	private static final ServiceRegistration NULL_REGISTRATION = (ServiceRegistration) Proxy
+			.newProxyInstance(ComponentImpl.class.getClassLoader(),
+					new Class[] { ServiceRegistration.class },
+					new DefaultNullObject());
+    private static final Class<?>[] VOID = new Class[] {};
+	private volatile Executor m_executor = new SerialExecutor(new Logger(null));
+	private ComponentState m_state = ComponentState.INACTIVE;
+	private final CopyOnWriteArrayList<DependencyContext> m_dependencies = new CopyOnWriteArrayList<>();
+	private final List<ComponentStateListener> m_listeners = new CopyOnWriteArrayList<>();
+	private boolean m_isStarted;
+    private final Logger m_logger;
+    private final BundleContext m_context;
+    private final DependencyManager m_manager;
+    private Object m_componentDefinition;
+	private Object m_componentInstance;
+    private volatile Object m_serviceName;
+    private volatile Dictionary<Object, Object> m_serviceProperties;
+    private volatile ServiceRegistration m_registration;
+    private final Map<Class<?>, Boolean> m_autoConfig = new ConcurrentHashMap<>();
+    private final Map<Class<?>, String> m_autoConfigInstance = new ConcurrentHashMap<>();
+    private final Map<String, Long> m_stopwatch = new ConcurrentHashMap<>();
+    private final long m_id;
+    private static AtomicLong m_idGenerator = new AtomicLong();
+    // Holds all the services of a given dependency context. Caution: the last entry in the skiplist is the highest ranked service.
+    private final Map<DependencyContext, ConcurrentSkipListSet<Event>> m_dependencyEvents = new HashMap<>();
+    private final AtomicBoolean m_active = new AtomicBoolean(false);
+        
+    public Component setDebug(String debugKey) {
+    	// Force debug level in our logger
+        m_logger.setEnabledLevel(LogService.LOG_DEBUG);
+        m_logger.setDebugKey(debugKey);
+    	return this;
+    }
+
+    // configuration (static)
+    private volatile String m_callbackInit;
+    private volatile String m_callbackStart;
+    private volatile String m_callbackStop;
+    private volatile String m_callbackDestroy;
+    private volatile Object m_callbackInstance;
+    
+    // instance factory
+	private volatile Object m_instanceFactory;
+	private volatile String m_instanceFactoryCreateMethod;
+	
+	// composition manager
+	private volatile Object m_compositionManager;
+	private volatile String m_compositionManagerGetMethod;
+	private volatile Object m_compositionManagerInstance;
+    private final Bundle m_bundle;
+	
+    static class SCDImpl implements ComponentDependencyDeclaration {
+        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 String getSimpleName() {
+            return m_name;
+        }
+        
+        public String getFilter() {
+            return null;
+        }
+
+        public int getState() {
+            return m_state;
+        }
+
+        public String getType() {
+            return m_type;
+        }
+    }
+
+    public ComponentImpl() {
+	    this(null, null, new Logger(null));
+	}
+	
+    public ComponentImpl(BundleContext context, DependencyManager manager, Logger logger) {
+        m_context = context;
+        m_bundle = context != null ? context.getBundle() : null;
+        m_manager = manager;
+        m_logger = logger;
+        m_autoConfig.put(BundleContext.class, Boolean.TRUE);
+        m_autoConfig.put(ServiceRegistration.class, Boolean.TRUE);
+        m_autoConfig.put(DependencyManager.class, Boolean.TRUE);
+        m_autoConfig.put(Component.class, Boolean.TRUE);
+        m_callbackInit = "init";
+        m_callbackStart = "start";
+        m_callbackStop = "stop";
+        m_callbackDestroy = "destroy";
+        m_id = m_idGenerator.getAndIncrement();
+    }
+
+	@Override
+	public Component add(final Dependency ... dependencies) {
+		getExecutor().execute(new Runnable() {
+			@Override
+			public void run() {
+				List<DependencyContext> instanceBoundDeps = new ArrayList<>();
+				for (Dependency d : dependencies) {
+					DependencyContext dc = (DependencyContext) d;
+					if (dc.getComponentContext() != null) {
+                        m_logger.err("%s can't be added to %s (dependency already added to another component).", dc,
+                            ComponentImpl.this);
+                        continue;
+					}
+					m_dependencyEvents.put(dc,  new ConcurrentSkipListSet<Event>());
+					m_dependencies.add(dc);
+					dc.setComponentContext(ComponentImpl.this);
+					if (!(m_state == ComponentState.INACTIVE)) {
+						dc.setInstanceBound(true);
+						instanceBoundDeps.add(dc);
+					}
+				}
+				startDependencies(instanceBoundDeps);
+				handleChange();
+			}
+		});
+		return this;
+	}
+
+	@Override
+	public Component remove(final Dependency d) {
+		getExecutor().execute(new Runnable() {
+			@Override
+			public void run() {
+				DependencyContext dc = (DependencyContext) d;
+				// First remove this dependency from the dependency list
+                m_dependencies.remove(d);
+                // Now we can stop the dependency (our component won't be deactivated, it will only be unbound with
+                // the removed dependency).
+				if (!(m_state == ComponentState.INACTIVE)) {
+					dc.stop();
+				}
+				// Finally, cleanup the dependency events.
+                m_dependencyEvents.remove(d);
+				handleChange();
+			}
+		});
+		return this;
+	}
+
+	public void start() {
+	    if (m_active.compareAndSet(false, true)) {
+            getExecutor().execute(new Runnable() {
+                @Override
+                public void run() {
+                    m_isStarted = true;
+                    handleChange();
+                }
+            });
+	    }
+	}
+	
+	public void stop() {           
+	    if (m_active.compareAndSet(true, false)) {
+	        Executor executor = getExecutor();
+
+	        // First, declare the task that will stop our component in our executor.
+	        final Runnable stopTask = new Runnable() {
+                @Override
+                public void run() {
+                	m_isStarted = false;
+                	handleChange();
+                }
+            };
+            
+            // Now, we have to schedule our stopTask in our component executor. But we have to handle a special case:
+            // if the component bundle is stopping *AND* if the executor is a parallel dispatcher, then we want 
+            // to invoke our stopTask synchronously, in order to make sure that the bundle context is valid while our 
+            // component is being deactivated (if we stop the component asynchronously, the bundle context may be invalidated
+            // before our component is stopped, and we don't want to be in this situation).
+            
+            boolean stopping = m_bundle != null /* null only in tests env */ && m_bundle.getState() == Bundle.STOPPING;
+            if (stopping && executor instanceof DispatchExecutor) {
+            	((DispatchExecutor) executor).execute(stopTask, false /* try to  execute synchronously, not using threadpool */);
+            } else {
+            	executor.execute(stopTask);
+            }
+	    }
+	}
+
+	@SuppressWarnings("unchecked")
+    @Override
+	public Component setInterface(String serviceName, Dictionary<?, ?> properties) {
+		ensureNotActive();
+	    m_serviceName = serviceName;
+	    m_serviceProperties = (Dictionary<Object, Object>) properties;
+	    return this;
+	}
+
+	@SuppressWarnings("unchecked")
+    @Override
+	public Component setInterface(String[] serviceName, Dictionary<?, ?> properties) {
+	    ensureNotActive();
+	    m_serviceName = serviceName;
+	    m_serviceProperties = (Dictionary<Object, Object>) properties;
+	    return this;
+	}
+	
+	@Override
+    public void handleEvent(final DependencyContext dc, final EventType type, final Event... event) {
+        // since this method can be invoked by anyone from any thread, we need to
+        // pass on the event to a runnable that we execute using the component's
+        // executor
+        getExecutor().execute(new Runnable() {
+            @Override
+            public void run() {
+                switch (type) {
+                case ADDED:
+                    handleAdded(dc, event[0]);
+                    break;
+                case CHANGED:
+                    handleChanged(dc, event[0]);
+                    break;
+                case REMOVED:
+                    handleRemoved(dc, event[0]);
+                    break;
+                case SWAPPED:
+                    handleSwapped(dc, event[0], event[1]);
+                    break;
+                }
+            }
+        });
+	}
+
+    @Override
+    public Event getDependencyEvent(DependencyContext dc) {
+        ConcurrentSkipListSet<Event> events = m_dependencyEvents.get(dc);
+        return events.size() > 0 ? events.last() : null;
+    }
+    
+    @Override
+    public Set<Event> getDependencyEvents(DependencyContext dc) {
+        return m_dependencyEvents.get(dc);
+    }
+
+    public Component setAutoConfig(Class<?> clazz, boolean autoConfig) {
+        m_autoConfig.put(clazz, Boolean.valueOf(autoConfig));
+        return this;
+    }
+    
+    public Component setAutoConfig(Class<?> clazz, String instanceName) {
+        m_autoConfig.put(clazz, Boolean.valueOf(instanceName != null));
+        m_autoConfigInstance.put(clazz, instanceName);
+        return this;
+    }
+    
+    public boolean getAutoConfig(Class<?> clazz) {
+        Boolean result = (Boolean) m_autoConfig.get(clazz);
+        return (result != null && result.booleanValue());
+    }
+    
+    public String getAutoConfigInstance(Class<?> clazz) {
+        return (String) m_autoConfigInstance.get(clazz);
+    }
+
+    private void handleAdded(DependencyContext dc, Event e) {
+        if (! m_isStarted) {
+            return;
+        }
+        m_logger.debug("handleAdded %s", e);
+        
+        Set<Event> dependencyEvents = m_dependencyEvents.get(dc);
+        dependencyEvents.add(e);        
+        dc.setAvailable(true);
+        
+        // Recalculate state changes. We only do this if the dependency is started. If the dependency is not started,
+        // it means it is actually starting. And in this case, we don't recalculate state changes now. We'll do it 
+        // once all currently available services are found, and then after, we'll recalculate state change 
+        // (see the startDependencies method).
+        // All this is done for two reasons:
+        // 1- optimization: it is preferable to recalculate state changes once we know about all currently available dependency services
+        //    (after the tracker has returned from its open method).
+        // 2- This also allows to determine the list of currently available dependency services from within the component start method callback
+        //    (this will be extremely useful when porting the Felix SCR on top of DM4).
+        
+        if (dc.isStarted()) {
+            switch (m_state) {
+            case WAITING_FOR_REQUIRED:
+                if (dc.isRequired())
+                    handleChange();
+                break;
+            case INSTANTIATED_AND_WAITING_FOR_REQUIRED:
+                if (!dc.isInstanceBound()) {
+                    if (dc.isRequired()) {
+                        dc.invokeCallback(EventType.ADDED, e);
+                    }
+                    updateInstance(dc, e, false, true);
+                }
+                else {
+                    if (dc.isRequired())
+                        handleChange();
+                }
+                break;
+            case TRACKING_OPTIONAL:
+                dc.invokeCallback(EventType.ADDED, e);
+                updateInstance(dc, e, false, true);
+                break;
+            default:
+            }
+        }
+    }
+        
+    private void handleChanged(final DependencyContext dc, final Event e) {
+        if (! m_isStarted) {
+            return;
+        }
+        Set<Event> dependencyEvents = m_dependencyEvents.get(dc);
+        dependencyEvents.remove(e);
+        dependencyEvents.add(e);
+        
+        if (dc.isStarted()) {
+            switch (m_state) {
+            case TRACKING_OPTIONAL:
+                dc.invokeCallback(EventType.CHANGED, e);
+                updateInstance(dc, e, true, false);
+                break;
+
+            case INSTANTIATED_AND_WAITING_FOR_REQUIRED:
+                if (!dc.isInstanceBound()) {
+                    dc.invokeCallback(EventType.CHANGED, e);
+                    updateInstance(dc, e, true, false);
+                }
+                break;
+            default:
+                // noop
+            }
+        }
+    }
+    
+    private void handleRemoved(DependencyContext dc, Event e) {
+        if (! m_isStarted) {
+            return;
+        }
+        // Check if the dependency is still available.
+        Set<Event> dependencyEvents = m_dependencyEvents.get(dc);
+        int size = dependencyEvents.size();
+        if (dependencyEvents.contains(e)) {
+            size--; // the dependency is currently registered and is about to be removed.
+        }
+        dc.setAvailable(size > 0);
+        
+        // If the dependency is now unavailable, we have to recalculate state change. This will result in invoking the
+        // "removed" callback with the removed dependency (which we have not yet removed from our dependency events list.).
+        // But we don't recalculate the state if the dependency is not started (if not started, it means that it is currently starting,
+        // and the tracker is detecting a removed service).
+        if (size == 0 && dc.isStarted()) {
+            handleChange();
+        }
+        
+        // Now, really remove the dependency event.
+        dependencyEvents.remove(e);    
+        
+        // Only check if the component instance has to be updated if the dependency is really started.
+        if (dc.isStarted()) {
+            // Depending on the state, we possible have to invoke the callbacks and update the component instance.        
+            switch (m_state) {
+            case INSTANTIATED_AND_WAITING_FOR_REQUIRED:
+                if (!dc.isInstanceBound()) {
+                    if (dc.isRequired()) {
+                        dc.invokeCallback(EventType.REMOVED, e);
+                    }
+                    updateInstance(dc, e, false, false);
+                }
+                break;
+            case TRACKING_OPTIONAL:
+                dc.invokeCallback(EventType.REMOVED, e);
+                updateInstance(dc, e, false, false);
+                break;
+            default:
+            }
+        }
+    }
+    
+    private void handleSwapped(DependencyContext dc, Event oldEvent, Event newEvent) {
+        if (! m_isStarted) {
+            return;
+        }
+        Set<Event> dependencyEvents = m_dependencyEvents.get(dc);        
+        dependencyEvents.remove(oldEvent);
+        dependencyEvents.add(newEvent);
+                
+        if (dc.isStarted()) {
+            // Depending on the state, we possible have to invoke the callbacks and update the component instance.        
+            switch (m_state) {
+            case WAITING_FOR_REQUIRED:
+                // No need to swap, we don't have yet injected anything
+                break;
+            case INSTANTIATED_AND_WAITING_FOR_REQUIRED:
+                // Only swap *non* instance-bound dependencies
+                if (!dc.isInstanceBound()) {
+                    if (dc.isRequired()) {
+                        dc.invokeCallback(EventType.SWAPPED, oldEvent, newEvent); 
+                    }
+                }
+                break;
+            case TRACKING_OPTIONAL:
+                dc.invokeCallback(EventType.SWAPPED, oldEvent, newEvent);
+                break;
+            default:
+            }
+        }
+    }
+    
+	private void handleChange() {
+	    m_logger.debug("handleChanged");
+		try {
+			ComponentState oldState;
+			ComponentState newState;
+			do {
+				oldState = m_state;
+				newState = calculateNewState(oldState);
+				m_logger.debug("%s -> %s", oldState, newState);
+				m_state = newState;
+			} while (performTransition(oldState, newState));
+		} finally {
+		    m_logger.debug("end handling change.");
+		}
+	}
+    
+	/** Based on the current state, calculate the new state. */
+	private ComponentState calculateNewState(ComponentState currentState) {
+		if (currentState == INACTIVE) {
+			if (m_isStarted) {
+				return WAITING_FOR_REQUIRED;
+			}
+		}
+		if (currentState == WAITING_FOR_REQUIRED) {
+			if (!m_isStarted) {
+				return INACTIVE;
+			}
+			if (allRequiredAvailable()) {
+				return INSTANTIATED_AND_WAITING_FOR_REQUIRED;
+			}
+		}
+		if (currentState == INSTANTIATED_AND_WAITING_FOR_REQUIRED) {
+			if (m_isStarted && allRequiredAvailable()) {
+				if (allInstanceBoundAvailable()) {
+					return TRACKING_OPTIONAL;
+				}
+				return currentState;
+			}
+			return WAITING_FOR_REQUIRED;
+		}
+		if (currentState == TRACKING_OPTIONAL) {
+			if (m_isStarted && allRequiredAvailable() && allInstanceBoundAvailable()) {
+				return currentState;
+			}
+			return INSTANTIATED_AND_WAITING_FOR_REQUIRED;
+		}
+		return currentState;
+	}
+
+	/** Perform all the actions associated with state transitions. Returns true if a transition was performed. */
+	private boolean performTransition(ComponentState oldState, ComponentState newState) {
+//		System.out.println("transition from " + oldState + " to " + newState);
+		if (oldState == ComponentState.INACTIVE && newState == ComponentState.WAITING_FOR_REQUIRED) {
+		    startDependencies(m_dependencies);
+			notifyListeners(newState);
+			return true;
+		}
+		if (oldState == ComponentState.WAITING_FOR_REQUIRED && newState == ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED) {
+			instantiateComponent();
+            invokeAutoConfigDependencies();
+			invokeAddRequiredDependencies();
+			ComponentState stateBeforeCallingInit = m_state;
+	        invoke(m_callbackInit); 
+	        if (stateBeforeCallingInit == m_state) {
+	            notifyListeners(newState); // init did not change current state, we can notify about this new state
+	        }
+			return true;
+		}
+		if (oldState == ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED && newState == ComponentState.TRACKING_OPTIONAL) {
+            invokeAutoConfigInstanceBoundDependencies();
+			invokeAddRequiredInstanceBoundDependencies();
+			invoke(m_callbackStart);
+			invokeAddOptionalDependencies();
+			registerService();
+			notifyListeners(newState);
+			return true;
+		}
+		if (oldState == ComponentState.TRACKING_OPTIONAL && newState == ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED) {
+		    unregisterService();
+		    invokeRemoveOptionalDependencies();
+			invoke(m_callbackStop);
+			invokeRemoveInstanceBoundDependencies();
+			notifyListeners(newState);
+			return true;
+		}
+		if (oldState == ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED && newState == ComponentState.WAITING_FOR_REQUIRED) {
+			invoke(m_callbackDestroy);
+			invokeRemoveRequiredDependencies();
+			notifyListeners(newState);
+			if (! someDependenciesNeedInstance()) {
+                destroyComponent();
+            }
+			return true;
+		}
+		if (oldState == ComponentState.WAITING_FOR_REQUIRED && newState == ComponentState.INACTIVE) {
+		    stopDependencies();
+            destroyComponent();
+			notifyListeners(newState);
+			return true;
+		}
+		return false;
+	}
+	
+    private boolean allRequiredAvailable() {
+        boolean available = true;
+        for (DependencyContext d : m_dependencies) {
+            if (d.isRequired() && !d.isInstanceBound()) {
+                if (!d.isAvailable()) {
+                    available = false;
+                    break;
+                }
+            }
+        }
+        return available;
+    }
+
+    private boolean allInstanceBoundAvailable() {
+        boolean available = true;
+        for (DependencyContext d : m_dependencies) {
+            if (d.isRequired() && d.isInstanceBound()) {
+                if (!d.isAvailable()) {
+                    available = false;
+                    break;
+                }
+            }
+        }
+        return available;
+    }
+
+    private boolean someDependenciesNeedInstance() {
+        for (DependencyContext d : m_dependencies) {
+            if (d.needsInstance()) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Updates the component instance(s).
+     * @param dc the dependency context for the updating dependency service
+     * @param event the event holding the updating service (service + properties)
+     * @param update true if dependency service properties are updating, false if not. If false, it means
+     *        that a dependency service is being added or removed. (see the "add" flag).
+     * @param add true if the dependency service has been added, false if it has been removed. This flag is 
+     *        ignored if the "update" flag is true (because the dependency properties are just being updated).
+     */
+    private void updateInstance(DependencyContext dc, Event event, boolean update, boolean add) {
+        if (dc.isAutoConfig()) {
+            updateImplementation(dc.getAutoConfigType(), dc, dc.getAutoConfigName(), event, update, add);
+        }
+        if (dc.isPropagated() && m_registration != null) {
+            m_registration.setProperties(calculateServiceProperties());
+        }
+    }
+    
+    private void startDependencies(List<DependencyContext> dependencies) {
+        // Start first optional dependencies first.
+        m_logger.debug("startDependencies.");
+        List<DependencyContext> requiredDeps = new ArrayList<>();
+        for (DependencyContext d : dependencies) {
+            if (d.isRequired()) {
+                requiredDeps.add(d);
+                continue;
+            }
+            if (d.needsInstance()) {
+                instantiateComponent();
+            }
+            d.start();
+        }
+        // now, start required dependencies.
+        for (DependencyContext d : requiredDeps) {
+            if (d.needsInstance()) {
+                instantiateComponent();
+            }
+            d.start();
+        }
+        // The started dependencies has probably called our handleAdded method: we now have to run our state machine.
+        handleChange();
+    }
+    
+    private void stopDependencies() {
+        for (DependencyContext d : m_dependencies) {
+            d.stop();
+        }
+    }
+
+    private void registerService() {
+        if (m_context != null && m_serviceName != null) {
+            ServiceRegistrationImpl wrapper = new ServiceRegistrationImpl();
+            m_registration = wrapper;
+            autoConfigureImplementation(ServiceRegistration.class, m_registration);
+            
+            // 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_componentInstance, properties);
+                }
+                else {
+                    registration = m_context.registerService((String[]) m_serviceName, m_componentInstance, properties);
+                }
+                wrapper.setServiceRegistration(registration);
+            }
+            catch (IllegalArgumentException iae) {
+                m_logger.log(Logger.LOG_ERROR, "Could not register service " + m_componentInstance, 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 void unregisterService() {
+        if (m_serviceName != null && m_registration != null) {
+            try {
+                if (m_bundle != null && m_bundle.getState() == Bundle.ACTIVE) {
+                    m_registration.unregister();
+                }
+            } catch (IllegalStateException e) { /* Should we really log this ? */}
+            autoConfigureImplementation(ServiceRegistration.class, NULL_REGISTRATION);
+            m_registration = null;
+        }
+    }
+    
+    private Dictionary<Object, Object> calculateServiceProperties() {
+		Dictionary<Object, Object> properties = new Hashtable<>();
+		for (int i = 0; i < m_dependencies.size(); i++) {
+			DependencyContext d = (DependencyContext) m_dependencies.get(i);
+			if (d.isPropagated() && d.isAvailable()) {
+				Dictionary<Object, Object> dict = d.getProperties();
+				addTo(properties, dict);
+			}
+		}
+		// our service properties must not be overriden by propagated dependency properties, so we add our service
+		// properties after having added propagated dependency properties.
+		addTo(properties, m_serviceProperties);
+		if (properties.size() == 0) {
+			properties = null;
+		}
+		return properties;
+	}
+
+	private void addTo(Dictionary<Object, Object> properties, Dictionary<Object, Object> additional) {
+		if (properties == null) {
+			throw new IllegalArgumentException("Dictionary to add to cannot be null.");
+		}
+		if (additional != null) {
+			Enumeration<Object> e = additional.keys();
+			while (e.hasMoreElements()) {
+				Object key = e.nextElement();
+				properties.put(key, additional.get(key));
+			}
+		}
+	}
+
+	private void instantiateComponent() {
+        m_logger.debug("instantiating component.");
+
+		// TODO add more complex factory instantiations of one or more components in a composition here
+	    if (m_componentInstance == null) {
+            if (m_componentDefinition instanceof Class) {
+                try {
+                    m_componentInstance = createInstance((Class<?>) m_componentDefinition);
+                }
+                catch (Exception e) {
+                    m_logger.log(Logger.LOG_ERROR, "Could not instantiate class " + m_componentDefinition, 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 {
+    		        		m_componentInstance = InvocationUtil.invokeMethod(factory, factory.getClass(), m_instanceFactoryCreateMethod, new Class[][] {{}}, new Object[][] {{}}, false);
+    					}
+    		        	catch (Exception e) {
+    	                    m_logger.log(Logger.LOG_ERROR, "Could not create service instance using factory " + factory + " method " + m_instanceFactoryCreateMethod + ".", e);
+    					}
+		        	}
+	        	}
+            }
+            
+            if (m_componentInstance == null) {
+                m_componentInstance = m_componentDefinition;
+            }
+            
+	        // configure the bundle context
+            autoConfigureImplementation(BundleContext.class, m_context);
+            autoConfigureImplementation(ServiceRegistration.class, NULL_REGISTRATION);
+            autoConfigureImplementation(DependencyManager.class, m_manager);
+            autoConfigureImplementation(Component.class, this);
+	    }
+	}
+	
+	private void destroyComponent() {
+		m_componentInstance = null;
+	}
+	
+	private void invokeAddRequiredDependencies() {
+		for (DependencyContext d : m_dependencies) {
+			if (d.isRequired() && !d.isInstanceBound()) {
+			    for (Event e : m_dependencyEvents.get(d)) {
+			        d.invokeCallback(EventType.ADDED, e);
+			    }
+			}
+		}
+	}
+	
+    private void invokeAutoConfigDependencies() {
+        for (DependencyContext d : m_dependencies) {
+            if (d.isAutoConfig() && !d.isInstanceBound()) {
+                configureImplementation(d.getAutoConfigType(), d, d.getAutoConfigName());
+            }
+        }
+    }
+    
+    private void invokeAutoConfigInstanceBoundDependencies() {
+        for (DependencyContext d : m_dependencies) {
+            if (d.isAutoConfig() && d.isInstanceBound()) {
+                configureImplementation(d.getAutoConfigType(), d, d.getAutoConfigName());
+            }
+        }
+    }
+	
+	private void invokeAddRequiredInstanceBoundDependencies() {
+		for (DependencyContext d : m_dependencies) {
+			if (d.isRequired() && d.isInstanceBound()) {
+	             for (Event e : m_dependencyEvents.get(d)) {
+	                 d.invokeCallback(EventType.ADDED, e);
+	             }
+			}
+		}
+	}
+	
+    private void invokeAddOptionalDependencies() {
+        for (DependencyContext d : m_dependencies) {
+            if (! d.isRequired()) {
+                for (Event e : m_dependencyEvents.get(d)) {
+                    d.invokeCallback(EventType.ADDED, e);
+                }
+            }
+        }
+    }
+
+    private void invokeRemoveRequiredDependencies() { 
+		for (DependencyContext d : m_dependencies) {
+			if (!d.isInstanceBound() && d.isRequired()) {
+                for (Event e : m_dependencyEvents.get(d)) {
+                    d.invokeCallback(EventType.REMOVED, e);
+                }
+			}
+		}
+	}
+
+    private void invokeRemoveOptionalDependencies() { 
+        for (DependencyContext d : m_dependencies) {
+            if (! d.isRequired()) {
+                for (Event e : m_dependencyEvents.get(d)) {
+                    d.invokeCallback(EventType.REMOVED, e);
+                }
+            }
+        }
+    }
+
+	private void invokeRemoveInstanceBoundDependencies() {
+		for (DependencyContext d : m_dependencies) {
+			if (d.isInstanceBound()) {
+                for (Event e : m_dependencyEvents.get(d)) {
+                    d.invokeCallback(EventType.REMOVED, e);
+                }
+			}
+		}
+	}
+
+	private void invoke(String name) {
+        if (name != null) {
+            // if a callback instance was specified, look for the method there, if not,
+            // ask the service for its composition instances
+            Object[] instances = m_callbackInstance != null ? new Object[] { m_callbackInstance } : getCompositionInstances();
+
+            long t1 = System.nanoTime();
+            try {
+                invokeCallbackMethod(instances, name, 
+                    new Class[][] {{ Component.class }, {}}, 
+                    new Object[][] {{ this }, {}},
+                    false);
+            } finally {
+                long t2 = System.nanoTime();
+                m_stopwatch.put(name, t2 - t1);
+            }
+        }
+    }
+    
+	@SuppressWarnings("unchecked")
+    public <T> T getInstance() {     
+	    Object[] instances  = getCompositionInstances();
+	    return instances.length == 0 ? null : (T) instances[0]; 
+    }
+
+    public Object[] getInstances() {
+    	return getCompositionInstances();
+    }
+    
+    public void invokeCallbackMethod(Object[] instances, String methodName, Class<?>[][] signatures, Object[][] parameters) {
+        invokeCallbackMethod(instances, methodName, signatures, parameters, true);
+    }
+
+    public void invokeCallbackMethod(Object[] instances, String methodName, Class<?>[][] signatures,
+        Object[][] parameters, boolean logIfNotFound) {
+        boolean callbackFound = false;
+        for (int i = 0; i < instances.length; i++) {
+            try {
+                InvocationUtil.invokeCallbackMethod(instances[i], methodName, signatures, parameters);
+                callbackFound |= true;
+            }
+            catch (NoSuchMethodException e) {
+                // if the method does not exist, ignore it
+            }
+            catch (InvocationTargetException e) {
+                // the method itself threw an exception, log that
+                m_logger.log(Logger.LOG_ERROR, "Invocation of '" + methodName + "' failed.", e.getCause());
+            }
+            catch (Throwable e) {
+                m_logger.log(Logger.LOG_ERROR, "Could not invoke '" + methodName + "'.", e);
+            }
+        }
+        
+        // If the callback is not found, we don't log if the method is on an AbstractDecorator.
+        // (Aspect or Adapter are not interested in user dependency callbacks)        
+        if (logIfNotFound && ! callbackFound && ! (getInstance() instanceof AbstractDecorator)) {
+            if (m_logger == null) {
+                System.out.println("Callback \"" + methodName + "\" not found on componnent instances "
+                    + Arrays.toString(getInstances()));
+            } else {
+                m_logger.log(LogService.LOG_ERROR, "Callback \"" + methodName + "\" callback not found on componnent instances "
+                    + Arrays.toString(getInstances()));
+            }
+
+        }
+    }
+
+   private Object createInstance(Class<?> clazz) throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+		Constructor<?> constructor = clazz.getConstructor(VOID);
+		constructor.setAccessible(true);
+        return constructor.newInstance();
+    }
+
+	private void notifyListeners(ComponentState state) {
+		for (ComponentStateListener l : m_listeners) {
+			l.changed(this, state);
+		}
+	}
+	
+	@Override
+	public boolean isAvailable() {
+		return m_state == TRACKING_OPTIONAL;
+	}
+	
+	@Override
+	public boolean isActive() {
+	    return m_active.get();
+	}
+	
+	@Override
+	public Component add(final ComponentStateListener l) {
+	    m_listeners.add(l);
+	    return this;
+	}
+
+	@Override
+	public Component remove(ComponentStateListener l) {
+	    m_listeners.remove(l);
+	    return this;
+	}
+
+	@SuppressWarnings("unchecked")
+    @Override
+	public List<DependencyContext> getDependencies() {
+		return (List<DependencyContext>) m_dependencies.clone();
+	}
+
+	@Override
+	public Component setImplementation(Object implementation) {
+		m_componentDefinition = implementation;
+		return this;
+	}
+	
+    private void autoConfigureImplementation(Class<?> clazz, Object instance) {
+        if (((Boolean) m_autoConfig.get(clazz)).booleanValue()) {
+            configureImplementation(clazz, instance, (String) m_autoConfigInstance.get(clazz));
+        }
+    }
+    
+   /**
+     * 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 object to fill in the implementation class(es) field
+     * @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 fieldName) {
+        Object[] targets = getInstances();
+        if (! FieldUtil.injectField(targets, fieldName, clazz, instance, m_logger) && fieldName != null) {
+            // If the target is an abstract decorator (i.e: an adapter, or an aspect), we must not log warnings
+            // if field has not been injected.
+            if (! (getInstance() instanceof AbstractDecorator)) {
+                m_logger.log(Logger.LOG_ERROR, "Could not inject " + instance + " to field \"" + fieldName
+                    + "\" at any of the following component instances: " + Arrays.toString(targets));
+            }
+        }
+    }
+
+    private void configureImplementation(Class<?> clazz, DependencyContext dc, String fieldName) {
+        Object[] targets = getInstances();
+        if (! FieldUtil.injectDependencyField(targets, fieldName, clazz, dc, m_logger) && fieldName != null) {
+            // If the target is an abstract decorator (i.e: an adapter, or an aspect), we must not log warnings
+            // if field has not been injected.
+            if (! (getInstance() instanceof AbstractDecorator)) {
+                m_logger.log(Logger.LOG_ERROR, "Could not inject dependency " + clazz.getName() + " to field \""
+                    + fieldName + "\" at any of the following component instances: " + Arrays.toString(targets));
+            }
+        }
+    }
+
+    /**
+     * Update the component instances.
+     *
+     * @param clazz the class of the dependency service to inject in the component instances
+     * @param dc the dependency context for the updating dependency service
+     * @param fieldName the component instances fieldname to fill in with the updated dependency service
+     * @param event the event holding the updating service (service + properties)
+     * @param update true if dependency service properties are updating, false if not. If false, it means
+     *        that a dependency service is being added or removed. (see the "add" flag).
+     * @param add true if the dependency service has been added, false if it has been removed. This flag is 
+     *        ignored if the "update" flag is true (because the dependency properties are just being updated).
+     */
+    private void updateImplementation(Class<?> clazz, DependencyContext dc, String fieldName, Event event, boolean update,
+        boolean add)
+    {
+        Object[] targets = getInstances();
+        FieldUtil.updateDependencyField(targets, fieldName, update, add, clazz, event, dc, m_logger);
+    }
+
+    @Override
+	public ServiceRegistration getServiceRegistration() {
+        return m_registration;
+	}
+
+	@SuppressWarnings("unchecked")
+    @Override
+	public <K,V> Dictionary<K, V> getServiceProperties() {
+		if (m_serviceProperties != null) {
+			// Applied patch from FELIX-4304
+			Hashtable<Object, Object> serviceProperties = new Hashtable<>();
+			addTo(serviceProperties, m_serviceProperties);
+			return (Dictionary<K, V>) serviceProperties;
+		}
+		return null;
+	}
+
+	@Override
+    @SuppressWarnings("unchecked")
+	public Component setServiceProperties(final Dictionary<?, ?> serviceProperties) {
+	    getExecutor().execute(new Runnable() {
+            @Override
+			public void run() {
+			    Dictionary<Object, Object> properties = null;
+		        m_serviceProperties = (Dictionary<Object, Object>) serviceProperties;
+		        if ((m_registration != null) && (m_serviceName != null)) {
+		            properties = calculateServiceProperties();
+			        m_registration.setProperties(properties);
+		        }
+			}
+		});
+	    return this;
+	}
+	
+	public Component 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 Component setCallbacks(Object instance, String init, String start, String stop, String destroy) {
+	    ensureNotActive();
+        m_callbackInstance = instance;
+        m_callbackInit = init;
+        m_callbackStart = start;
+        m_callbackStop = stop;
+        m_callbackDestroy = destroy;
+        return this;
+    }
+
+	@Override
+	public Component setFactory(Object factory, String createMethod) {
+	    ensureNotActive();
+		m_instanceFactory = factory;
+		m_instanceFactoryCreateMethod = createMethod;
+		return this;
+	}
+
+	@Override
+	public Component setFactory(String createMethod) {
+		return setFactory(null, createMethod);
+	}
+
+	@Override
+	public Component setComposition(Object instance, String getMethod) {
+	    ensureNotActive();
+		m_compositionManager = instance;
+		m_compositionManagerGetMethod = getMethod;
+		return this;
+	}
+
+	@Override
+	public Component setComposition(String getMethod) {
+		return setComposition(null, getMethod);
+	}
+
+	private Object[] getCompositionInstances() {
+        Object[] instances = null;
+        if (m_compositionManagerGetMethod != null) {
+            if (m_compositionManager != null) {
+                m_compositionManagerInstance = m_compositionManager;
+            }
+            else {
+                m_compositionManagerInstance = m_componentInstance;
+            }
+            if (m_compositionManagerInstance != null) {
+                try {
+                    instances = (Object[]) InvocationUtil.invokeMethod(m_compositionManagerInstance, m_compositionManagerInstance.getClass(), m_compositionManagerGetMethod, new Class[][] {{}}, new Object[][] {{}}, false);
+                }
+                catch (Exception e) {
+                    m_logger.log(Logger.LOG_ERROR, "Could not obtain instances from the composition manager.", e);
+                    instances = m_componentInstance == null ? new Object[] {} : new Object[] { m_componentInstance };
+                }
+            }
+        }
+        else {
+            instances = m_componentInstance == null ? new Object[] {} : new Object[] { m_componentInstance };
+        }
+        return instances;
+	}
+
+	@Override
+	public DependencyManager getDependencyManager() {
+        return m_manager;
+	}
+	
+    public ComponentDependencyDeclaration[] getComponentDependencies() {
+        List<DependencyContext> deps = getDependencies();
+        if (deps != null) {
+            ComponentDependencyDeclaration[] result = new ComponentDependencyDeclaration[deps.size()];
+            for (int i = 0; i < result.length; i++) {
+                DependencyContext dep = (DependencyContext) deps.get(i);
+                if (dep instanceof ComponentDependencyDeclaration) {
+                    result[i] = (ComponentDependencyDeclaration) 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() {
+        StringBuffer sb = new StringBuffer();
+        Object serviceName = m_serviceName;
+        if (serviceName instanceof String[]) {
+            String[] names = (String[]) serviceName;
+            for (int i = 0; i < names.length; i++) {
+                if (i > 0) {
+                    sb.append(", ");
+                }
+                sb.append(names[i]);
+            }
+            appendProperties(sb);
+        } else if (serviceName instanceof String) {
+            sb.append(serviceName.toString());
+            appendProperties(sb);
+        } else {
+            Object implementation = m_componentDefinition;
+            if (implementation != null) {
+                if (implementation instanceof Class) {
+                    sb.append(((Class<?>) implementation).getName());
+                } else {
+                    // If the implementation instance does not override "toString", just display
+                    // the class name, else display the component using its toString method
+                    try {
+                	Method m = implementation.getClass().getMethod("toString", new Class[0]);
+                        if (m.getDeclaringClass().equals(Object.class)) {
+                            sb.append(implementation.getClass().getName());
+                        } else {
+                            sb.append(implementation.toString());
+                        }
+                    }  catch (java.lang.NoSuchMethodException e) {
+                        // Just display the class name
+                        sb.append(implementation.getClass().getName());
+                    }
+                }
+            } else {
+                sb.append(super.toString());
+            }
+        }
+        return sb.toString();
+    }
+    
+    private void appendProperties(StringBuffer result) {
+        Dictionary<Object, Object> properties = calculateServiceProperties();
+        if (properties != null) {
+            result.append("(");
+            Enumeration<?> enumeration = properties.keys();
+            while (enumeration.hasMoreElements()) {
+                Object key = enumeration.nextElement();
+                result.append(key.toString());
+                result.append('=');
+                Object value = properties.get(key);
+                if (value instanceof String[]) {
+                    String[] values = (String[]) value;
+                    result.append('{');
+                    for (int i = 0; i < values.length; i++) {
+                        if (i > 0) {
+                            result.append(',');
+                        }
+                        result.append(values[i].toString());
+                    }
+                    result.append('}');
+                }
+                else {
+                    result.append(value.toString());
+                }
+                if (enumeration.hasMoreElements()) {
+                    result.append(',');
+                }
+            }
+            result.append(")");
+        }
+    }
+    
+    @Override
+    public BundleContext getBundleContext() {
+        return m_context;
+    }
+    
+    @Override
+    public Bundle getBundle() {
+        return m_bundle;
+    }
+
+    public long getId() {
+        return m_id;
+    }
+    
+    public String getClassName() {
+        Object serviceInstance = m_componentInstance;
+        if (serviceInstance != null) {
+            return serviceInstance.getClass().getName();
+        } 
+        
+        Object implementation = m_componentDefinition;
+        if (implementation != null) {
+            if (implementation instanceof Class) {
+                return ((Class<?>) implementation).getName();
+            }
+            return implementation.getClass().getName();
+        } 
+        
+        Object instanceFactory = m_instanceFactory;
+        if (instanceFactory != null) {
+            return instanceFactory.getClass().getName();
+        } else {
+            // unexpected.
+            return ComponentImpl.class.getName();
+        }
+    }
+    
+    public String[] getServices() {
+        if (m_serviceName instanceof String[]) {
+            return (String[]) m_serviceName;
+        } else if (m_serviceName instanceof String) {
+            return new String[] { (String) m_serviceName };
+        } else {
+            return null;
+        }
+    }
+    
+    public int getState() {
+        return (isAvailable() ? ComponentDeclaration.STATE_REGISTERED : ComponentDeclaration.STATE_UNREGISTERED);
+    }
+
+    public void ensureNotActive() {
+        if (m_active.get()) {
+            throw new IllegalStateException("Can't modify an already started component.");
+        }
+    }
+    
+    public ComponentDeclaration getComponentDeclaration() {
+        return this;
+    }
+    
+    @Override
+    public String toString() {
+    	if (m_logger.getDebugKey() != null) {
+    		return m_logger.getDebugKey();
+    	}
+    	return getClassName();
+    }
+    
+    @Override
+    public void setThreadPool(Executor threadPool) {
+        ensureNotActive();
+        m_executor = new DispatchExecutor(threadPool, m_logger);
+    }
+    
+    @Override
+    public Logger getLogger() {
+        return m_logger;
+    }
+
+    @Override
+    public Map<String, Long> getCallbacksTime() {
+        return m_stopwatch;
+    }
+    
+    private Executor getExecutor() {
+        return m_executor;
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentScheduler.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentScheduler.java
new file mode 100644
index 0000000..eb2c0ea
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ComponentScheduler.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Executor;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentDeclaration;
+import org.apache.felix.dm.ComponentExecutorFactory;
+import org.apache.felix.dm.context.ComponentContext;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentFactory;
+
+/**
+ * The Dependency Manager delegates all components addition/removal to this class.
+ * If a ComponentExecutorFactory is registered in the OSGi registry, this class will use it to get an 
+ * Executor used for components management and lifecycle callbacks.
+ * 
+ * @see {@link ComponentFactory}
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ComponentScheduler {
+    private final static ComponentScheduler m_instance = new ComponentScheduler();
+    private final static String PARALLEL = "org.apache.felix.dependencymanager.parallel";
+    private volatile ComponentExecutorFactory m_componentExecutorFactory;
+    private final Executor m_serial = new SerialExecutor(null);
+    private ConcurrentMap<Component, Component> m_pending = new ConcurrentHashMap<>();
+
+    public static ComponentScheduler instance() {
+        return m_instance;
+    }
+
+    protected void bind(final ComponentExecutorFactory componentExecutorFactory) {
+        m_componentExecutorFactory = componentExecutorFactory;
+        m_serial.execute(new Runnable() {
+            @Override
+            public void run() {
+                for (Component c : m_pending.keySet()) {
+                    createComponentExecutor(m_componentExecutorFactory, c);
+                    ((ComponentContext) c).start();
+                }
+                m_pending.clear();
+            }
+        });
+    }
+
+    protected void unbind(ComponentExecutorFactory threadPool) {
+        m_componentExecutorFactory = null;
+    }
+
+    public void add(final Component c) {
+        if (mayStartNow(c)) {
+            ((ComponentContext) c).start();
+        }
+        else {
+            // The component requires a threadpool: delay execution until one is available.
+            m_serial.execute(new Runnable() {
+                @Override
+                public void run() {
+                    ComponentExecutorFactory execFactory = m_componentExecutorFactory;
+                    if (execFactory == null) {
+                        m_pending.put(c, c);
+                    }
+                    else {
+                        createComponentExecutor(execFactory, c);
+                        ((ComponentContext) c).start();
+                    }
+                }
+            });
+        }
+    }
+
+    public void remove(final Component c) {
+        m_pending.remove(c);
+        ((ComponentContext) c).stop();
+    }
+
+    private boolean mayStartNow(Component c) {
+        ComponentExecutorFactory execFactory = m_componentExecutorFactory;
+        BundleContext ctx = c.getDependencyManager().getBundleContext();
+        String parallel = ctx.getProperty(PARALLEL);
+
+        if (execFactory == null) {
+            // No ComponentExecutorFactory available. If a "parallel" OSGi system property is specified, 
+            // we have to wait for a ComponentExecutorFactory servoce if the component class name is matching one of the 
+            // prefixes specified in the "parallel" system property.
+            if (parallel != null && requiresThreadPool(c, parallel)) {
+                return false; // wait for a threadpool
+            } else {
+                return true; // no threadpool required, start the component now, synchronously
+            }
+        }
+        else {
+            // A threadpool is there. If the "parallel" OSGi system property is not specified, we can start the component
+            // now and we'll use the threadpool for it.
+            // But if the "parallel" system property is specified, the component will use the threadpool only if it's
+            // classname is starting with one of the prefixes specified in the property.
+            if (parallel == null || requiresThreadPool(c, parallel)) {
+                ((ComponentContext) c).setThreadPool(execFactory.getExecutorFor(c));
+            }
+            return true; // start the component now, possibly using the threadpool (see above).
+        }
+    }
+
+    private boolean requiresThreadPool(Component c, String parallel) {
+        // The component declared from our DM Activator can not be parallel.
+        ComponentDeclaration decl = c.getComponentDeclaration();
+        if (ComponentScheduler.class.getName().equals(decl.getName())) {
+            return false;
+        }
+
+        for (String prefix : parallel.trim().split(",")) {
+            prefix = prefix.trim();
+            boolean not = prefix.startsWith("!");
+            if (not) {
+                prefix = prefix.substring(1).trim();
+            }
+            if ("*".equals(prefix) || c.getComponentDeclaration().getClassName().startsWith(prefix)) {
+                return !not;
+            }
+        }
+        return false;
+    }
+    
+    private void createComponentExecutor(ComponentExecutorFactory execFactory, Component c) {
+        Executor exec = execFactory.getExecutorFor(c);
+        if (exec != null) {
+            ((ComponentContext) c).setThreadPool(exec);
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
new file mode 100644
index 0000000..db93df2
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java
@@ -0,0 +1,311 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Dictionary;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.felix.dm.ConfigurationDependency;
+import org.apache.felix.dm.Logger;
+import org.apache.felix.dm.PropertyMetaData;
+import org.apache.felix.dm.context.AbstractDependency;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.context.Event;
+import org.apache.felix.dm.context.EventType;
+import org.apache.felix.dm.impl.metatype.MetaTypeProviderImpl;
+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;
+
+/**
+ * Implementation for a configuration dependency.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ConfigurationDependencyImpl extends AbstractDependency<ConfigurationDependency> implements ConfigurationDependency, ManagedService {
+    private Dictionary<String, Object> m_settings;
+	private String m_pid;
+	private ServiceRegistration m_registration;
+    private MetaTypeProviderImpl m_metaType;
+	private final AtomicBoolean m_updateInvokedCache = new AtomicBoolean();
+	private final Logger m_logger;
+	private final BundleContext m_context;
+
+    public ConfigurationDependencyImpl() {
+        this(null, null);
+    }
+	
+    public ConfigurationDependencyImpl(BundleContext context, Logger logger) {
+        m_context = context;
+    	m_logger = logger;
+        setRequired(true);
+        setCallback("updated");
+    }
+    
+	public ConfigurationDependencyImpl(ConfigurationDependencyImpl prototype) {
+	    super(prototype);
+	    m_context = prototype.m_context;
+	    m_pid = prototype.m_pid;
+	    m_logger = prototype.m_logger;
+        m_metaType = prototype.m_metaType != null ? new MetaTypeProviderImpl(prototype.m_metaType, this, null) : null;
+	}
+	
+    @Override
+    public Class<?> getAutoConfigType() {
+        return null; // we don't support auto config mode.
+    }
+
+	@Override
+	public DependencyContext createCopy() {
+	    return new ConfigurationDependencyImpl(this);
+	}
+
+    public ConfigurationDependencyImpl setCallback(String callback) {
+        super.setCallbacks(callback, null);
+        return this;
+    }
+    
+    public ConfigurationDependencyImpl setCallback(Object instance, String callback) {
+        super.setCallbacks(instance, callback, null);
+        return this;
+    }
+
+    @Override
+    public boolean needsInstance() {
+        return m_callbackInstance == null;
+    }
+
+    @Override
+    public void start() {
+        BundleContext context = m_component.getBundleContext();
+        if (context != null) { // If null, we are in a test environment
+	        Properties props = new Properties();
+	        props.put(Constants.SERVICE_PID, m_pid);
+	        ManagedService ms = this;
+	        if (m_metaType != null) {
+	            ms = m_metaType;
+	        }
+	        m_registration = context.registerService(ManagedService.class.getName(), ms, props);
+        }
+        super.start();
+    }
+
+    @Override
+    public void stop() {
+        if (m_registration != null) {
+            try {
+                m_registration.unregister();
+            } catch (IllegalStateException e) {}
+        	m_registration = null;
+        }
+        super.stop();
+    }
+    
+	public ConfigurationDependency setPid(String pid) {
+		ensureNotActive();
+		m_pid = pid;
+		return this;
+	}
+		
+    @Override
+    public String getSimpleName() {
+        return m_pid;
+    }
+    
+    @Override
+    public String getFilter() {
+        return null;
+    }
+
+    public String getType() {
+        return "configuration";
+    }
+            
+    public ConfigurationDependency add(PropertyMetaData properties)
+    {
+        createMetaTypeImpl();
+        m_metaType.add(properties);
+        return this;
+    }
+
+    public ConfigurationDependency setDescription(String description)
+    {
+        createMetaTypeImpl();
+        m_metaType.setDescription(description);
+        return this;
+    }
+
+    public ConfigurationDependency setHeading(String heading)
+    {
+        createMetaTypeImpl();
+        m_metaType.setName(heading);
+        return this;
+    }
+    
+    public ConfigurationDependency setLocalization(String path)
+    {
+        createMetaTypeImpl();
+        m_metaType.setLocalization(path);
+        return this;
+    }
+    
+	@SuppressWarnings("unchecked")
+	@Override
+	public Dictionary<String, Object> getProperties() {
+		if (m_settings == null) {
+            throw new IllegalStateException("cannot find configuration");
+		}
+		return m_settings;
+	}
+    
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @Override
+    public void updated(Dictionary settings) throws ConfigurationException {
+    	m_updateInvokedCache.set(false);
+        Dictionary<String, Object> 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 this is initial settings, or a configuration update, we handle it synchronously.
+        // We'll conclude that the dependency is available only if invoking updated did not cause
+        // any ConfigurationException.
+        if (settings != null) {
+            Object[] instances = m_component.getInstances();
+            if (instances != null) {
+                try {
+                    invokeUpdated(settings);
+                } catch (ConfigurationException e) {
+                    logConfigurationException(e);
+                    throw e;
+                }
+            }
+        }
+        
+        // At this point, we have accepted the configuration.
+        synchronized (this) {
+            m_settings = settings;
+        }
+
+        if ((oldSettings == null) && (settings != null)) {
+            // Notify the component that our dependency is available.
+            m_component.handleEvent(this, EventType.ADDED, new ConfigurationEventImpl(m_pid, settings));
+        }
+        else if ((oldSettings != null) && (settings != null)) {
+            // Notify the component that our dependency has changed.
+            m_component.handleEvent(this, EventType.CHANGED, new ConfigurationEventImpl(m_pid, settings));
+        }
+        else if ((oldSettings != null) && (settings == null)) {
+            // Notify the component that our dependency has been removed.
+            // Notice that the component will be stopped, and then all required dependencies will be unbound
+            // (including our configuration dependency).
+            m_component.handleEvent(this, EventType.REMOVED, new ConfigurationEventImpl(m_pid, oldSettings));
+        }
+    }
+
+    @Override
+    public void invokeCallback(EventType type, Event ... event) {
+        switch (type) {
+        case ADDED:
+            try {
+                invokeUpdated(m_settings);
+            } catch (ConfigurationException e) {
+                logConfigurationException(e);
+            }
+            break;
+        case CHANGED:
+            // We already did that synchronously, from our updated method
+            break;
+        case REMOVED:
+            // The state machine is stopping us. We have to invoke updated(null).
+            try {
+                m_updateInvokedCache.set(false);
+                invokeUpdated(null);
+            } catch (ConfigurationException e) {
+                logConfigurationException(e);
+            } finally {
+                // Reset for the next time the state machine calls invokeAdd
+                m_updateInvokedCache.set(false);
+            }
+            break;
+        default:
+            break;
+        }
+    }
+    
+    private void invokeUpdated(Dictionary<?,?> settings) throws ConfigurationException {
+    	if (m_updateInvokedCache.compareAndSet(false, true)) {
+			Object[] instances = super.getInstances(); // either the callback instance or the component instances
+			if (instances != null) {
+				for (int i = 0; i < instances.length; i++) {
+					try {
+						InvocationUtil.invokeCallbackMethod(instances[i],
+								m_add, new Class[][] {
+										{ Dictionary.class }, {} },
+								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,
+									"Configuration update failed",
+									e.getTargetException());
+						}
+					} catch (NoSuchMethodException e) {
+						// if the method does not exist, ignore it
+					} catch (Throwable t) {
+						// wrap any other exception as a ConfigurationException.
+						throw new ConfigurationException(null,
+								"Configuration update failed", t);
+					}
+				}
+			}
+    	}
+    }
+    
+    private synchronized void createMetaTypeImpl() {
+        if (m_metaType == null) {
+            m_metaType = new MetaTypeProviderImpl(m_pid, m_context, m_logger, this, null);
+        }
+    }
+    
+    private void logConfigurationException(ConfigurationException e) {
+        if (m_logger != null) {
+            m_logger.log(Logger.LOG_ERROR, "Got exception while handling configuration update for pid " + m_pid, e);
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationEventImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationEventImpl.java
new file mode 100644
index 0000000..c5f64d5
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ConfigurationEventImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.Dictionary;
+
+import org.apache.felix.dm.context.Event;
+
+/**
+ * Implementation for a configuration event.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ConfigurationEventImpl extends Event {
+    private final String m_pid;
+    
+    public ConfigurationEventImpl(String pid, Dictionary<String, Object> conf) {
+        super(conf);
+        m_pid = pid;
+    }
+    
+    public String getPid() {
+        return m_pid;
+    }
+        
+    @Override
+    public int compareTo(Event other) {
+        return m_pid.compareTo(((ConfigurationEventImpl) other).m_pid);
+    }
+
+    @SuppressWarnings("unchecked")
+	@Override
+    public Dictionary<String, Object> getProperties() {
+        return getEvent();
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/DefaultNullObject.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/DefaultNullObject.java
new file mode 100644
index 0000000..eede17d
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/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.dm.impl;
+
+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/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/DispatchExecutor.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/DispatchExecutor.java
new file mode 100644
index 0000000..a780231
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/DispatchExecutor.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.felix.dm.Logger;
+import org.osgi.service.log.LogService;
+
+/**   
+ * A DispatchExecutor is a queue that can execute FIFO tasks in a shared threadpool configured for the dispatcher.
+ * Each task scheduled in a given DispatchExecutor will be executed serially in FIFO order; and multiple 
+ * DispatchExecutor instances may each run concurrently with respect to each other.
+ * <p>
+ * 
+ * This class also supports synchronous scheduling, like the @link {@link SerialExecutor} class; and in this case,
+ * only one caller thread will execute the tasks scheduled in the DispatchQueue (and the internal 
+ * threadpool won't be used).
+ * 
+ * <p> 
+ * 
+ * This class is <b>lock free</b> by design and ensures <b>"safe object publication"</b> between scheduling threads and
+ * actual executing thread: if one thread T1 schedules a task, but another thread T2 actually 
+ * executes it, then all the objects from the T1 thread will be "safely published" to the executing T2 thread.
+ * Safe publication is ensured  because we are using a ConcurrentLinkedQueue, and volatile attributes.
+ * (see [1], chapter 3.5.3 (Safe publication idioms). 
+ * 
+ * [1] Java Concurrency In Practice, Addison Wesley
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DispatchExecutor implements Executor, Runnable {
+	/**
+	 * The threadpool used for the execution of the tasks that are scheduled in this queue.
+	 */
+	private final Executor m_threadPool;
+
+	/** 
+	 * List of tasks scheduled in our queue.
+	 */
+	protected final ConcurrentLinkedQueue<Runnable> m_tasks = new ConcurrentLinkedQueue<>();
+
+    /**
+     * Marker used to remember the id of the thread currently executing this dispatch queue.
+     */
+    private volatile Thread m_executingThread;
+
+    /** 
+     * Flag telling if this dispatch queue is already scheduled for execution in the threadpool.
+     */
+    private final AtomicBoolean m_scheduled = new AtomicBoolean();
+
+    /** 
+	 * Logger used to log exceptions thrown by scheduled tasks. 
+	 */
+	private final Logger m_logger;
+	
+	/**
+	 * Creates a new DispatchQueue, which can be executed within a fixed thread pool. Multiple queue
+	 * can be executed concurrently, but all runnables scheduled in a given queue will be executed serially, 
+	 * in FIFO order. 
+	 * 
+	 * @param threadPool the executor (typically a threadpool) used to execute this DispatchExecutor.
+	 * @param logger the Logger used when errors are taking place
+	 */
+    public DispatchExecutor(Executor threadPool, Logger logger) {
+		m_logger = logger;
+		m_threadPool = threadPool;
+	}
+	
+    /**
+     * Enqueues a task for later execution. You must call {@link #execute()} in order
+     * to trigger the actual execution of all scheduled tasks (in FIFO order).
+     */
+    public void schedule(Runnable task) {
+        m_tasks.add(task);
+    }
+
+	/**
+	 * Submits a task in this queue, and schedule the execution of this DispatchQueue in the threadpool. 	 
+	 * The task is immediately executed (inline execution) if the queue is currently being executed by 
+	 * the current thread.
+	 */
+	public void execute(Runnable task) {
+	    execute(task, true);
+	}
+	
+	/**
+     * Schedules a task in this queue.
+     * If the queue is currently being executed by the current thread, then the task is executed immediately.
+     * @tasks the task to schedule
+     * @threadpool true if the queue should be executed in the threadpool, false if the queue must be executed by
+     * only one caller thread.
+     */
+    public void execute(Runnable task, boolean threadpool) {
+        Thread currThread = Thread.currentThread();
+        if (m_executingThread == currThread) {
+            runTask(task);
+        } else {
+            schedule(task);
+            execute(threadpool);
+        }
+    }
+	
+    /**
+     * Schedules the execution of this DispatchQueue in the threadpool.
+     */
+	public void execute() {
+	    execute(true);
+	}
+	
+    /**
+     * Schedules the execution of this DispatchQueue in the threadpool, or from a single caller thread.
+     * 
+     * @param threadpool true means the DispatchQueue is executed in the threadpool, false means the queue is executed from the
+     * caller thread.
+     */
+    public void execute(boolean threadpool) {
+        if (m_scheduled.compareAndSet(false, true)) { // schedules our run method in the tpool.
+            try {
+                if (threadpool) {
+                    m_threadPool.execute(this);
+                } else {
+                    run(); // run all queue tasks from the caller thread
+                }
+            } catch (RejectedExecutionException e) {
+                // The threadpool seems stopped (maybe the framework is being stopped). Anyway, just execute our tasks
+                // from the current thread.
+                run();
+            }
+        }
+    }
+
+	/**
+	 * Run all tasks scheduled in this queue, in FIFO order. This method may be executed either in the threadpool, or from
+	 * the caller thread.
+	 */
+	@Override
+	public void run() {
+        try {
+            // We do a memory barrier in order to ensure consistent per-thread
+            // memory visibility
+            m_executingThread = Thread.currentThread();
+            Runnable task;
+            while ((task = m_tasks.poll()) != null) {
+                runTask(task);
+            }
+        } finally {
+            m_scheduled.set(false);
+            m_executingThread = null;
+            if (m_tasks.peek() != null) {
+                execute();
+            }
+        }
+	}
+
+	/**
+	 * Runs a given task
+	 * @param task the task to execute
+	 */
+    private void runTask(Runnable task) {
+		try {
+		    task.run();
+		} catch (Throwable t) {
+			m_logger.log(LogService.LOG_ERROR, "Error processing tasks", t);
+		}
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
new file mode 100644
index 0000000..f96214a
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.Logger;
+import org.apache.felix.dm.PropertyMetaData;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.impl.metatype.MetaTypeProviderImpl;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+/**
+ * Factory configuration adapter service implementation. This class extends the FilterService in order to catch
+ * some Service methods for configuring actual adapter service implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FactoryConfigurationAdapterImpl extends FilterComponent {
+    // Our Managed Service Factory PID
+    protected final String m_factoryPid;
+    
+    // Our logger
+    protected final Logger m_logger;
+    
+    public FactoryConfigurationAdapterImpl(DependencyManager dm, String factoryPid, String update, boolean propagate) {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_factoryPid = factoryPid;
+        m_logger = ((ComponentImpl) m_component).getLogger();
+
+        Hashtable<String, Object> props = new Hashtable<>();
+        props.put(Constants.SERVICE_PID, factoryPid);
+        m_component
+            .setInterface(ManagedServiceFactory.class.getName(), props)
+            .setImplementation(new AdapterImpl(update, propagate))
+            .setCallbacks("init", null, "stop", null);
+    }
+    
+    public FactoryConfigurationAdapterImpl(DependencyManager dm, String factoryPid, String update, boolean propagate,
+        BundleContext bctx, Logger logger, String heading, String description, String localization, PropertyMetaData[] properyMetaData) {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_factoryPid = factoryPid;
+        m_logger = logger;
+        Hashtable<String, Object> props = new Hashtable<>();
+        props.put(Constants.SERVICE_PID, factoryPid);
+        m_component
+            .setInterface(ManagedServiceFactory.class.getName(), props)
+            .setImplementation(new MetaTypeAdapterImpl(update, propagate,
+                bctx, logger, heading, description,
+                localization, properyMetaData))
+            .setCallbacks("init", null, "stop", null);
+    }
+    
+    public String getName() {
+        return "Adapter for factory pid " + m_factoryPid;
+    }
+    
+    /**
+     * Creates, updates, or removes a service, when a ConfigAdmin factory configuration is created/updated or deleted.
+     */
+    public class AdapterImpl extends AbstractDecorator implements ManagedServiceFactory {        
+        // The adapter "update" method used to provide the configuration
+        protected final String m_update;
+
+        // Tells if the CM config must be propagated along with the adapter service properties
+        protected final boolean m_propagate;
+
+        /**
+         * Creates a new CM factory configuration adapter.
+         * 
+         * @param factoryPid
+         * @param updateMethod
+         * @param adapterInterface
+         * @param adapterImplementation
+         * @param adapterProperties
+         * @param propagate
+         */
+        public AdapterImpl(String updateMethod, boolean propagate) {
+            m_update = updateMethod;
+            m_propagate = propagate;
+        }
+
+        /**
+         * Returns the managed service factory name.
+         */
+        public String getName() {
+            return m_factoryPid;
+        }
+      
+        /**
+         * Method called from our superclass, when we need to create a service.
+         */
+        @SuppressWarnings("unchecked")
+        public Component createService(Object[] properties) {
+            Dictionary<String, ?> settings = (Dictionary<String, ?>) properties[0];     
+            Component newService = m_manager.createComponent();        
+            Object impl = null;
+            
+            try {
+                if (m_serviceImpl != null) {
+                    impl = (m_serviceImpl instanceof Class) ? ((Class<?>) m_serviceImpl).newInstance() : m_serviceImpl;
+                }
+                else {
+                    impl = instantiateFromFactory(m_factory, m_factoryCreateMethod);
+                }
+                InvocationUtil.invokeCallbackMethod(impl, m_update, 
+                    new Class[][] {{ Dictionary.class }, {}}, 
+                    new Object[][] {{ settings }, {}});
+            }
+            
+            catch (Throwable t) {
+               handleException(t);
+            }
+
+            // Merge adapter service properties, with CM settings 
+            Dictionary<String, Object> serviceProperties = getServiceProperties(settings);
+            newService.setInterface(m_serviceInterfaces, serviceProperties);
+            newService.setImplementation(impl);
+            newService.setComposition(m_compositionInstance, m_compositionMethod); // if not set, no effect
+            newService.setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy); // if not set, no effect
+            configureAutoConfigState(newService, m_component);
+            
+            for (DependencyContext dc : m_component.getDependencies()) {
+                newService.add((Dependency) dc.createCopy());
+            }
+            
+            for (int i = 0; i < m_stateListeners.size(); i ++) {
+                newService.add(m_stateListeners.get(i));
+            }
+            
+            return newService;
+        }
+
+        /**
+         * Method called from our superclass, when we need to update a Service, because 
+         * the configuration has changed.
+         */
+        @SuppressWarnings("unchecked")
+        public void updateService(Object[] properties) {
+            Dictionary<String, ?> cmSettings = (Dictionary<String, ?>) properties[0];
+            Component service = (Component) properties[1];
+            Object impl = service.getInstances()[0];
+
+            try {
+                InvocationUtil.invokeCallbackMethod(impl, m_update, 
+                    new Class[][] {{ Dictionary.class }, {}}, 
+                    new Object[][] {{ cmSettings }, {}});
+                if (m_serviceInterfaces != null && m_propagate == true) {
+                    Dictionary<String, ?> serviceProperties = getServiceProperties(cmSettings);
+                    service.setServiceProperties(serviceProperties);
+                }
+            }
+            
+            catch (Throwable t) {
+                handleException(t);
+            }
+        }   
+
+        /**
+         * Merge CM factory configuration setting with the adapter service properties. The private CM factory configuration 
+         * settings are ignored. A CM factory configuration property is private if its name starts with a dot (".").
+         * 
+         * @param adapterProperties
+         * @param settings
+         * @return
+         */
+        private Dictionary<String, Object> getServiceProperties(Dictionary<String, ?> settings) {
+            Dictionary<String, Object> props = new Hashtable<>();
+            
+            // Add adapter Service Properties
+            if (m_serviceProperties != null) {
+                Enumeration<String> keys = m_serviceProperties.keys();
+                while (keys.hasMoreElements()) {
+                    String key = keys.nextElement();
+                    Object val = m_serviceProperties.get(key);
+                    props.put(key, val);
+                }
+            }
+
+            if (m_propagate) {
+                // Add CM setting into adapter service properties.
+                // (CM setting will override existing adapter service properties).
+                Enumeration<String> keys = settings.keys();
+                while (keys.hasMoreElements()) {
+                    String key = keys.nextElement();
+                    if (! key.toString().startsWith(".")) {
+                        // public properties are propagated
+                        Object val = settings.get(key);
+                        props.put(key, val);
+                    }
+                }
+            }
+
+            
+            return props;
+        }
+    
+        private Object instantiateFromFactory(Object mFactory, String mFactoryCreateMethod) {
+            Object factory = null;
+            if (m_factory instanceof Class) {
+                try {
+                    factory = createInstance((Class<?>) m_factory);
+                }
+                catch (Throwable t) {
+                    handleException(t);
+                }
+            }
+            else {
+                factory = m_factory;
+            }
+
+            try {
+                return InvocationUtil.invokeMethod(factory, factory.getClass(), m_factoryCreateMethod, new Class[][] { {} }, new Object[][] { {} }, false);
+            }
+            catch (Throwable t) {
+                handleException(t);
+                return null;
+            }
+        }
+
+        private Object createInstance(Class<?> clazz) throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException {
+            Constructor<?> constructor = clazz.getConstructor(new Class[] {});
+            constructor.setAccessible(true);
+            return clazz.newInstance();
+        }
+    
+        private void handleException(Throwable t) {
+            m_logger.log(Logger.LOG_ERROR, "Got exception while handling configuration update for factory pid " + m_factoryPid, t);
+            if (t instanceof InvocationTargetException) {
+                // Our super class will check if the target exception is itself a ConfigurationException.
+                // In this case, it will simply re-thrown.
+                throw new RuntimeException(((InvocationTargetException) t).getTargetException());
+            }
+            else if (t instanceof RuntimeException) {
+                throw (RuntimeException) t;
+            }
+            else {
+                throw new RuntimeException(t);
+            }
+        }
+    }
+
+    
+    /**
+     * Extends AdapterImpl for MetaType support.
+     */
+    class MetaTypeAdapterImpl extends AdapterImpl implements MetaTypeProvider {
+        // Our MetaType Provider for describing our properties metadata
+        private final MetaTypeProviderImpl m_metaType;
+        
+        public MetaTypeAdapterImpl(String updateMethod, boolean propagate,
+                                   BundleContext bctx, Logger logger, String heading, 
+                                   String description, String localization,
+                                   PropertyMetaData[] properyMetaData) {
+            super(updateMethod, propagate);
+            m_metaType = new MetaTypeProviderImpl(m_factoryPid, bctx, logger, null, this);
+            m_metaType.setName(heading);
+            m_metaType.setDescription(description);
+            if (localization != null) {
+                m_metaType.setLocalization(localization);
+            }
+            for (int i = 0; i < properyMetaData.length; i++) {
+                m_metaType.add(properyMetaData[i]);
+            }
+        }
+        
+        public String[] getLocales() {
+            return m_metaType.getLocales();
+        }
+
+        public ObjectClassDefinition getObjectClassDefinition(String id, String locale) {
+            return m_metaType.getObjectClassDefinition(id, locale);
+        }
+    }    
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FieldUtil.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FieldUtil.java
new file mode 100644
index 0000000..dbaa123
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FieldUtil.java
@@ -0,0 +1,351 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.felix.dm.Logger;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.context.Event;
+
+/**
+ * Reflection Helper methods, used to inject autoconfig fields in component instances.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FieldUtil {
+    /**
+     * Callbacks for fields to be injected
+     */
+    private interface FieldFunction {
+        // Inject an updated service in the given field for the the given target.
+        void injectField(Field f, Object target);
+
+        // Inject an Iterable Field in the given target 
+        void injectIterableField(Field f, Object target);
+
+        // Inject a Map field in the given target (key = dependency service, value = Dictionary with dependency service properties).
+        void injectMapField(Field f, Object target);
+    }
+
+    /**
+     * Injects some component instances (on a given field, if provided), with an object of a given class.
+     * @param targets the component instances to fill in
+     * @param fieldName the fieldname, or null. If null, the field must exaclty match the injected service classname.
+     * @param clazz the injected service class
+     * @param service the injected service
+     * @param logger the component logger.
+     */
+    public static boolean injectField(Object[] targets, String fieldName, Class<?> clazz, final Object service,
+        final Logger logger)
+    {
+        if (service == null) {
+            return true; // TODO why service can be null ?
+        }
+        return mapField(true, clazz, targets, fieldName, logger, new FieldFunction() {
+            public void injectField(Field f, Object target) {
+                try {
+                    f.setAccessible(true);
+                    f.set(target, service);
+                } catch (Throwable e) {
+                    logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class "
+                        + target.getClass().getName(), e);
+                }
+            }
+
+            public void injectIterableField(Field f, Object target) { // never called
+            }
+
+            public void injectMapField(Field f, Object target) { // never called
+            }
+        });
+    }
+
+    /**
+     * Injects a dependency service in some component instances.
+     * Here, we'll inject the dependency services in the component if the field is of the same type of the injected services,
+     * or if the field is a Collection of the injected service, or if the field is a Map<Injected Service class, Dictionary).
+     * @param targets the component instances to fill in
+     * @param fieldName the fieldname, or null. If null, the field must exaclty match the injected service classname.
+     * @param clazz the injected service class
+     * @param service the injected service
+     * @param logger the component logger.
+     */
+    public static boolean injectDependencyField(Object[] targets, String fieldName, Class<?> clazz,
+        final DependencyContext dc, final Logger logger)
+    {
+        final Event event = dc.getService();
+        if (event == null) {
+            return true; // TODO check why event can be null
+        }
+        return mapField(false, clazz, targets, fieldName, logger, new FieldFunction() {
+            public void injectField(Field f, Object target) {
+                try {
+                    f.setAccessible(true);
+                    f.set(target, event.getEvent());
+                } catch (Throwable e) {
+                    logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class "
+                        + target.getClass().getName(), e);
+                }
+            }
+
+            @SuppressWarnings("unchecked")
+            public void injectIterableField(Field f, Object target) {
+                f.setAccessible(true);
+
+                try {
+                    Iterable<Object> iter = (Iterable<Object>) f.get(target);
+                    if (iter == null) {
+                        iter = new ConcurrentLinkedQueue<Object>();
+                        f.set(target, iter);
+                    }
+                    dc.copyToCollection((Collection<Object>) iter);
+                } catch (Throwable e) {
+                    logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class "
+                        + target.getClass().getName(), e);
+                }
+            }
+
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            @Override
+            public void injectMapField(Field f, Object target) {
+                f.setAccessible(true);
+                try {
+                    Map<Object, Dictionary<?, ?>> map = (Map) f.get(target);
+                    if (map == null) {
+                        map = new ConcurrentHashMap<>();
+                        f.set(target, map);
+                    }
+                    dc.copyToMap(map);
+                } catch (Throwable e) {
+                    logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class "
+                        + target.getClass().getName(), e);
+                }
+            }
+        });
+    }
+
+    /**
+     * Adds, or removes, or update some component instances with an updated dependency service
+     * @param targets the component instances to fill in with the updated service
+     * @param fieldName the component instance fieldname 
+     * @param update true if it's a dependency service update, false if the dependency service is added or removed
+     * @param add true if the dependency service has been added, false the dependency service has been removed. 
+     * This flag is ignored if the "update" parameter is "true". 
+     * @param clazz the clazz of the dependency service
+     * @param event the event holding the dependency service
+     * @param dc the dependency service context
+     * @param logger the logger used when problems occure.
+     */
+    public static void updateDependencyField(Object[] targets, String fieldName, final boolean update,
+        final boolean add, Class<?> clazz, final Event event, final DependencyContext dc, final Logger logger)
+    {
+        mapField(false, clazz, targets, fieldName, logger, new FieldFunction() {
+            public void injectField(Field f, Object target) {
+                try {
+                    f.setAccessible(true);
+                    f.set(target, dc.getService().getEvent());
+                } catch (Throwable e) {
+                    logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class "
+                        + target.getClass().getName(), e);
+                }
+            }
+
+            @SuppressWarnings("unchecked")
+            public void injectIterableField(Field f, Object target) {
+                if (update) {
+                    return;
+                }
+
+                f.setAccessible(true);
+
+                try {
+                    Collection<Object> coll = (Collection<Object>) f.get(target);
+                    if (add) {
+                        coll.add(event.getEvent());
+                    } else {
+                        coll.remove(event.getEvent());
+                    }
+                } catch (Throwable e) {
+                    logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class "
+                        + target.getClass().getName(), e);
+                }
+            }
+
+            @SuppressWarnings({ "rawtypes", "unchecked" })
+            @Override
+            public void injectMapField(Field f, Object target) {
+                f.setAccessible(true);
+
+                try {
+                    Map<Object, Dictionary<?, ?>> map = (Map) f.get(target);
+                    if (add) {
+                        map.put(event.getEvent(), event.getProperties());
+                    } else {
+                        map.remove(event.getEvent());
+                    }
+                } catch (Throwable e) {
+                    logger.log(Logger.LOG_ERROR, "Could not set field " + f + " in class "
+                        + target.getClass().getName(), e);
+                }
+            }
+        });
+    }
+
+    /**
+     * Scans component instances for fields having either the same dependency service type, or being a 
+     * Collection of the dependency service, or being a Map<Dependency Service class, Dictionary> (the Dictionary
+     * corresponds to the dependency service properties).
+     * @param strict true if we are only looking for fields having exactly the same type as the dependency service. 
+     * In other words, if strict = true, we don't lookup for fields of "Collection" or "Map" types.
+     * @param clazz the dependency service class
+     * @param targets the component instances
+     * @param fieldName the component instances field name or null
+     * @param logger a logger used when exceptions are occuring
+     * @param func the callback used to notify when we find either a field with the same dependency service type, or
+     * with a "Collection" type, or with a "Map" type.
+     */
+    private static boolean mapField(boolean strict, Class<?> clazz, Object[] targets, String fieldName, Logger logger,
+        FieldFunction func)
+    {
+        boolean injected = false;
+        if (targets != null && clazz != null) {
+            for (int i = 0; i < targets.length; i++) {
+                Object target = targets[i];
+                Class<?> targetClass = target.getClass();
+                if (Proxy.isProxyClass(targetClass)) {
+                    target = Proxy.getInvocationHandler(target);
+                    targetClass = target.getClass();
+                }
+                while (targetClass != null) {
+                    Field[] fields = targetClass.getDeclaredFields();
+                    for (int j = 0; j < fields.length; j++) {
+                        Field field = fields[j];
+                        Class<?> fieldType = field.getType();
+
+                        if (fieldName == null) {
+                            // Field type class must match injected service type
+                            if (fieldType.equals(clazz)) {
+                                injected = true;
+                                func.injectField(field, target);
+                            } else if (!strict && mayInjectToIterable(clazz, field, true)) {
+                                injected = true;
+                                func.injectIterableField(field, target);
+                            } else if (!strict && mayInjectToMap(clazz, field, true)) {
+                                injected = true;
+                                func.injectMapField(field, target);
+                            }
+                        } else if (field.getName().equals(fieldName)) {
+                            // Field type may be a superclass of the service type
+                            if (fieldType.isAssignableFrom(clazz)) {
+                                injected = true;
+                                func.injectField(field, target);
+                            } else if (!strict && mayInjectToIterable(clazz, field, false)) {
+                                injected = true;
+                                func.injectIterableField(field, target);
+                            } else if (!strict && mayInjectToMap(clazz, field, false)) {
+                                injected = true;
+                                func.injectMapField(field, target);
+                            } else {
+                                logger.log(
+                                    Logger.LOG_ERROR,
+                                    "Could not set field " + field + " in class " + target.getClass().getName()
+                                        + ": the type of the field type should be either assignable from "
+                                        + clazz.getName() + " or Collection, or Map");
+                            }
+                        }
+                    }
+                    targetClass = targetClass.getSuperclass();
+                }
+            }
+        }
+        return injected;
+    }
+
+    private static boolean mayInjectToIterable(Class<?> clazz, Field field, boolean strictClassEquality) {
+        Class<?> fieldType = field.getType();
+        if (Iterable.class.isAssignableFrom(fieldType)) {
+            ParameterizedType parameterType = (ParameterizedType) field.getGenericType();
+            if (parameterType == null) {
+                return false;
+            }
+            Type[] types = parameterType.getActualTypeArguments();
+            if (types == null || types.length == 0) {
+            	return false;
+            }
+            if (types[0] instanceof Class<?>) {
+            	Class<?> parameterizedTypeClass = (Class<?>) types[0];
+            	return strictClassEquality ? parameterizedTypeClass.equals(clazz)
+            			: parameterizedTypeClass.isAssignableFrom(clazz);
+            }	
+        }
+        return false;
+    }
+
+    private static boolean mayInjectToMap(Class<?> clazz, Field field, boolean strictClassEquality) {
+        Class<?> fieldType = field.getType();
+        if (Map.class.isAssignableFrom(fieldType)) {
+            // The field must be a parameterized map (generics).
+            if (! (field.getGenericType() instanceof ParameterizedType)) {
+                return false;
+            }
+            ParameterizedType parameterType = (ParameterizedType) field.getGenericType();
+            if (parameterType == null) {
+                return false;
+            }
+            
+            Type[] types = parameterType.getActualTypeArguments();
+            if (types == null || types.length < 2) {
+            	return false;
+            }
+                   
+            // The map field generic key parameter must be "Class".
+            if (! (types[0] instanceof Class<?>)) {
+                return false;
+            }
+            
+            // The map generic value parameter must be Dictionary, or Dictionary<String, ...>
+            if (types[1] instanceof Class<?>) {
+                // The map field is in the form "Map m_field<Class, Dictionary>"
+                Class<?> mapValueGenericType = (Class<?>) types[1];
+                if (! mapValueGenericType.equals(Dictionary.class)) {
+                    return false;
+                }
+            } else if (types[1] instanceof ParameterizedType) {
+                // The map field is in the form "Map m_field<Class, Dictionary<String, ...>"
+                ParameterizedType mapValueGenericType = (ParameterizedType) types[1];
+                if (! mapValueGenericType.getRawType().equals(Dictionary.class)) {
+                    return false;
+                }
+            }
+            
+            Class<?> K = (Class<?>) types[0];
+            return strictClassEquality ? K.equals(clazz) : K.isAssignableFrom(clazz);
+        }
+        return false;
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java
new file mode 100644
index 0000000..33bf464
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/FilterComponent.java
@@ -0,0 +1,354 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentDeclaration;
+import org.apache.felix.dm.ComponentDependencyDeclaration;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.Logger;
+import org.apache.felix.dm.context.ComponentContext;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.context.Event;
+import org.apache.felix.dm.context.EventType;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * This class allows to filter a Component interface. All Aspect/Adapters extend this class
+ * in order to add functionality to the default Component implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FilterComponent implements Component, ComponentContext, ComponentDeclaration {
+    protected volatile ComponentImpl m_component;
+    protected volatile List<ComponentStateListener> m_stateListeners = new CopyOnWriteArrayList<>();
+    protected volatile String m_init = "init";
+    protected volatile String m_start = "start";
+    protected volatile String m_stop = "stop";
+    protected volatile String m_destroy = "destroy";
+    protected volatile Object m_callbackObject;
+    protected volatile Object m_compositionInstance;
+    protected volatile String m_compositionMethod;
+    protected volatile String[] m_serviceInterfaces;
+    protected volatile Object m_serviceImpl;
+    protected volatile Object m_factory;
+    protected volatile String m_factoryCreateMethod;
+    protected volatile Dictionary<String, Object> m_serviceProperties;
+
+    public FilterComponent(Component service) {
+        m_component = (ComponentImpl) service;
+    }
+    
+    @Override
+    public String toString() {
+        return m_component.toString();
+    }
+
+    public Component add(Dependency ... dependencies) {
+        m_component.add(dependencies);
+        // Add the dependencies to all already instantiated services.
+        // If one dependency from the list is required, we have nothing to do, since our internal
+        // service will be stopped/restarted.
+        for (Dependency dependency : dependencies) {
+            if (((DependencyContext) dependency).isRequired()) {
+                return this;
+            }
+        }
+        // Ok, the list contains no required dependencies: add optionals dependencies in already instantiated services.
+        Object[] instances = m_component.getInstances();
+        if (instances.length > 0) {
+            AbstractDecorator ad = (AbstractDecorator) instances[0];
+            if (ad != null) {
+                ad.addDependency(dependencies);
+            }
+        }
+        return this;
+    }
+
+    public Component add(ComponentStateListener listener) {
+        m_stateListeners.add(listener);
+        // Add the listener to all already instantiated services.
+        Object[] instances = m_component.getInstances();
+        if (instances.length > 0) {
+            AbstractDecorator ad = (AbstractDecorator) instances[0];
+            if (ad != null) {
+                ad.addStateListener(listener);
+            }
+        }
+        return this;
+    }
+
+    public List<DependencyContext> getDependencies() {
+        return m_component.getDependencies();
+    }
+
+    public String getClassName() {
+        return m_component.getClassName();
+    }
+    
+    @SuppressWarnings("unchecked")
+	public Dictionary<String, Object> getServiceProperties() {
+        return m_serviceProperties;
+    }
+
+    public ServiceRegistration getServiceRegistration() {
+        return m_component.getServiceRegistration();
+    }
+
+    public Component remove(Dependency dependency) {
+        m_component.remove(dependency);
+        // Remove the dependency (if optional) from all already instantiated services.
+        // If the dependency is required, our internal service will be stopped, so in this case
+        // we have nothing to do.
+        if (!((DependencyContext) dependency).isRequired())
+        {
+            Object[] instances = m_component.getInstances();
+            if (instances.length > 0) {
+                AbstractDecorator ad = (AbstractDecorator) instances[0];
+                if (ad != null) {
+                    ad.removeDependency(dependency);
+                }
+            }
+        }
+        return this;
+    }
+
+    public Component remove(ComponentStateListener listener) {
+        m_stateListeners.remove(listener);
+        // Remove the listener from all already instantiated services.
+        Object[] instances = m_component.getInstances();
+        if (instances.length > 0) {
+            AbstractDecorator ad = (AbstractDecorator) instances[0];
+            if (ad != null) {
+                ad.removeStateListener(listener);
+            }
+        }
+        return this;
+    }
+
+    public Component setCallbacks(Object instance, String init, String start, String stop, String destroy) {
+        m_component.ensureNotActive();
+        m_callbackObject = instance;
+        m_init = init;
+        m_start = start;
+        m_stop = stop;
+        m_destroy = destroy;
+        return this;
+    }
+
+    public Component setCallbacks(String init, String start, String stop, String destroy) {
+        setCallbacks(null, init, start, stop, destroy);
+        return this;
+    }
+
+    public Component setComposition(Object instance, String getMethod) {
+        m_component.ensureNotActive();
+        m_compositionInstance = instance;
+        m_compositionMethod = getMethod;
+        return this;
+    }
+
+    public Component setComposition(String getMethod) {
+        m_component.ensureNotActive();
+        m_compositionMethod = getMethod;
+        return this;
+    }
+
+    public Component setFactory(Object factory, String createMethod) {
+        m_component.ensureNotActive();
+        m_factory = factory;
+        m_factoryCreateMethod = createMethod;
+        return this;
+    }
+
+    public Component setFactory(String createMethod) {
+        return setFactory(null, createMethod);
+    }
+
+    public Component setImplementation(Object implementation) {
+        m_component.ensureNotActive();
+        m_serviceImpl = implementation;
+        return this;
+    }
+
+    public Component setInterface(String serviceName, Dictionary<?, ?> properties) {
+        return setInterface(new String[] { serviceName }, properties);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Component setInterface(String[] serviceInterfaces, Dictionary<?, ?> properties) {
+        m_component.ensureNotActive();
+        if (serviceInterfaces != null) {
+            m_serviceInterfaces = new String[serviceInterfaces.length];
+            System.arraycopy(serviceInterfaces, 0, m_serviceInterfaces, 0, serviceInterfaces.length);
+            m_serviceProperties = (Dictionary<String, Object>) properties;
+        }
+        return this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Component setServiceProperties(Dictionary<?, ?> serviceProperties) {
+        m_serviceProperties = (Dictionary<String, Object>) serviceProperties;
+        // Set the properties to all already instantiated services.
+        if (serviceProperties != null) {
+            Object[] instances = m_component.getInstances();
+            if (instances.length > 0) {
+                AbstractDecorator ad = (AbstractDecorator) instances[0];
+                if (ad != null) {
+                    ad.setServiceProperties(serviceProperties);
+                }
+            }
+        }
+        return this;
+    }
+
+    public void start() {
+        m_component.start();
+    }
+
+    public void stop() {
+        m_component.stop();
+    }
+    
+    public void invokeCallbackMethod(Object[] instances, String methodName, Class<?>[][] signatures, Object[][] parameters) {
+        m_component.invokeCallbackMethod(instances, methodName, signatures, parameters);
+    }
+        
+    public DependencyManager getDependencyManager() {
+        return m_component.getDependencyManager();
+    }
+
+    public Component setAutoConfig(Class<?> clazz, boolean autoConfig) {
+        m_component.setAutoConfig(clazz, autoConfig);
+        return this;
+    }
+
+    public Component setAutoConfig(Class<?> clazz, String instanceName) {
+        m_component.setAutoConfig(clazz, instanceName);
+        return this;
+    }
+    
+    public boolean getAutoConfig(Class<?> clazz) {
+        return m_component.getAutoConfig(clazz);
+    }
+    
+    public String getAutoConfigInstance(Class<?> clazz) {
+        return m_component.getAutoConfigInstance(clazz);
+    }
+
+    public ComponentDependencyDeclaration[] getComponentDependencies() {
+        return m_component.getComponentDependencies();
+    }
+
+    public String getName() {
+        return m_component.getName();
+    }
+
+    public int getState() {
+        return m_component.getState();
+    }
+    
+    public long getId() {
+        return m_component.getId();
+    }
+
+    public String[] getServices() {
+        return m_component.getServices();
+    }
+    
+    public BundleContext getBundleContext() {
+        return m_component.getBundleContext();
+    }
+        
+    @Override
+    public boolean isActive() {
+        return m_component.isActive();
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return m_component.isAvailable();
+    }
+
+    @Override
+    public void handleEvent(DependencyContext dc, EventType type, Event ... e) {
+        m_component.handleEvent(dc, type, e);
+    }
+    
+    @Override
+    public <T> T getInstance() {
+        return m_component.getInstance();
+    }
+
+    @Override
+    public Object[] getInstances() {
+        return m_component.getInstances();
+    }
+    
+    @Override
+    public Event getDependencyEvent(DependencyContext dc) {
+        return m_component.getDependencyEvent(dc);
+    }
+    
+    @Override
+    public Set<Event> getDependencyEvents(DependencyContext dc) {
+        return m_component.getDependencyEvents(dc);
+    }
+    
+    public ComponentDeclaration getComponentDeclaration() {
+        return this;
+    }
+
+	@Override
+	public Component setDebug(String label) {
+		m_component.setDebug(label);
+		return this;
+	}
+	
+    @Override
+    public void setThreadPool(Executor threadPool) {
+        m_component.setThreadPool(threadPool);
+    }
+
+    @Override
+    public Map<String, Long> getCallbacksTime() {
+        return m_component.getCallbacksTime();
+    }
+
+    @Override
+    public Bundle getBundle() {
+        return m_component.getBundle();
+    }
+
+    @Override
+    public Logger getLogger() {
+        return m_component.getLogger();
+    }
+}
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/InvocationUtil.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/InvocationUtil.java
new file mode 100644
index 0000000..880eba2
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/InvocationUtil.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Utility methods for invoking callbacks. Lookups of callbacks are accellerated by using a LRU cache.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class InvocationUtil {
+    private static final Map<Key, Method> m_methodCache;
+    static {
+        int size = 2048;
+        // TODO enable this again
+//        try {
+//            String value = System.getProperty(DependencyManager.METHOD_CACHE_SIZE);
+//            if (value != null) {
+//                size = Integer.parseInt(value);
+//            }
+//        }
+//        catch (Exception e) {}
+        m_methodCache = new LRUMap(Math.max(size, 64));
+    }
+    
+    /**
+     * Invokes a callback method on an instance. The code will search for a callback method with
+     * the supplied name and any of the supplied signatures in order, invoking the first one it finds.
+     * 
+     * @param instance the instance to invoke the method on
+     * @param methodName the name of the method
+     * @param signatures the ordered list of signatures to look for
+     * @param parameters the parameter values to use for each potential signature
+     * @return whatever the method returns
+     * @throws NoSuchMethodException when no method could be found
+     * @throws IllegalArgumentException when illegal values for this methods arguments are supplied 
+     * @throws IllegalAccessException when the method cannot be accessed
+     * @throws InvocationTargetException when the method that was invoked throws an exception
+     */
+    public static Object invokeCallbackMethod(Object instance, String methodName, Class<?>[][] signatures, Object[][] parameters) throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+        Class<?> currentClazz = instance.getClass();
+        while (currentClazz != null && currentClazz != Object.class) {
+            try {
+                return invokeMethod(instance, currentClazz, methodName, signatures, parameters, false);
+            }
+            catch (NoSuchMethodException nsme) {
+                // ignore
+            }
+            currentClazz = currentClazz.getSuperclass();
+        }
+        throw new NoSuchMethodException(methodName);
+    }
+
+    /**
+     * Invoke a method on an instance.
+     * 
+     * @param object the instance to invoke the method on
+     * @param clazz the class of the instance
+     * @param name the name of the method
+     * @param signatures the signatures to look for in order
+     * @param parameters the parameter values for the signatures
+     * @param isSuper <code>true</code> if this is a superclass and we should therefore not look for private methods
+     * @return whatever the method returns
+     * @throws NoSuchMethodException when no method could be found
+     * @throws IllegalArgumentException when illegal values for this methods arguments are supplied 
+     * @throws IllegalAccessException when the method cannot be accessed
+     * @throws InvocationTargetException when the method that was invoked throws an exception
+     */
+    public static Object invokeMethod(Object object, Class<?> clazz, String name, Class<?>[][] signatures, Object[][] parameters, boolean isSuper) throws NoSuchMethodException, InvocationTargetException, IllegalArgumentException, IllegalAccessException {
+        if (object == null) {
+            throw new IllegalArgumentException("Instance cannot be null");
+        }
+        if (clazz == null) {
+            throw new IllegalArgumentException("Class cannot be null");
+        }
+        
+        // if we're talking to a proxy here, dig one level deeper to expose the
+        // underlying invocation handler (we do the same for injecting instances)
+        if (Proxy.isProxyClass(clazz)) {
+            object = Proxy.getInvocationHandler(object);
+            clazz = object.getClass();
+        }
+        
+        Method m = null;
+        for (int i = 0; i < signatures.length; i++) {
+            Class<?>[] signature = signatures[i];
+            m = getDeclaredMethod(clazz, name, signature, isSuper);
+            if (m != null) {
+                return m.invoke(object, parameters[i]);
+            }
+        }
+        throw new NoSuchMethodException(name);
+    }
+    
+    private static Method getDeclaredMethod(Class<?> clazz, String name, Class<?>[] signature, boolean isSuper) {
+        // first check our cache
+        Key key = new Key(clazz, name, signature);
+        Method m = null;
+        synchronized (m_methodCache) {
+            m = (Method) m_methodCache.get(key);
+            if (m != null) {
+                return m;
+            }
+            else if (m_methodCache.containsKey(key)) {
+                // the key is in our cache, it just happens to have a null value
+                return null;
+            }
+        }
+        // then do a lookup
+        try {
+            m = clazz.getDeclaredMethod(name, signature);
+            if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
+                m.setAccessible(true);
+            }
+        }
+        catch (NoSuchMethodException e) {
+        }
+        synchronized (m_methodCache) {
+            m_methodCache.put(key, m);
+        }
+        return m;
+    }
+    
+    public static class Key {
+        private final Class<?> m_clazz;
+        private final String m_name;
+        private final Class<?>[] m_signature;
+
+        public Key(Class<?> clazz, String name, Class<?>[] signature) {
+            m_clazz = clazz;
+            m_name = name;
+            m_signature = signature;
+        }
+
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((m_clazz == null) ? 0 : m_clazz.hashCode());
+            result = prime * result + ((m_name == null) ? 0 : m_name.hashCode());
+            result = prime * result + Arrays.hashCode(m_signature);
+            return result;
+        }
+
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            Key other = (Key) obj;
+            if (m_clazz == null) {
+                if (other.m_clazz != null)
+                    return false;
+            }
+            else if (!m_clazz.equals(other.m_clazz))
+                return false;
+            if (m_name == null) {
+                if (other.m_name != null)
+                    return false;
+            }
+            else if (!m_name.equals(other.m_name))
+                return false;
+            if (!Arrays.equals(m_signature, other.m_signature))
+                return false;
+            return true;
+        }
+    }
+    
+    @SuppressWarnings("serial")
+    public static class LRUMap extends LinkedHashMap<Key, Method> {
+        private final int m_size;
+        
+        public LRUMap(int size) {
+            m_size = size;
+        }
+        
+        protected boolean removeEldestEntry(java.util.Map.Entry<Key, Method> eldest) {
+            return size() > m_size;
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java
new file mode 100644
index 0000000..9bcc696
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ResourceDependency;
+import org.apache.felix.dm.context.DependencyContext;
+
+/**
+ * Resource adapter service implementation. This class extends the FilterService in order to catch
+ * some Service methods for configuring actual resource adapter service implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResourceAdapterImpl extends FilterComponent {
+    private Object m_callbackInstance = null;
+    private String m_callbackChanged = "changed";
+    private String m_callbackAdded = "setResource";
+    private final String m_resourceFilter;
+    
+    /**
+     * Creates a new Resource Adapter Service implementation.
+     * @param dm the dependency manager used to create our internal adapter service
+     */
+    public ResourceAdapterImpl(DependencyManager dm, String resourceFilter, boolean propagate, Object callbackInstance, String callbackSet, String callbackChanged) {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_callbackInstance = callbackInstance;
+        m_callbackAdded = callbackSet;
+        m_callbackChanged = callbackChanged;
+        m_resourceFilter = resourceFilter;
+        m_component.setImplementation(new ResourceAdapterDecorator(propagate))
+            .add(dm.createResourceDependency()
+                 .setFilter(resourceFilter)
+                 .setAutoConfig(false)
+                 .setCallbacks("added", "removed"))
+            .setCallbacks("init", null, "stop", null);
+    }
+    
+    public ResourceAdapterImpl(DependencyManager dm, String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackSet, String callbackChanged) {
+        super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
+        m_callbackInstance = callbackInstance;
+        m_callbackAdded = callbackSet;
+        m_callbackChanged = callbackChanged;
+        m_resourceFilter = resourceFilter;
+        m_component.setImplementation(new ResourceAdapterDecorator(propagateCallbackInstance, propagateCallbackMethod))
+            .add(dm.createResourceDependency()
+                 .setFilter(resourceFilter)
+                 .setAutoConfig(false)
+                 .setCallbacks("added", "removed"))
+            .setCallbacks("init", null, "stop", null);
+    }   
+    
+    public String getName() {
+        return "Resource Adapter" + ((m_resourceFilter != null) ? " with filter " + m_resourceFilter : "");
+    }
+
+    public class ResourceAdapterDecorator extends AbstractDecorator {
+        private final boolean m_propagate;
+        private final Object m_propagateCallbackInstance;
+        private final String m_propagateCallbackMethod;
+
+        public ResourceAdapterDecorator(boolean propagate) {
+            this(propagate, null, null);
+        }
+
+        public ResourceAdapterDecorator(Object propagateCallbackInstance, String propagateCallbackMethod) {
+            this(true, propagateCallbackInstance, propagateCallbackMethod);
+        }
+        
+        private ResourceAdapterDecorator(boolean propagate, Object propagateCallbackInstance, String propagateCallbackMethod) {
+            m_propagate = propagate;
+            m_propagateCallbackInstance = propagateCallbackInstance;
+            m_propagateCallbackMethod = propagateCallbackMethod;
+        }
+
+        public Component createService(Object[] properties) {
+            URL resource = (URL) properties[0]; 
+            Hashtable<String, Object> props = new Hashtable<>();
+            if (m_serviceProperties != null) {
+                Enumeration<String> e = m_serviceProperties.keys();
+                while (e.hasMoreElements()) {
+                    String key = e.nextElement();
+                    props.put(key, m_serviceProperties.get(key));
+                }
+            }
+            List<DependencyContext> dependencies = m_component.getDependencies();
+            // the first dependency is always the dependency on the resource, which
+            // will be replaced with a more specific dependency below
+            dependencies.remove(0);
+            ResourceDependency resourceDependency = m_manager.createResourceDependency()
+                 .setResource(resource)
+                 .setCallbacks(m_callbackInstance, m_callbackAdded, m_callbackChanged, null)
+                 .setAutoConfig(m_callbackAdded == null)
+                 .setRequired(true);
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                resourceDependency.setPropagate(m_propagateCallbackInstance, m_propagateCallbackMethod);
+            } else {
+                resourceDependency.setPropagate(m_propagate);
+            }
+            Component service = m_manager.createComponent()
+                .setInterface(m_serviceInterfaces, props)
+                .setImplementation(m_serviceImpl)
+                .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
+                .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
+                .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
+                .add(resourceDependency);
+            
+            configureAutoConfigState(service, m_component);
+
+            for (DependencyContext dc : dependencies) {
+                service.add((Dependency) dc.createCopy());
+            }
+
+            for (ComponentStateListener stateListener : m_stateListeners) {
+                service.add(stateListener);
+            }
+            return service;
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceDependencyImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceDependencyImpl.java
new file mode 100644
index 0000000..effd588
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceDependencyImpl.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentDependencyDeclaration;
+import org.apache.felix.dm.ResourceDependency;
+import org.apache.felix.dm.ResourceHandler;
+import org.apache.felix.dm.context.AbstractDependency;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.context.Event;
+import org.apache.felix.dm.context.EventType;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResourceDependencyImpl extends AbstractDependency<ResourceDependency> implements ResourceDependency, ResourceHandler, ComponentDependencyDeclaration {
+    private volatile ServiceRegistration m_registration;
+    private volatile String m_resourceFilter;
+    private volatile URL m_trackedResource;
+
+    public ResourceDependencyImpl() {
+    }
+    
+    public ResourceDependencyImpl(ResourceDependencyImpl prototype) {
+        super(prototype);
+        m_resourceFilter = prototype.m_resourceFilter;
+        m_trackedResource = prototype.m_trackedResource;
+    }
+    
+    @Override
+    public DependencyContext createCopy() {
+        return new ResourceDependencyImpl(this);
+    }
+    
+    @Override
+    public void start() {
+        Dictionary<String, Object> props = null;
+        if (m_trackedResource != null) {
+            props = new Hashtable<>();
+            props.put(ResourceHandler.URL, m_trackedResource);
+        } else {
+            if (m_resourceFilter != null) {
+                props = new Hashtable<>();
+                props.put(ResourceHandler.FILTER, m_resourceFilter);
+            }
+        }
+        m_registration = m_component.getBundleContext().registerService(ResourceHandler.class.getName(), this, props);
+        super.start();
+    }
+
+    @Override
+    public void stop() {
+        m_registration.unregister();
+        m_registration = null;
+        super.stop();
+    }
+
+    public void added(URL resource) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            getComponentContext().handleEvent(this, EventType.ADDED, new ResourceEventImpl(resource, null));
+        }
+    }
+    
+    public void added(URL resource, Dictionary<?, ?> resourceProperties) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            getComponentContext().handleEvent(this, EventType.ADDED, new ResourceEventImpl(resource, resourceProperties));
+        }
+    }
+        
+    public void changed(URL resource) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            m_component.handleEvent(this, EventType.CHANGED, new ResourceEventImpl(resource, null));
+        }
+    }
+    
+    public void changed(URL resource, Dictionary<?, ?> resourceProperties) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            m_component.handleEvent(this, EventType.CHANGED, new ResourceEventImpl(resource, resourceProperties));
+        }
+    }
+
+    public void removed(URL resource) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            m_component.handleEvent(this, EventType.REMOVED, new ResourceEventImpl(resource, null));
+        }
+    }
+    
+    public void removed(URL resource, Dictionary<?, ?> resourceProperties) {
+        if (m_trackedResource == null || m_trackedResource.equals(resource)) {
+            m_component.handleEvent(this, EventType.REMOVED, new ResourceEventImpl(resource, resourceProperties));
+        }
+    }
+    
+    @Override
+    public void invokeCallback(EventType type, Event ... e) {
+        switch (type) {
+        case ADDED:
+            if (m_add != null) {
+                invoke(m_add, e[0]);
+            }
+            break;
+        case CHANGED:
+            if (m_change != null) {
+                invoke (m_change, e[0]);
+            }
+            break;
+        case REMOVED:
+            if (m_remove != null) {
+                invoke (m_remove, e[0]);
+            }
+            break;
+        default:
+            break;
+        }
+    }
+    
+    private void invoke(String method, Event e) {
+        ResourceEventImpl re = (ResourceEventImpl) e;
+        URL serviceInstance = re.getResource();
+        Dictionary<?,?> resourceProperties = re.getProperties();
+       
+        m_component.invokeCallbackMethod(getInstances(), method,
+            new Class[][] {
+                    { Component.class, URL.class, Dictionary.class }, 
+                    { Component.class, URL.class },
+                    { Component.class },  
+                    { URL.class, Dictionary.class }, 
+                    { URL.class },
+                    { Object.class }, 
+                    {}},
+            new Object[][] {
+                    { m_component, serviceInstance, resourceProperties }, 
+                    { m_component, serviceInstance }, 
+                    { m_component }, 
+                    { serviceInstance, resourceProperties },
+                    { serviceInstance },
+                    { serviceInstance }, 
+                    {}}
+        );
+
+    }  
+                    
+    public ResourceDependency setResource(URL resource) {
+        m_trackedResource = resource;
+        return this;
+    }
+    
+    public ResourceDependency setFilter(String resourceFilter) {
+        ensureNotActive();
+        m_resourceFilter = resourceFilter;
+        return this;
+    }
+    
+    public ResourceDependency setFilter(String resourceFilter, String resourcePropertiesFilter) {
+        ensureNotActive();
+        m_resourceFilter = resourceFilter;
+        return this;
+    }
+    
+    @Override
+    public Class<?> getAutoConfigType() {
+        return URL.class;
+    }
+        
+    @SuppressWarnings("unchecked")
+    public Dictionary<String, Object> getProperties() {
+        ResourceEventImpl re = (ResourceEventImpl) m_component.getDependencyEvent(this);
+        if (re != null) {
+            URL resource = re.getResource();
+            Dictionary<String, Object> resourceProperties = re.getProperties();
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary<String, Object>) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod, new Class[][] {{ URL.class }}, new Object[][] {{ resource }});
+                }
+                catch (InvocationTargetException e) {
+                    m_component.getLogger().warn("Exception while invoking callback method", e.getCause());
+                }
+                catch (Throwable e) {
+                    m_component.getLogger().warn("Exception while trying to invoke callback method", e);
+                }
+                throw new IllegalStateException("Could not invoke callback");
+            }
+            else {
+                Hashtable<String, Object> props = new Hashtable<>();
+                props.put(ResourceHandler.HOST, resource.getHost());
+                props.put(ResourceHandler.PATH, resource.getPath());
+                props.put(ResourceHandler.PROTOCOL, resource.getProtocol());
+                props.put(ResourceHandler.PORT, Integer.toString(resource.getPort()));
+                // add the custom resource properties
+                if (resourceProperties != null) {
+                    Enumeration<String> properyKeysEnum = resourceProperties.keys(); 
+                    while (properyKeysEnum.hasMoreElements()) {
+                        String key = properyKeysEnum.nextElement();
+                        if (!key.equals(ResourceHandler.HOST) &&
+                                !key.equals(ResourceHandler.PATH) &&
+                                !key.equals(ResourceHandler.PROTOCOL) &&
+                                !key.equals(ResourceHandler.PORT)) {
+                            props.put(key, resourceProperties.get(key).toString());
+                        } else {
+                            m_component.getLogger().warn(
+                                "Custom resource property is overlapping with the default resource property for key: %s",
+                                key);
+                        }
+                    }
+                }
+                return props;
+            }
+        }
+        else {
+            throw new IllegalStateException("cannot find resource");
+        }
+    }
+    
+    @Override
+    public String getName() {
+        StringBuilder sb = new StringBuilder();
+        if (m_trackedResource != null) {
+            sb.append(m_trackedResource.toString());
+        }
+        if (m_resourceFilter != null) {
+            sb.append(m_resourceFilter);
+        }
+        return sb.toString();
+    }
+    
+    @Override
+    public String getSimpleName() {
+        return m_trackedResource != null ? m_trackedResource.toString() : null;
+    }
+
+    @Override
+    public String getFilter() {
+        return m_resourceFilter;
+    }
+
+    @Override
+    public String getType() {
+        return "resource";
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceEventImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceEventImpl.java
new file mode 100644
index 0000000..b655bed
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ResourceEventImpl.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.dm.impl;
+
+import java.net.URL;
+import java.util.Dictionary;
+
+import org.apache.felix.dm.context.Event;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResourceEventImpl extends Event {
+    final Dictionary<Object, Object> m_resourceProperties;
+    
+    @SuppressWarnings("unchecked")
+    public ResourceEventImpl(URL resource, Dictionary<?, ?> resourceProperties) {
+        super(resource);
+        m_resourceProperties = (Dictionary<Object, Object>) resourceProperties;
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public <K,V> Dictionary<K,V> getProperties() {
+        return (Dictionary<K, V>) ((Dictionary<K,V>) m_resourceProperties == null ? EMPTY_PROPERTIES : m_resourceProperties);
+    }
+
+    public URL getResource() {
+        return getEvent();
+    }
+        
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ResourceEventImpl) {
+            ResourceEventImpl r1 = this;
+            ResourceEventImpl r2 = (ResourceEventImpl) obj;
+            boolean match = r1.getResource().equals(r2.getResource());
+            if (match) {
+                Dictionary<?,?> d1 = getProperties();
+                Dictionary<?,?> d2 = r2.getProperties();
+                
+                if (d1 == null) {
+                	return d2 == null ? match : false;
+                }
+                else {
+                	return d1.equals(d2);
+                }
+            }
+        }
+        return false;
+    }
+    
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + getResource().hashCode();
+        result = prime * result + ((getProperties() == null) ? 0 : getProperties().hashCode());
+        return result;
+    }
+
+    @Override
+    public int compareTo(Event that) {
+        if (this.equals(that)) {
+            return 0;
+        }
+        
+        // Sort by resource name.
+        return getResource().toString().compareTo(((ResourceEventImpl) that).getResource().toString());
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/SerialExecutor.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/SerialExecutor.java
new file mode 100644
index 0000000..9ef6c9f
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/SerialExecutor.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.felix.dm.Logger;
+import org.osgi.service.log.LogService;
+
+/**
+ * Allows you to enqueue tasks from multiple threads and then execute
+ * them on one thread sequentially. It assumes no 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. <p>
+ * 
+ * This class is <b>lock free</b> by design and ensures <b>"safe object publication"</b> between scheduling threads and
+ * actual executing thread: if one thread T1 schedules a task, but another thread T2 actually 
+ * executes it, then all the objects from the T1 thread will be "safely published" to the executing T2 thread.
+ * Safe publication is ensured  because we are using a ConcurrentLinkedQueue.
+ * (see [1], chapter 3.5.3 (Safe publication idioms). 
+ * 
+ * [1] Java Concurrency In Practice, Addison Wesley
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SerialExecutor implements Executor {
+    /** 
+     * All tasks scheduled are stored there and only one thread may run them.
+     **/
+    protected final ConcurrentLinkedQueue<Runnable> m_tasks = new ConcurrentLinkedQueue<Runnable>();
+
+    /** 
+     * Thread currently executing the task queue. 
+     **/
+    protected final AtomicReference<Thread> m_runningThread = new AtomicReference<>();
+
+    /** 
+     * Logger used when a task execution throws an exception 
+     **/
+    private final Logger m_logger;
+
+    /**
+     * Makes a new SerialExecutor
+     * @param logger used when a task execution throws an exception. Can be null if no exception should be logger.
+     */
+    public SerialExecutor(Logger logger) {
+        m_logger = logger;
+    }
+
+    /**
+     * Enqueues a task for later execution. You must call {@link #execute()} in order
+     * to trigger the task execution, which may or may not be executed by
+     * your current thread.
+     */
+    public void schedule(Runnable task) {
+        m_tasks.add(task); // No need to synchronize, m_tasks is a concurrent linked queue.
+    }
+
+    /**
+     * Executes any pending tasks, enqueued using the {@link SerialExecutor#schedule(Runnable)} method. 
+     * 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() {
+        Thread currentThread = Thread.currentThread();
+        if (m_runningThread.compareAndSet(null, currentThread)) {
+            runTasks(currentThread);
+        }
+    }
+
+    /**
+     * Schedules a task for execution, and then attempts to execute it. This method is thread safe, so 
+     * multiple threads can try to execute a task but only the first will be executed, other threads will 
+     * return immediately, and the first thread will execute the tasks scheduled by the other threads.<p>
+     * <p>
+     * This method is reentrant: if the current thread is currently being executed by this executor, then 
+     * the task passed to this method will be executed immediately, from the current invoking thread
+     * (inline execution).
+     */
+    public void execute(Runnable task) {
+        Thread currentThread = Thread.currentThread();
+        if (m_runningThread.get() == currentThread) {
+            runTask(task);
+        } else {
+            schedule(task);  
+            execute();
+        }
+    }
+    
+    /**
+     * Run all pending tasks
+     * @param currentRunninghread the current executing thread
+     */
+    private void runTasks(Thread currentRunninghread) {
+        do {
+            try {
+                Runnable task;
+                ConcurrentLinkedQueue<Runnable> tasks = m_tasks;
+
+                while ((task = tasks.poll()) != null) {
+                    runTask(task);
+                }
+            }
+            finally {
+                m_runningThread.set(null);
+            }
+        }
+        // We must test again if some tasks have been scheduled after our "while" loop above, but before the
+        // m_runningThread reference has been reset to null.
+        while (!m_tasks.isEmpty() && m_runningThread.compareAndSet(null, currentRunninghread));
+    }
+
+    /**
+     * Run a given task.
+     * @param task the task to execute.
+     */
+    void runTask(Runnable command) {
+        try {
+            command.run();
+        }
+        catch (Throwable t) {
+            if (m_logger != null) {
+                m_logger.log(LogService.LOG_ERROR, "Error processing tasks", t);
+            } else {
+                t.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "[Executor: queue size: " + m_tasks.size() + "]";
+    }
+}
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceDependencyImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceDependencyImpl.java
new file mode 100644
index 0000000..ab4daf4
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceDependencyImpl.java
@@ -0,0 +1,554 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentDeclaration;
+import org.apache.felix.dm.ServiceDependency;
+import org.apache.felix.dm.context.AbstractDependency;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.context.Event;
+import org.apache.felix.dm.context.EventType;
+import org.apache.felix.dm.tracker.ServiceTracker;
+import org.apache.felix.dm.tracker.ServiceTrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceDependencyImpl extends AbstractDependency<ServiceDependency> implements ServiceDependency, ServiceTrackerCustomizer {
+	protected volatile ServiceTracker m_tracker;
+    protected String m_swap;
+    protected volatile Class<?> m_trackedServiceName;
+    private volatile String m_trackedServiceFilter;
+    private volatile String m_trackedServiceFilterUnmodified;
+    private volatile ServiceReference m_trackedServiceReference;
+    private volatile Object m_defaultImplementation;
+    private volatile Object m_defaultImplementationInstance;
+    private volatile Object m_nullObject;
+    private boolean m_debug = false;
+    private String m_debugKey;
+    private long m_trackedServiceReferenceId;
+    
+    public ServiceDependency setDebug(String debugKey) {
+    	m_debugKey = debugKey;
+    	m_debug = true;
+    	return this;
+    }
+
+    /**
+     * Entry to wrap service properties behind a Map.
+     */
+    private static final class ServicePropertiesMapEntry implements Map.Entry<String, Object> {
+        private final String m_key;
+        private Object m_value;
+
+        public ServicePropertiesMapEntry(String key, Object value) {
+            m_key = key;
+            m_value = value;
+        }
+
+        public String 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;
+        }
+
+        @SuppressWarnings("unchecked")
+        public boolean equals(Object o) {
+            if (!(o instanceof Map.Entry)) {
+                return false;
+            }
+            Map.Entry<String, Object> e = (Map.Entry<String, Object>) 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<String, Object> {
+        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<Map.Entry<String, Object>> entrySet() {
+            Set<Map.Entry<String, Object>> 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;
+        }
+    }
+    
+	public ServiceDependencyImpl() {
+	}
+	
+	public ServiceDependencyImpl(ServiceDependencyImpl prototype) {
+		super(prototype);
+        m_trackedServiceName = prototype.m_trackedServiceName;
+        m_nullObject = prototype.m_nullObject;
+        m_trackedServiceFilter = prototype.m_trackedServiceFilter;
+        m_trackedServiceFilterUnmodified = prototype.m_trackedServiceFilterUnmodified;
+        m_trackedServiceReference = prototype.m_trackedServiceReference;
+        m_autoConfigInstance = prototype.m_autoConfigInstance;
+        m_defaultImplementation = prototype.m_defaultImplementation;
+        m_autoConfig = prototype.m_autoConfig;
+	}
+	    	    
+    // --- CREATION
+    			
+    public ServiceDependency setCallbacks(Object instance, String added, String changed, String removed, String swapped) {
+        setCallbacks(instance, added, changed, removed);
+        m_swap = swapped;
+        return this;
+    }
+    
+    public ServiceDependency setCallbacks(String added, String changed, String removed, String swapped) {
+        setCallbacks(added, changed, removed);
+        m_swap = swapped;
+        return this;
+    }
+		
+    @Override
+    public ServiceDependency setDefaultImplementation(Object implementation) {
+        ensureNotActive();
+        m_defaultImplementation = implementation;
+        return this;
+    }   
+
+    @Override
+   	public ServiceDependency setService(Class<?> serviceName) {
+        setService(serviceName, null, null);
+        return this;
+    }
+
+    public ServiceDependency setService(Class<?> serviceName, String serviceFilter) {
+        setService(serviceName, null, serviceFilter);
+        return this;
+    }
+
+    public ServiceDependency setService(String serviceFilter) {
+        if (serviceFilter == null) {
+            throw new IllegalArgumentException("Service filter cannot be null.");
+        }
+        setService(null, null, serviceFilter);
+        return this;
+    }
+
+    public ServiceDependency setService(Class<?> serviceName, ServiceReference serviceReference) {
+        setService(serviceName, serviceReference, null);
+        return this;
+    }
+
+	@Override
+	public void start() {
+        if (m_trackedServiceName != null) {
+            BundleContext ctx = m_component.getBundleContext();
+            if (m_trackedServiceFilter != null) {
+                try {
+                    m_tracker = new ServiceTracker(ctx, ctx.createFilter(m_trackedServiceFilter), this);
+                } catch (InvalidSyntaxException e) {
+                    throw new IllegalStateException("Invalid filter definition for dependency: "
+                        + m_trackedServiceFilter);
+                }
+            } else if (m_trackedServiceReference != null) {
+                m_tracker = new ServiceTracker(ctx, m_trackedServiceReference, this);
+            } else {
+                m_tracker = new ServiceTracker(ctx, m_trackedServiceName.getName(), this);
+            }
+        } else {
+            throw new IllegalStateException("Could not create tracker for dependency, no service name specified.");
+        }
+        if (m_debug) {
+            m_tracker.setDebug(m_debugKey);
+        }
+        m_tracker.open();
+        super.start();
+	}
+	
+	@Override
+	public void stop() {
+	    m_tracker.close();
+	    m_tracker = null;
+	    super.stop();
+	}
+
+	@Override
+	public Object addingService(ServiceReference reference) {
+		try {
+		    return m_component.getBundleContext().getService(reference);
+		} catch (IllegalStateException e) {
+		    // most likely our bundle is being stopped. Only log an exception if our component is enabled.
+		    if (m_component.isActive()) {
+                m_component.getLogger().warn("could not handle service dependency for component %s", e,
+                    m_component.getComponentDeclaration().getClassName());
+		    }
+		    return null;		    
+		}
+	}
+
+	@Override
+	public void addedService(ServiceReference reference, Object service) {
+		if (m_debug) {
+			System.out.println(m_debugKey + " addedService: ref=" + reference + ", service=" + service);
+		}
+        m_component.handleEvent(this, EventType.ADDED,
+            new ServiceEventImpl(m_component.getBundle(), m_component.getBundleContext(), reference, service));
+	}
+
+	@Override
+	public void modifiedService(ServiceReference reference, Object service) {
+        m_component.handleEvent(this, EventType.CHANGED,
+            new ServiceEventImpl(m_component.getBundle(), m_component.getBundleContext(), reference, service));
+	}
+
+	@Override
+	public void removedService(ServiceReference reference, Object service) {
+        m_component.handleEvent(this, EventType.REMOVED,
+            new ServiceEventImpl(m_component.getBundle(), m_component.getBundleContext(), reference, service));
+	}
+	
+    @Override
+    public void invokeCallback(EventType type, Event ... events) {
+        switch (type) {
+        case ADDED:
+            if (m_add != null) {
+                invoke (m_add, events[0], getInstances());
+            }
+            break;
+        case CHANGED:
+            if (m_change != null) {
+                invoke (m_change, events[0], getInstances());
+            }
+            break;
+        case REMOVED:
+            if (m_remove != null) {
+                invoke (m_remove, events[0], getInstances());
+            }
+            break;
+        case SWAPPED:
+            if (m_swap != null) {
+                ServiceEventImpl oldE = (ServiceEventImpl) events[0];
+                ServiceEventImpl newE = (ServiceEventImpl) events[1];
+                invokeSwap(m_swap, oldE.getReference(), oldE.getEvent(), newE.getReference(), newE.getEvent(),
+                    getInstances());
+            }
+            break;
+        }
+    }
+
+	@Override
+    public Class<?> getAutoConfigType() {
+        return m_trackedServiceName;
+    }
+	
+    @Override
+    public DependencyContext createCopy() {
+        return new ServiceDependencyImpl(this);
+    }
+    
+    @Override
+    public String getName() {
+        StringBuilder sb = new StringBuilder();
+        if (m_trackedServiceName != null) {
+            sb.append(m_trackedServiceName.getName());
+            if (m_trackedServiceFilterUnmodified != null) {
+                sb.append(' ');
+                sb.append(m_trackedServiceFilterUnmodified);
+            }
+        }
+        if (m_trackedServiceReference != null) {
+            sb.append("{service.id=" + m_trackedServiceReference.getProperty(Constants.SERVICE_ID) + "}");
+        }
+        return sb.toString();
+    }
+    
+    @Override
+    public String getSimpleName() {
+        if (m_trackedServiceName != null) {
+            return m_trackedServiceName.getName();
+        }
+        return null;
+    }
+
+    @Override
+    public String getFilter() {
+        if (m_trackedServiceFilterUnmodified != null) {
+            return m_trackedServiceFilterUnmodified;
+        } else if (m_trackedServiceReference != null) {
+            return new StringBuilder("(").append(Constants.SERVICE_ID).append("=").append(
+                String.valueOf(m_trackedServiceReferenceId)).append(")").toString();
+        } else {
+            return null;
+        }
+    }
+    
+    @Override
+    public String getType() {
+        return "service";
+    }
+
+	@SuppressWarnings("unchecked")
+    @Override
+    public Dictionary<String, Object> getProperties() {
+        ServiceEventImpl se = (ServiceEventImpl) m_component.getDependencyEvent(this);
+        if (se != null) {
+            if (m_propagateCallbackInstance != null && m_propagateCallbackMethod != null) {
+                try {
+                    return (Dictionary<String, Object>) InvocationUtil.invokeCallbackMethod(m_propagateCallbackInstance, m_propagateCallbackMethod,
+                            new Class[][]{{ServiceReference.class, Object.class}, {ServiceReference.class}}, new Object[][]{
+                                    {se.getReference(), se.getEvent()}, {se.getReference()}});
+                } catch (InvocationTargetException e) {
+                    m_component.getLogger().warn("Exception while invoking callback method", e.getCause());
+                } catch (Throwable e) {
+                    m_component.getLogger().warn("Exception while trying to invoke callback method", e);
+                }
+                throw new IllegalStateException("Could not invoke callback");
+            } else {
+                Hashtable<String, Object> props = new Hashtable<>();
+                String[] keys = se.getReference().getPropertyKeys();
+                for (int i = 0; i < keys.length; i++) {
+                    if (!(keys[i].equals(Constants.SERVICE_ID) || keys[i].equals(Constants.SERVICE_PID))) {
+                        props.put(keys[i], se.getReference().getProperty(keys[i]));
+                    }
+                }
+                return props;
+            }
+        } else {
+            throw new IllegalStateException("cannot find service reference");
+        }
+    }	
+        
+    /** Internal method to set the name, service reference and/or filter. */
+    private void setService(Class<?> serviceName, ServiceReference serviceReference, String serviceFilter) {
+        ensureNotActive();
+        if (serviceName == null) {
+            m_trackedServiceName = Object.class;
+        }
+        else {
+            m_trackedServiceName = serviceName;
+        }
+        if (serviceFilter != null) {
+            m_trackedServiceFilterUnmodified = serviceFilter;
+            if (serviceName == null) {
+                m_trackedServiceFilter = serviceFilter;
+            }
+            else {
+                m_trackedServiceFilter = "(&(" + Constants.OBJECTCLASS + "=" + serviceName.getName() + ")"
+                    + serviceFilter + ")";
+            }
+        }
+        else {
+            m_trackedServiceFilterUnmodified = null;
+            m_trackedServiceFilter = null;
+        }
+        if (serviceReference != null) {
+            m_trackedServiceReference = serviceReference;
+            if (serviceFilter != null) {
+                throw new IllegalArgumentException("Cannot specify both a filter and a service reference.");
+            }
+            m_trackedServiceReferenceId = (Long) m_trackedServiceReference.getProperty(Constants.SERVICE_ID);
+        }
+        else {
+            m_trackedServiceReference = null;
+        }
+    }
+    
+    @Override
+    public Object getDefaultService(boolean nullObject) {
+        Object service = null;
+        if (isAutoConfig()) {
+            service = getDefaultImplementation();
+            if (service == null && nullObject) {
+                service = getNullObject();
+            }
+        }
+        return service;
+    }
+        
+    private Object getNullObject() {
+        if (m_nullObject == null) {
+            Class<?> trackedServiceName;
+            trackedServiceName = m_trackedServiceName;
+            try {
+                m_nullObject = Proxy.newProxyInstance(trackedServiceName.getClassLoader(),
+                    new Class[] { trackedServiceName }, new DefaultNullObject());
+            }
+            catch (Throwable err) {
+                m_component.getLogger().err("Could not create null object for %s.", err, trackedServiceName);
+            }
+        }
+        return m_nullObject;
+    }
+
+    private Object getDefaultImplementation() {
+        if (m_defaultImplementation != null) {
+            if (m_defaultImplementation instanceof Class) {
+                try {
+                    m_defaultImplementationInstance = ((Class<?>) m_defaultImplementation).newInstance();
+                }
+                catch (Throwable e) {
+                    m_component.getLogger().err("Could not create default implementation instance of class %s.", e,
+                        m_defaultImplementation);
+                }
+            }
+            else {
+                m_defaultImplementationInstance = m_defaultImplementation;
+            }
+        }
+        return m_defaultImplementationInstance;
+    }
+
+    public void invoke(String method, Event e, Object[] instances) {
+        ServiceEventImpl se = (ServiceEventImpl) e;
+        ServicePropertiesMap propertiesMap = new ServicePropertiesMap(se.getReference());
+        Dictionary<?,?> properties = se.getProperties();
+        m_component.invokeCallbackMethod(instances, method,
+            new Class[][]{
+                {Component.class, ServiceReference.class, m_trackedServiceName},
+                {Component.class, ServiceReference.class, Object.class}, 
+                {Component.class, ServiceReference.class},
+                {Component.class, m_trackedServiceName}, 
+                {Component.class, Object.class}, 
+                {Component.class},
+                {Component.class, Map.class, m_trackedServiceName},
+                {ServiceReference.class, m_trackedServiceName},
+                {ServiceReference.class, Object.class}, 
+                {ServiceReference.class},
+                {m_trackedServiceName}, 
+                {m_trackedServiceName, Map.class}, 
+                {Map.class, m_trackedServiceName}, 
+                {m_trackedServiceName, Dictionary.class}, 
+                {Dictionary.class, m_trackedServiceName}, 
+                {Object.class}, 
+                {}},
+            
+            new Object[][]{
+                {m_component, se.getReference(), se.getEvent()},
+                {m_component, se.getReference(), se.getEvent()}, 
+                {m_component, se.getReference()}, 
+                {m_component, se.getEvent()},
+                {m_component, se.getEvent()},
+                {m_component},
+                {m_component, propertiesMap, se.getEvent()},
+                {se.getReference(), se.getEvent()},
+                {se.getReference(), se.getEvent()}, 
+                {se.getReference()}, 
+                {se.getEvent()}, 
+                {se.getEvent(), propertiesMap},
+                {propertiesMap, se.getEvent()},
+                {se.getEvent(), properties},
+                {properties, se.getEvent()},
+                {se.getEvent()}, 
+                {}}
+        );
+    }
+        
+    public void invokeSwap(String swapMethod, ServiceReference previousReference, Object previous,
+			ServiceReference currentReference, Object current, Object[] instances) {
+    	if (m_debug) {
+    		System.out.println("invoke swap: " + swapMethod + " on component " + m_component + ", instances: " + Arrays.toString(instances) + " - " + ((ComponentDeclaration)m_component).getState());
+    	}
+    	try {
+		m_component.invokeCallbackMethod(instances, swapMethod,
+				new Class[][]{
+            		{m_trackedServiceName, m_trackedServiceName}, 
+            		{Object.class, Object.class},
+            		{ServiceReference.class, m_trackedServiceName, ServiceReference.class, m_trackedServiceName},
+            		{ServiceReference.class, Object.class, ServiceReference.class, Object.class},
+            		{Component.class, m_trackedServiceName, m_trackedServiceName}, 
+            		{Component.class, Object.class, Object.class},
+            		{Component.class, ServiceReference.class, m_trackedServiceName, ServiceReference.class, m_trackedServiceName},
+            		{Component.class, ServiceReference.class, Object.class, ServiceReference.class, Object.class}}, 
+	            
+            	new Object[][]{
+                    {previous, current}, 
+                    {previous, current}, 
+                    {previousReference, previous, currentReference, current},
+                    {previousReference, previous, currentReference, current}, {m_component, previous, current},
+                    {m_component, previous, current}, {m_component, previousReference, previous, currentReference, current},
+                    {m_component, previousReference, previous, currentReference, current}}
+			);
+    	} catch (Throwable e) {
+    	    m_component.getLogger().err("Could not invoke swap callback", e);
+    	}
+	}
+
+	@Override
+	public void swappedService(final ServiceReference reference, final Object service,
+			final ServiceReference newReference, final Object newService) {
+		if (m_swap != null) {
+			// it will not trigger a state change, but the actual swap should be scheduled to prevent things
+			// getting out of order.		    		    
+		    // We delegate the swap handling to the ComponentImpl, which is the class responsible for state management.
+		    // The ComponentImpl will first check if the component is in the proper state so the swap method can be invoked.		    
+            m_component.handleEvent(this, EventType.SWAPPED,
+                new ServiceEventImpl(m_component.getBundle(), m_component.getBundleContext(), reference, service),
+                new ServiceEventImpl(m_component.getBundle(), m_component.getBundleContext(), newReference, newService));
+		} else {
+			addedService(newReference, newService);
+			removedService(reference, service);
+		}
+	}	
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceEventImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceEventImpl.java
new file mode 100644
index 0000000..a27147d
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceEventImpl.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.Dictionary;
+
+import org.apache.felix.dm.context.Event;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceEventImpl extends Event {
+    /**
+     * The service reference on which a service dependency depends on
+     */
+	private final ServiceReference m_reference; 
+		
+    /**
+     * The bundle context of the bundle which has created the service dependency. If not null, 
+     * will be used in close method when ugetting the service reference of the dependency.
+     */
+	private final BundleContext m_bundleContext;
+	
+    /**
+     * The bundle which has created the service dependency. If not null, will be used to ensure that the bundle is still active before
+     * ungetting the service reference of the dependency. (ungetting a service reference on a bundle which is not
+     * active triggers an exception, and this may degrade performance, especially when doing some benchmarks).
+     */
+	private final Bundle m_bundle;
+	
+	public ServiceEventImpl(ServiceReference reference, Object service) {
+	    this(null, null, reference, service);
+	}
+
+    public ServiceEventImpl(Bundle bundle, BundleContext bundleContext, ServiceReference reference, Object service) {
+	    super(service);
+	    m_bundle = bundle;
+	    m_bundleContext = bundleContext;
+		m_reference = reference;
+	}
+	
+	/**
+	 * Returns the bundle which has declared a service dependency.
+	 */
+	public Bundle getBundle() {
+	    return m_bundle;
+	}
+	
+    /**
+     * Returns the context of the bundle which has declared a service dependency.
+     */
+	public BundleContext getBundleContext() {
+	    return m_bundleContext;
+	}
+
+	/**
+	 * Returns the reference service dependency.
+	 */
+	public ServiceReference getReference() {
+		return m_reference;
+	}
+	    
+    @SuppressWarnings("unchecked")
+	@Override
+    public Dictionary<String, Object> getProperties() {
+        return ServiceUtil.propertiesToDictionary(m_reference);
+    }
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof ServiceEventImpl) {
+			return getReference().equals(((ServiceEventImpl) obj).getReference());
+		}
+		return false;
+	}
+	
+	@Override
+	public int hashCode() {
+		return getReference().hashCode();
+	}
+
+    @Override
+    public int compareTo(Event b) {
+    	return getReference().compareTo(((ServiceEventImpl) b).getReference());
+    }
+        
+    @Override
+    public String toString() {
+    	return getEvent().toString();
+    }
+
+    @Override
+    public void close() {
+        if (m_bundleContext != null) {
+            try {
+                // Optimization: don't call ungetService if the bundle referring to the service is not active. 
+                // This optim is important when doing benchmarks where the referring bundle is being stopped 
+                // while some dependencies are lost concurrently (here we want to avoid having many exception thrown).
+                if (m_bundle == null || m_bundle.getState() == Bundle.ACTIVE) {
+                    m_bundleContext.ungetService(m_reference);
+                }
+            } catch (IllegalStateException e) {}
+        }
+    }
+}
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceRegistrationImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceRegistrationImpl.java
new file mode 100644
index 0000000..4604acb
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceRegistrationImpl.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.dm.impl;
+
+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();
+    }
+
+    @SuppressWarnings("rawtypes")
+    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/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceUtil.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceUtil.java
new file mode 100644
index 0000000..cb7bfb6
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/ServiceUtil.java
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * OSGi service utilities.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceUtil {
+    /**
+     * Useful when needing to provide empty service properties.
+     */
+    public final static Dictionary<String, Object> EMPTY_PROPERTIES = new Hashtable<>();
+
+    /**
+     * Returns the service ranking of a service, based on its service reference. If
+     * the service has a property specifying its ranking, that will be returned. If
+     * not, the default ranking of zero will be returned.
+     * 
+     * @param ref the service reference to determine the ranking for
+     * @return the ranking
+     */
+    public static int getRanking(ServiceReference ref) {
+        return getRankingAsInteger(ref).intValue();
+    }
+    
+    /**
+     * Returns the service ranking of a service, based on its service reference. If
+     * the service has a property specifying its ranking, that will be returned. If
+     * not, the default ranking of zero will be returned.
+     * 
+     * @param ref the service reference to determine the ranking for
+     * @return the ranking
+     */
+    public static Integer getRankingAsInteger(ServiceReference ref) {
+        Integer rank = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
+        if (rank != null) {
+            return rank;
+        }
+        return new Integer(0);
+    }
+    
+    /**
+     * Returns the service ID of a service, based on its service reference. This
+     * method is aware of service aspects as defined by the dependency manager and
+     * will return the ID of the orginal service if you give it an aspect.
+     * 
+     * @param ref the service reference to determine the service ID of
+     * @return the service ID
+     */
+    public static long getServiceId(ServiceReference ref) {
+        return getServiceIdAsLong(ref).longValue();
+    }
+    
+    /**
+     * Returns the service ID of a service, based on its service reference. This
+     * method is aware of service aspects as defined by the dependency manager and
+     * will return the ID of the orginal service if you give it an aspect.
+     * 
+     * @param ref the service reference to determine the service ID of
+     * @return the service ID
+     */
+    public static Long getServiceIdAsLong(ServiceReference ref) {
+    	return getServiceIdObject(ref);
+    }
+    
+    public static Long getServiceIdObject(ServiceReference ref) {
+        Long aid = (Long) ref.getProperty(DependencyManager.ASPECT);
+        if (aid != null) {
+            return aid;
+        }
+        Long sid = (Long) ref.getProperty(Constants.SERVICE_ID);
+        if (sid != null) {
+            return sid;
+        }
+        throw new IllegalArgumentException("Invalid service reference, no service ID found");
+    }
+
+    /**
+     * Determines if the service is an aspect as defined by the dependency manager.
+     * Aspects are defined by a property and this method will check for its presence.
+     * 
+     * @param ref the service reference
+     * @return <code>true</code> if it's an aspect, <code>false</code> otherwise
+     */
+    public static boolean isAspect(ServiceReference ref) {
+        Long aid = (Long) ref.getProperty(DependencyManager.ASPECT);
+        return (aid != null);
+    }
+    
+    /**
+     * Converts a service reference to a string, listing both the bundle it was
+     * registered from and all properties.
+     * 
+     * @param ref the service reference
+     * @return a string representation of the service
+     */
+    public static String toString(ServiceReference ref) {
+        if (ref == null) {
+            return "ServiceReference[null]";
+        }
+        else {
+            StringBuffer buf = new StringBuffer();
+            Bundle bundle = ref.getBundle();
+            if (bundle != null) {
+                buf.append("ServiceReference[");
+                buf.append(bundle.getBundleId());
+                buf.append("]{");
+            }
+            else {
+                buf.append("ServiceReference[unregistered]{");
+            }
+            buf.append(propertiesToString(ref, null));
+            buf.append("}");
+            return buf.toString();
+        }
+    }
+    
+    /**
+     * Converts the properties of a service reference to a string.
+     * 
+     * @param ref the service reference
+     * @param exclude a list of properties to exclude, or <code>null</code> to show everything
+     * @return a string representation of the service properties
+     */
+    public static String propertiesToString(ServiceReference ref, List<String> exclude) {
+        StringBuffer buf = new StringBuffer();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            if (i > 0) { 
+                buf.append(','); 
+            }
+            buf.append(keys[i]);
+            buf.append('=');
+            Object val = ref.getProperty(keys[i]);
+            if (exclude == null || !exclude.contains(val)) {
+                if (val instanceof String[]) {
+                    String[] valArray = (String[]) val;
+                    StringBuffer valBuf = new StringBuffer();
+                    valBuf.append('{');
+                    for (int j = 0; j < valArray.length; j++) {
+                        if (valBuf.length() > 1) {
+                            valBuf.append(',');
+                        }
+                        valBuf.append(valArray[j].toString());
+                    }
+                    valBuf.append('}');
+                    buf.append(valBuf);
+                }
+                else {
+                    buf.append(val.toString());
+                }
+            }
+        }
+        return buf.toString();
+    }
+    
+    /**
+     * Wraps ServiceReference properties behind a Dictionary object.
+     * @param ref the ServiceReference to wrap
+     * @return a new Dictionary used to wrap the ServiceReference properties
+     */
+    public static Dictionary<String, Object> propertiesToDictionary(final ServiceReference ref) {
+        return new Dictionary<String, Object>() {
+            private Dictionary<String, Object> m_wrapper;
+            
+            @Override
+            public int size() {
+                return getWrapper().size();
+            }
+
+            @Override
+            public boolean isEmpty() {
+                return getWrapper().isEmpty();
+            }
+
+            @Override
+            public Enumeration<String> keys() {
+                return getWrapper().keys();
+            }
+
+            @Override
+            public Enumeration<Object> elements() {
+                return getWrapper().elements();
+            }
+
+            @Override
+            public Object get(Object key) {
+                return ref.getProperty(key.toString());
+            }
+
+            @Override
+            public Object put(String key, Object value) {
+                throw new UnsupportedOperationException("Unmodified Dictionary.");
+            }
+
+            @Override
+            public Object remove(Object key) {
+                throw new UnsupportedOperationException("Unmodified Dictionary.");
+            }
+            
+            @Override
+            public String toString() {
+                return getWrapper().toString();
+            }
+            
+            private synchronized Dictionary<String, Object> getWrapper() {
+                if (m_wrapper == null) {
+                    m_wrapper = new Hashtable<String, Object>();
+                    String[] keys = ref.getPropertyKeys();
+                    for (String key : keys) {
+                        m_wrapper.put(key, ref.getProperty(key));
+                    }                    
+                }
+                return m_wrapper;
+            }
+        };
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/TemporalServiceDependencyImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/TemporalServiceDependencyImpl.java
new file mode 100644
index 0000000..c329307
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/TemporalServiceDependencyImpl.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.ServiceDependency;
+import org.apache.felix.dm.context.EventType;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Temporal Service dependency implementation, used to hide temporary service dependency "outage".
+ * Only works with a required dependency.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TemporalServiceDependencyImpl extends ServiceDependencyImpl implements ServiceDependency, InvocationHandler {
+    // Max millis to wait for service availability.
+    private final long m_timeout;
+        
+    // Framework bundle (we use it to detect if the framework is stopping)
+    private final Bundle m_frameworkBundle;
+
+    // The service proxy, which blocks when service is not available.
+    private volatile Object m_serviceInstance;
+
+    /**
+     * Creates a new Temporal Service Dependency.
+     * 
+     * @param context The bundle context of the bundle which is instantiating this dependency object
+     * @param logger the logger our Internal logger for logging events.
+     * @see DependencyActivatorBase#createTemporalServiceDependency()
+     */
+    public TemporalServiceDependencyImpl(BundleContext context, long timeout) {
+        super.setRequired(true);
+        if (timeout < 0) {
+            throw new IllegalArgumentException("Invalid timeout value: " + timeout);
+        }
+        m_timeout = timeout;
+        m_frameworkBundle = context.getBundle(0);
+    }
+
+    /**
+     * Sets the required flag which determines if this service is required or not. This method
+     * just override the superclass method in order to check if the required flag is true 
+     * (optional dependency is not supported by this class).
+     * 
+     * @param required the required flag, which must be set to true
+     * @return this service dependency
+     * @throws IllegalArgumentException if the "required" parameter is not true.
+     */
+    @Override
+    public ServiceDependency setRequired(boolean required) {
+        if (! required) {
+            throw new IllegalArgumentException("A Temporal Service dependency can't be optional");
+        }
+        super.setRequired(required);
+        return this;
+    }
+    
+    /**
+     * The ServiceTracker calls us here in order to inform about a service arrival.
+     */
+    @Override
+    public void addedService(ServiceReference ref, Object service) {
+        // Update our service cache, using the tracker. We do this because the
+        // just added service might not be the service with the highest rank ...
+        boolean makeAvailable = false;
+        synchronized (this) {
+            if (m_serviceInstance == null) {
+                m_serviceInstance = Proxy.newProxyInstance(m_trackedServiceName.getClassLoader(), new Class[] { m_trackedServiceName }, this);
+                makeAvailable = true;
+            }
+        }
+        if (makeAvailable) {
+            getComponentContext().handleEvent(this, EventType.ADDED,
+                new ServiceEventImpl(m_component.getBundle(), m_component.getBundleContext(), ref, m_serviceInstance));
+        } else {
+            // This added will possibly unblock our invoke() method (if it's blocked in m_tracker.waitForService method).
+        }
+    }
+
+    /**
+     * The ServiceTracker calls us here when a tracked service properties are modified.
+     */
+    @Override
+    public void modifiedService(ServiceReference ref, Object service) {
+        // We don't care.
+    }
+
+    /**
+     * The ServiceTracker calls us here when a tracked service is lost.
+     */
+    @Override
+    public void removedService(ServiceReference ref, Object service) {
+        // If we detect that the fwk is stopping, we behave as our superclass. That is:
+        // the lost dependency has to trigger our service deactivation, since the fwk is stopping
+        // and the lost dependency won't come up anymore.
+        if (m_frameworkBundle.getState() == Bundle.STOPPING) {
+            // Important: Notice that calling "super.removedService() might invoke our service "stop" 
+            // callback, which in turn might invoke the just removed service dependency. In this case, 
+            // our "invoke" method won't use the tracker to get the service dependency (because at this point, 
+            // the tracker has withdrawn its reference to the lost service). So, you will see that the "invoke" 
+            // method will use the "m_cachedService" instead ...
+            boolean makeUnavailable = false;
+            synchronized (this) {
+                if (m_tracker.getService() == null) {
+                    makeUnavailable = true;
+                }
+            }
+            if (makeUnavailable) {
+                // the event.close method will unget the service.
+                m_component.handleEvent(this, EventType.REMOVED, new ServiceEventImpl(m_component.getBundle(),
+                    m_component.getBundleContext(), ref, m_serviceInstance));
+            }
+        } else {
+            // Unget what we got in addingService (see ServiceTracker 701.4.1)
+            m_component.getBundleContext().ungetService(ref);
+            // if there is no available services, the next call to invoke() method will block until another service
+            // becomes available. Else the next call to invoke() will return that highest ranked available service.
+        }
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        Object service = null;
+        try {
+            service = m_tracker.waitForService(m_timeout);
+        } catch (InterruptedException e) {            
+        }
+        
+        if (service == null) {
+            throw new IllegalStateException("Service unavailable: " + m_trackedServiceName.getName());
+        }
+        
+        try {
+			try {
+				return method.invoke(service, args);
+			} catch (IllegalAccessException iae) {
+				method.setAccessible(true);
+				return method.invoke(service, args);
+			}
+        } catch (InvocationTargetException e) {
+        	throw e.getTargetException();
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AbstractFactoryFilterIndex.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AbstractFactoryFilterIndex.java
new file mode 100644
index 0000000..1e72f31
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AbstractFactoryFilterIndex.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.dm.impl.index;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.felix.dm.impl.ServiceUtil;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class AbstractFactoryFilterIndex {
+	protected final Map<Long, SortedSet<ServiceReference>> m_sidToServiceReferencesMap = new HashMap<>();
+	protected final Map <ServiceListener, String> m_listenerToFilterMap = new HashMap<>();
+
+    public void addedService(ServiceReference reference, Object service) {
+        add(reference);
+    }
+
+    public void modifiedService(ServiceReference reference, Object service) {
+        modify(reference);
+    }
+
+    public void removedService(ServiceReference reference, Object service) {
+        remove(reference);
+    }
+    
+	public void swappedService(ServiceReference reference, Object service,
+			ServiceReference newReference, Object newService) {
+		addedService(newReference, newService);
+		removedService(reference, service);
+	}
+    
+	public void add(ServiceReference reference) {
+        Long sid = ServiceUtil.getServiceIdObject(reference);
+        synchronized (m_sidToServiceReferencesMap) {
+            SortedSet<ServiceReference> list = m_sidToServiceReferencesMap.get(sid);
+            if (list == null) {
+                list = new TreeSet<ServiceReference>();
+                m_sidToServiceReferencesMap.put(sid, list);
+            }
+            list.add(reference);
+        }
+    }
+
+    public void modify(ServiceReference reference) {
+        remove(reference);
+        add(reference);
+    }
+
+	public void remove(ServiceReference reference) {
+        Long sid = ServiceUtil.getServiceIdObject(reference);
+        synchronized (m_sidToServiceReferencesMap) {
+            SortedSet<ServiceReference> list = m_sidToServiceReferencesMap.get(sid);
+            if (list != null) {
+                list.remove(reference);
+            }
+        }
+    }
+    
+    protected boolean referenceMatchesObjectClass(ServiceReference ref, String objectClass) {
+    	boolean matches = false;
+    	Object value = ref.getProperty(Constants.OBJECTCLASS);
+    	matches = Arrays.asList((String[])value).contains(objectClass);
+    	return matches;
+    }
+    
+    /** Structure to hold internal filter data. */
+    protected static class FilterData {
+        public long m_serviceId;
+        public String m_objectClass;
+        public int m_ranking;
+
+		public String toString() {
+			return "FilterData [serviceId=" + m_serviceId + "]";
+		}
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AdapterFilterIndex.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AdapterFilterIndex.java
new file mode 100644
index 0000000..74699b9
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AdapterFilterIndex.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.index;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.FilterIndex;
+import org.apache.felix.dm.impl.ServiceUtil;
+import org.apache.felix.dm.tracker.ServiceTracker;
+import org.apache.felix.dm.tracker.ServiceTrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class AdapterFilterIndex extends AbstractFactoryFilterIndex implements FilterIndex, ServiceTrackerCustomizer {
+	// (&(objectClass=foo.Bar)(|(service.id=18233)(org.apache.felix.dependencymanager.aspect=18233)))
+	private static final String FILTER_REGEXP = "\\(&\\(" + Constants.OBJECTCLASS + "=([a-zA-Z\\.\\$0-9]*)\\)\\(\\|\\(" 
+									+ Constants.SERVICE_ID + "=([0-9]*)\\)\\(" 
+									+ DependencyManager.ASPECT + "=([0-9]*)\\)\\)\\)";
+	private static final Pattern PATTERN = Pattern.compile(FILTER_REGEXP);
+    private final Object m_lock = new Object();
+    private ServiceTracker m_tracker;
+    private BundleContext m_context;
+	private final Map<Object, List<ServiceListener>> m_sidToListenersMap = new HashMap<>();
+	protected final Map<ServiceListener, String> m_listenerToObjectClassMap = new HashMap<>();
+
+    public void open(BundleContext context) {
+        synchronized (m_lock) {
+            if (m_context != null) {
+                throw new IllegalStateException("Filter already open.");
+            }
+            try {
+                m_tracker = new ServiceTracker(context, context.createFilter("(" + Constants.OBJECTCLASS + "=*)"), this);
+            }
+            catch (InvalidSyntaxException e) {
+                throw new Error();
+            }
+            m_context = context;
+        }
+        m_tracker.open(true, true);
+    }
+
+    public void close() {
+        ServiceTracker tracker;
+        synchronized (m_lock) {
+            if (m_context == null) {
+                throw new IllegalStateException("Filter already closed.");
+            }
+            tracker = m_tracker;
+            m_tracker = null;
+            m_context = null;
+        }
+        tracker.close();
+    }
+
+    public boolean isApplicable(String clazz, String filter) {
+        return getFilterData(clazz, filter) != null;
+    }
+
+    /** Returns a value object with the relevant filter data, or <code>null</code> if this filter was not valid. */
+    private FilterData getFilterData(String clazz, String filter) {
+        // something like:
+    	// (&(objectClass=foo.Bar)(|(service.id=18233)(org.apache.felix.dependencymanager.aspect=18233)))  
+    	FilterData resultData = null;
+    	if (filter != null) {
+	    	Matcher matcher = PATTERN.matcher(filter);
+	    	if (matcher.matches()) {
+	    		String sid = matcher.group(2);
+	    		String sid2 = matcher.group(3);
+	    		if (sid.equals(sid2)) {
+	    			resultData = new FilterData();
+	    			resultData.m_serviceId = Long.parseLong(sid);
+	    		}
+	    	}
+    	}
+    	return resultData;
+    }
+
+	public List<ServiceReference> getAllServiceReferences(String clazz, String filter) {
+		List<ServiceReference> result = new ArrayList<>();
+		Matcher matcher = PATTERN.matcher(filter);
+		if (matcher.matches()) {
+			FilterData data = getFilterData(clazz, filter);
+			if (data != null) {
+				SortedSet<ServiceReference> list = null;
+				synchronized (m_sidToServiceReferencesMap) {
+					list = m_sidToServiceReferencesMap.get(Long.valueOf(data.m_serviceId));
+					if (list != null) {
+						Iterator<ServiceReference> iterator = list.iterator();
+						while (iterator.hasNext()) {
+							ServiceReference ref = (ServiceReference) iterator.next();
+							String objectClass = matcher.group(1);
+							if (referenceMatchesObjectClass(ref, objectClass)) {
+								result.add(ref);
+							}
+						}
+					}
+				}
+			}
+		}
+		return result;
+	}
+    
+	public void serviceChanged(ServiceEvent event) {
+        ServiceReference reference = event.getServiceReference();
+        Long sid = ServiceUtil.getServiceIdObject(reference);
+        List<ServiceListener> notificationList = new ArrayList<>();
+        synchronized (m_sidToListenersMap) {
+            List<ServiceListener> list = m_sidToListenersMap.get(sid);
+            if (list != null) {
+            	Iterator<ServiceListener> iterator = list.iterator();
+            	while (iterator.hasNext()) {
+                	ServiceListener listener = (ServiceListener) iterator.next();
+                	String objectClass = m_listenerToObjectClassMap.get(listener);
+                	if (referenceMatchesObjectClass(reference, objectClass)) {
+                		notificationList.add(listener);
+                	} 
+            	}
+            }
+        }
+        // notify
+        Iterator<ServiceListener> iterator = notificationList.iterator();
+        while (iterator.hasNext()) {
+        	ServiceListener listener = (ServiceListener) iterator.next();
+        	listener.serviceChanged(event);
+        }
+    }
+
+	public void addServiceListener(ServiceListener listener, String filter) {
+        FilterData data = getFilterData(null, filter);
+        if (data != null) {
+            Long sidObject = Long.valueOf(data.m_serviceId);
+            synchronized (m_sidToListenersMap) {
+            	List<ServiceListener> listeners = m_sidToListenersMap.get(sidObject);
+            	if (listeners == null) {
+            		listeners = new ArrayList<>();
+            		m_sidToListenersMap.put(sidObject, listeners);
+            	}
+            	listeners.add(listener);
+            	m_listenerToFilterMap.put(listener, filter);
+        		Matcher matcher = PATTERN.matcher(filter);
+        		if (matcher.matches()) {
+        			String objectClass = matcher.group(1);
+        			m_listenerToObjectClassMap.put(listener, objectClass);
+        		} else {
+        			throw new IllegalArgumentException("Filter string does not match index pattern");
+        		}
+
+            }
+        }
+    }
+
+	public void removeServiceListener(ServiceListener listener) {
+        synchronized (m_sidToListenersMap) {
+        	m_listenerToObjectClassMap.remove(listener);
+            String filter = (String) m_listenerToFilterMap.remove(listener);
+            if (filter != null) {
+            	// the listener does exist
+            	FilterData data = getFilterData(null, filter);
+            	if (data != null) {
+            		Long sidObject = Long.valueOf(data.m_serviceId);
+            		List<ServiceListener> listeners = m_sidToListenersMap.get(sidObject);
+            		if (listeners != null) {
+            			listeners.remove(listener);
+            		}
+            	}
+            }
+        }
+    }
+
+    public Object addingService(ServiceReference reference) {
+        BundleContext context;
+        synchronized (m_lock) {
+            context = m_context;
+        }
+        if (context != null) {
+            return context.getService(reference);
+        }
+        else {
+            throw new IllegalStateException("No valid bundle context.");
+        }
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("AdapterFilterIndex[");
+        sb.append("S2L: " + m_sidToListenersMap.size());
+        sb.append(", S2SR: " + m_sidToServiceReferencesMap.size());
+        sb.append(", L2F: " + m_listenerToFilterMap.size());
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AspectFilterIndex.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AspectFilterIndex.java
new file mode 100644
index 0000000..f14e884
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/AspectFilterIndex.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.index;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.FilterIndex;
+import org.apache.felix.dm.impl.ServiceUtil;
+import org.apache.felix.dm.tracker.ServiceTracker;
+import org.apache.felix.dm.tracker.ServiceTrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class AspectFilterIndex extends AbstractFactoryFilterIndex implements FilterIndex, ServiceTrackerCustomizer {
+	// (&(objectClass=foo.Bar)(|(!(service.ranking=*))(service.ranking<=99))(|(service.id=4451)(org.apache.felix.dependencymanager.aspect=4451)))
+    private static final String FILTER_START = "(&(" + Constants.OBJECTCLASS + "=";
+    private static final String FILTER_SUBSTRING_0 = ")(&(|(!(" + Constants.SERVICE_RANKING + "=*))(" + Constants.SERVICE_RANKING + "<=";
+    private static final String FILTER_SUBSTRING_1 = "))(|(" + Constants.SERVICE_ID + "=";
+    private static final String FILTER_SUBSTRING_2 = ")(" + DependencyManager.ASPECT + "=";
+    private static final String FILTER_END = "))))";
+    private final Object m_lock = new Object();
+    private ServiceTracker m_tracker;
+    private BundleContext m_context;
+    
+	private final Map<Long, Map<String, SortedMap<Integer, List<ServiceListener>>>> m_sidToObjectClassToRankingToListenersMap = new HashMap<>();
+
+    public void open(BundleContext context) {
+        synchronized (m_lock) {
+            if (m_context != null) {
+                throw new IllegalStateException("Filter already open.");
+            }
+            try {
+                m_tracker = new ServiceTracker(context, context.createFilter("(" + Constants.OBJECTCLASS + "=*)"), this);
+            }
+            catch (InvalidSyntaxException e) {
+                throw new Error();
+            }
+            m_context = context;
+        }
+        m_tracker.open(true, true);
+    }
+
+    public void close() {
+        ServiceTracker tracker;
+        synchronized (m_lock) {
+            if (m_context == null) {
+                throw new IllegalStateException("Filter already closed.");
+            }
+            tracker = m_tracker;
+            m_tracker = null;
+            m_context = null;
+        }
+        tracker.close();
+    }
+
+    public boolean isApplicable(String clazz, String filter) {
+        return getFilterData(clazz, filter) != null;
+    }
+
+    /** Returns a value object with the relevant filter data, or <code>null</code> if this filter was not valid. */
+    private FilterData getFilterData(String clazz, String filter) {
+        // something like:
+        // (&(objectClass=foo.Bar)(&(|(!(service.ranking=*))(service.ranking<=9))(|(service.id=37)(org.apache.felix.dependencymanager.aspect=37))))
+        if ((filter != null)
+            && (filter.startsWith(FILTER_START)) // (&(objectClass=
+            && (filter.endsWith(FILTER_END)) // ))))
+            ) {
+            int i0 = filter.indexOf(FILTER_SUBSTRING_0);
+            if (i0 == -1) {
+                return null;
+            }
+            int i1 = filter.indexOf(FILTER_SUBSTRING_1);
+            if (i1 == -1 || i1 <= i0) {
+                return null;
+            }
+            int i2 = filter.indexOf(FILTER_SUBSTRING_2);
+            if (i2 == -1 || i2 <= i1) {
+                return null;
+            }
+            long sid = Long.parseLong(filter.substring(i1 + FILTER_SUBSTRING_1.length(), i2));
+            long sid2 = Long.parseLong(filter.substring(i2 + FILTER_SUBSTRING_2.length(), filter.length() - FILTER_END.length()));
+            if (sid != sid2) {
+                return null;
+            }
+            FilterData result = new FilterData();
+            result.m_objectClass = filter.substring(FILTER_START.length(), i0);
+            result.m_serviceId = sid;
+            result.m_ranking = Integer.parseInt(filter.substring(i0 + FILTER_SUBSTRING_0.length(), i1));
+            return result;
+        }
+        return null;
+    }
+
+	public List<ServiceReference> getAllServiceReferences(String clazz, String filter) {
+        List<ServiceReference> result = new ArrayList<>();
+        FilterData data = getFilterData(clazz, filter);
+        if (data != null) {
+        	SortedSet<ServiceReference> list = null;
+        	synchronized (m_sidToServiceReferencesMap) {
+        		list = m_sidToServiceReferencesMap.get(Long.valueOf(data.m_serviceId));
+        		if (list != null) {
+        			Iterator<ServiceReference> iterator = list.iterator();
+        			while (iterator.hasNext()) {
+        				ServiceReference reference = (ServiceReference) iterator.next();
+        				if (referenceMatchesObjectClass(reference, data.m_objectClass) && ServiceUtil.getRanking(reference) <= data.m_ranking) {
+        					result.add(reference);
+        				}
+        			}
+        		}
+			}
+        }
+        return result;
+    }
+
+	public void serviceChanged(ServiceEvent event) {
+        List<ServiceListener> list = new ArrayList<>();
+        ServiceReference reference = event.getServiceReference();
+        Long sidObject = ServiceUtil.getServiceIdObject(reference);
+        int ranking = ServiceUtil.getRanking(reference);
+        String[] objectClasses = (String[]) reference.getProperty(Constants.OBJECTCLASS);
+        
+        synchronized (m_sidToObjectClassToRankingToListenersMap) {
+        	for (int i = 0; i < objectClasses.length; i++) {
+        		// handle each of the object classes separately since aspects only work on one object class at a time
+        		String objectClass = objectClasses[i];
+        		Map<String, SortedMap<Integer, List<ServiceListener>>> objectClassToRankingToListenersMap = m_sidToObjectClassToRankingToListenersMap.get(sidObject);
+        		if (objectClassToRankingToListenersMap != null) {
+        			SortedMap<Integer, List<ServiceListener>> rankingToListenersMap = objectClassToRankingToListenersMap.get(objectClass);
+        			if (rankingToListenersMap != null) {
+        				Iterator<Entry<Integer, List<ServiceListener>>> iterator = rankingToListenersMap.entrySet().iterator();
+        				while (iterator.hasNext()) {
+        					Entry<Integer, List<ServiceListener>> entry = iterator.next();
+        					if (ranking <= ((Integer) entry.getKey()).intValue()) {
+        						list.addAll(entry.getValue());
+        					}
+        				}
+        			}
+        		}
+        	}
+		}
+        Iterator<ServiceListener> iterator = list.iterator();
+        while (iterator.hasNext()) {
+            ServiceListener listener = iterator.next();
+            listener.serviceChanged(event);
+        }
+    }
+
+	public void addServiceListener(ServiceListener listener, String filter) {
+        FilterData data = getFilterData(null, filter);
+        if (data != null) {
+            Long sidObject = Long.valueOf(data.m_serviceId);
+            synchronized (m_sidToObjectClassToRankingToListenersMap) {
+            	Map<String, SortedMap<Integer, List<ServiceListener>>> objectClassToRankingToListenersMap = m_sidToObjectClassToRankingToListenersMap.get(sidObject);
+            	if (objectClassToRankingToListenersMap == null) {
+            		objectClassToRankingToListenersMap = new TreeMap<>();
+            		m_sidToObjectClassToRankingToListenersMap.put(sidObject, objectClassToRankingToListenersMap);
+            	}
+            	
+            	SortedMap<Integer, List<ServiceListener>> rankingToListenersMap = objectClassToRankingToListenersMap.get(data.m_objectClass);
+                if (rankingToListenersMap == null) {
+                    rankingToListenersMap = new TreeMap<>();
+                    objectClassToRankingToListenersMap.put(data.m_objectClass, rankingToListenersMap);
+                }            	
+            	
+            	List<ServiceListener> listeners = rankingToListenersMap.get(Integer.valueOf(data.m_ranking));
+            	if (listeners == null) {
+            		listeners = new ArrayList<>();
+            		rankingToListenersMap.put(Integer.valueOf(data.m_ranking), listeners);
+            	}
+            	
+            	listeners.add(listener);
+                m_listenerToFilterMap.put(listener, filter);
+            }
+        }
+    }
+
+	public void removeServiceListener(ServiceListener listener) {
+    	synchronized (m_sidToObjectClassToRankingToListenersMap) {
+    		String filter = (String) m_listenerToFilterMap.remove(listener);
+    		if (filter != null) {
+    			// the listener does exist
+    			FilterData data = getFilterData(null, filter);
+    			if (data != null) {
+    				// this index is applicable
+    				Long sidObject = Long.valueOf(data.m_serviceId);
+                	Map<String, SortedMap<Integer, List<ServiceListener>>> objectClassToRankingToListenersMap = m_sidToObjectClassToRankingToListenersMap.get(sidObject);
+                	if (objectClassToRankingToListenersMap != null) {
+                		SortedMap<Integer, List<ServiceListener>> rankingToListenersMap = objectClassToRankingToListenersMap.get(data.m_objectClass);
+                		if (rankingToListenersMap != null) {
+                			List<ServiceListener> listeners = rankingToListenersMap.get(Integer.valueOf(data.m_ranking));
+                			if (listeners != null) {
+                				listeners.remove(listener);
+                			}
+                			// cleanup 
+                			if (listeners != null && listeners.isEmpty()) {
+                				rankingToListenersMap.remove(Integer.valueOf(data.m_ranking));
+                			}
+                			if (rankingToListenersMap.isEmpty()) {
+                				objectClassToRankingToListenersMap.remove(data.m_objectClass);
+                			}
+                			if (objectClassToRankingToListenersMap.isEmpty()) {
+                				m_sidToObjectClassToRankingToListenersMap.remove(sidObject);
+                			}
+                		}
+                	}
+    			}
+    		}
+		}
+    }
+
+    public Object addingService(ServiceReference reference) {
+        BundleContext context;
+        synchronized (m_lock) {
+            context = m_context;
+        }
+        if (context != null) {
+            return context.getService(reference);
+        }
+        else {
+            throw new IllegalStateException("No valid bundle context.");
+        }
+    }
+    
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("AspectFilterIndex[");
+        sb.append("S2R2L: " + m_sidToObjectClassToRankingToListenersMap.size());
+        sb.append(", S2SR: " + m_sidToServiceReferencesMap.size());
+        sb.append(", L2F: " + m_listenerToFilterMap.size());
+        sb.append("]");
+        return sb.toString();
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/BundleContextInterceptor.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/BundleContextInterceptor.java
new file mode 100644
index 0000000..11cf401
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/BundleContextInterceptor.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.index;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.felix.dm.FilterIndex;
+import org.apache.felix.dm.Logger;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class BundleContextInterceptor extends BundleContextInterceptorBase {
+	protected static final String INDEX_LOG_TRESHOLD = "org.apache.felix.dm.index.log.treshold";
+    private final ServiceRegistryCache m_cache;
+    private final boolean m_perfmon;
+	private Logger m_logger;
+	private long m_threshold;
+
+    public BundleContextInterceptor(ServiceRegistryCache cache, BundleContext context) {
+        super(context);
+        m_cache = cache;
+        m_perfmon = context.getProperty(INDEX_LOG_TRESHOLD) != null;
+		if (m_perfmon) {
+			m_threshold = Long.parseLong(context.getProperty(INDEX_LOG_TRESHOLD));
+			m_logger = new Logger(context);
+		}
+    }
+
+    public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
+        FilterIndex filterIndex = m_cache.hasFilterIndexFor(null, filter);
+        if (filterIndex != null) {
+            filterIndex.addServiceListener(listener, filter);
+        }
+        else {
+            m_context.addServiceListener(listener, filter);
+        }
+    }
+
+    public void addServiceListener(ServiceListener listener) {
+        FilterIndex filterIndex = m_cache.hasFilterIndexFor(null, null);
+        if (filterIndex != null) {
+            filterIndex.addServiceListener(listener, null);
+        }
+        else {
+            m_context.addServiceListener(listener);
+        }
+    }
+
+	public void removeServiceListener(ServiceListener listener) {
+    	// remove servicelistener. although it would be prettier to find the correct filterindex first it's
+    	// probaby faster to do a brute force removal.
+    	Iterator<FilterIndex> filterIndexIterator = m_cache.getFilterIndices().iterator();
+    	while (filterIndexIterator.hasNext()) {
+    		filterIndexIterator.next().removeServiceListener(listener);
+    	}
+    	m_context.removeServiceListener(listener);
+    }
+
+	public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+    	long start = 0L;
+    	if (m_perfmon) {
+    		start = System.currentTimeMillis();
+    	}
+        // first we ask the cache if there is an index for our request (class and filter combination)
+        FilterIndex filterIndex = m_cache.hasFilterIndexFor(clazz, filter);
+        if (filterIndex != null) {
+            List<ServiceReference> result = filterIndex.getAllServiceReferences(clazz, filter);
+            Iterator<ServiceReference> iterator = result.iterator();
+            while (iterator.hasNext()) {
+                ServiceReference reference = iterator.next();
+                String[] list = (String[]) reference.getProperty(Constants.OBJECTCLASS);
+                for (int i = 0; i < list.length; i++) {
+                    if (!reference.isAssignableTo(m_context.getBundle(), list[i])) {
+                        iterator.remove();
+                        break;
+                    }
+                }
+            }
+            if (m_perfmon) {
+	        	long duration = System.currentTimeMillis() - start;
+	        	if (duration > m_threshold) {
+	        		m_logger.log(Logger.LOG_DEBUG, "Indexed filter exceeds lookup time threshold (" + duration + " ms): " + clazz + " " + filter);
+	        	}
+            }
+            if (result.size() == 0) {
+                return null;
+            }
+            return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
+        }
+        else {
+            // if they don't know, we ask the real bundle context instead
+            ServiceReference[] serviceReferences = m_context.getServiceReferences(clazz, filter);
+            if (m_perfmon) {
+	        	long duration = System.currentTimeMillis() - start;
+	        	if (duration > m_threshold) {
+	        		m_logger.log(Logger.LOG_DEBUG, "Unindexed filter exceeds lookup time threshold (" + duration + " ms): " + clazz + " " + filter);
+	        	}
+            }
+        	return serviceReferences;
+        }
+    }
+
+	public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        // first we ask the cache if there is an index for our request (class and filter combination)
+        FilterIndex filterIndex = m_cache.hasFilterIndexFor(clazz, filter);
+        if (filterIndex != null) {
+            List<ServiceReference> result = filterIndex.getAllServiceReferences(clazz, filter);
+            if (result == null || result.size() == 0) {
+                return null;
+            }
+            return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
+        }
+        else {
+            // if they don't know, we ask the real bundle context instead
+            return m_context.getAllServiceReferences(clazz, filter);
+        }
+    }
+
+    public ServiceReference getServiceReference(String clazz) {
+        ServiceReference[] references;
+        try {
+            references = getServiceReferences(clazz, null);
+            if (references == null || references.length == 0) {
+                return null;
+            }
+            Arrays.sort(references);
+            return references[references.length - 1];
+        }
+        catch (InvalidSyntaxException e) {
+            throw new Error("Invalid filter syntax thrown for null filter.", e);
+        }
+    }
+
+    public void serviceChanged(ServiceEvent event) {
+        m_cache.serviceChangedForFilterIndices(event);
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/BundleContextInterceptorBase.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/BundleContextInterceptorBase.java
new file mode 100644
index 0000000..498fd16
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/BundleContextInterceptorBase.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.index;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Base class for bundle context interceptors that keep track of service listeners and delegate incoming changes to them.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class BundleContextInterceptorBase implements BundleContext, ServiceListener {
+    protected final BundleContext m_context;
+    /** Keeps track of all service listeners and their optional filters. */
+	private final Map<ServiceListener, String> m_serviceListenerFilterMap = new HashMap<>();
+    private long m_currentVersion = 0;
+    private long m_entryVersion = -1;
+	private Entry<ServiceListener, String>[] m_serviceListenerFilterMapEntries;
+
+    public BundleContextInterceptorBase(BundleContext context) {
+        m_context = context;
+    }
+
+    public String getProperty(String key) {
+        return m_context.getProperty(key);
+    }
+
+    public Bundle getBundle() {
+        return m_context.getBundle();
+    }
+
+    public Bundle installBundle(String location) throws BundleException {
+        return m_context.installBundle(location);
+    }
+
+    public Bundle installBundle(String location, InputStream input) throws BundleException {
+        return m_context.installBundle(location, input);
+    }
+
+    public Bundle getBundle(long id) {
+        return m_context.getBundle(id);
+    }
+
+    public Bundle[] getBundles() {
+        return m_context.getBundles();
+    }
+
+	public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
+        synchronized (m_serviceListenerFilterMap) {
+            m_serviceListenerFilterMap.put(listener, filter);
+            m_currentVersion++;
+        }
+    }
+
+	public void addServiceListener(ServiceListener listener) {
+        synchronized (m_serviceListenerFilterMap) {
+            m_serviceListenerFilterMap.put(listener, null);
+            m_currentVersion++;
+        }
+    }
+
+    public void removeServiceListener(ServiceListener listener) {
+        synchronized (m_serviceListenerFilterMap) {
+            m_serviceListenerFilterMap.remove(listener);
+            m_currentVersion++;
+        }
+    }
+
+    public void addBundleListener(BundleListener listener) {
+        m_context.addBundleListener(listener);
+    }
+
+    public void removeBundleListener(BundleListener listener) {
+        m_context.removeBundleListener(listener);
+    }
+
+    public void addFrameworkListener(FrameworkListener listener) {
+        m_context.addFrameworkListener(listener);
+    }
+
+    public void removeFrameworkListener(FrameworkListener listener) {
+        m_context.removeFrameworkListener(listener);
+    }
+
+    public ServiceRegistration registerService(String[] clazzes, Object service, @SuppressWarnings("rawtypes") Dictionary properties) {
+        return m_context.registerService(clazzes, service, properties);
+    }
+
+    public ServiceRegistration registerService(String clazz, Object service, @SuppressWarnings("rawtypes") Dictionary properties) {
+        return m_context.registerService(clazz, service, properties);
+    }
+
+    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        return m_context.getServiceReferences(clazz, filter);
+    }
+
+    public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        return m_context.getAllServiceReferences(clazz, filter);
+    }
+
+    public ServiceReference getServiceReference(String clazz) {
+        return m_context.getServiceReference(clazz);
+    }
+
+    public Object getService(ServiceReference reference) {
+        return m_context.getService(reference);
+    }
+
+    public boolean ungetService(ServiceReference reference) {
+        return m_context.ungetService(reference);
+    }
+
+    public File getDataFile(String filename) {
+        return m_context.getDataFile(filename);
+    }
+
+    public Filter createFilter(String filter) throws InvalidSyntaxException {
+        return m_context.createFilter(filter);
+    }
+
+	@SuppressWarnings("unchecked")
+	protected Entry<ServiceListener, String>[] synchronizeCollection() {
+        // lazy copy on write: we make a new copy only if writes have changed the collection
+        synchronized (m_serviceListenerFilterMap) {
+            if (m_currentVersion != m_entryVersion) {
+                m_serviceListenerFilterMapEntries = (Entry<ServiceListener, String>[]) m_serviceListenerFilterMap.entrySet().toArray(new Entry[m_serviceListenerFilterMap.size()]);
+                m_entryVersion = m_currentVersion;
+            }
+        }
+        return m_serviceListenerFilterMapEntries;
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/FilterIndexBundleContext.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/FilterIndexBundleContext.java
new file mode 100644
index 0000000..9a6a266
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/FilterIndexBundleContext.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.index;
+
+import java.util.Map.Entry;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FilterIndexBundleContext extends BundleContextInterceptorBase {
+    public FilterIndexBundleContext(BundleContext context) {
+        super(context);
+    }
+
+	public void serviceChanged(ServiceEvent event) {
+        Entry<ServiceListener, String>[] entries = synchronizeCollection();
+        for (int i = 0; i < entries.length; i++) {
+            Entry<ServiceListener, String> serviceListenerFilterEntry = entries[i];
+            ServiceListener serviceListener = serviceListenerFilterEntry.getKey();
+            String filter = serviceListenerFilterEntry.getValue();
+            if (filter == null) {
+                serviceListener.serviceChanged(event);
+            }
+            else {
+                // call service changed on the listener if the filter matches the event
+                // TODO review if we can be smarter here
+                try {
+                    if ("(objectClass=*)".equals(filter)) {
+                        serviceListener.serviceChanged(event);
+                    }
+                    else {
+                        if (m_context.createFilter(filter).match(event.getServiceReference())) {
+                            serviceListener.serviceChanged(event);
+                        }
+                    }
+                }
+                catch (InvalidSyntaxException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/ServiceRegistryCache.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/ServiceRegistryCache.java
new file mode 100644
index 0000000..8848e11
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/ServiceRegistryCache.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.index;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.felix.dm.FilterIndex;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceRegistryCache implements ServiceListener/*, CommandProvider*/ {
+	private final List<FilterIndex> m_filterIndexList = new CopyOnWriteArrayList<>();
+    private final BundleContext m_context;
+    private final FilterIndexBundleContext m_filterIndexBundleContext;
+	private final Map<BundleContext, BundleContextInterceptor> m_bundleContextInterceptorMap = new HashMap<>();
+    private long m_currentVersion = 0;
+    private long m_arrayVersion = -1;
+    
+    public ServiceRegistryCache(BundleContext context) {
+        m_context = context;
+        m_filterIndexBundleContext = new FilterIndexBundleContext(m_context);
+    }
+    
+    public void open() {
+        m_context.addServiceListener(this);
+    }
+    
+    public void close() {
+        m_context.removeServiceListener(this);
+    }
+    
+    public void addFilterIndex(FilterIndex index) {
+        m_filterIndexList.add(index);
+        index.open(m_filterIndexBundleContext);
+    }
+    
+    public void removeFilterIndex(FilterIndex index) {
+        index.close();
+        m_filterIndexList.remove(index);
+    }
+
+    public void serviceChanged(ServiceEvent event) {
+        // any incoming event is first dispatched to the list of filter indices
+        m_filterIndexBundleContext.serviceChanged(event);
+        // and then all the other listeners can access it
+        synchronized (m_bundleContextInterceptorMap) {
+            if (m_currentVersion != m_arrayVersion) {
+                // if our copy is out of date, we make a new one
+                m_arrayVersion = m_currentVersion;
+            }
+        }
+        
+        serviceChangedForFilterIndices(event);
+    }
+    
+    /** Creates an interceptor for a bundle context that uses our cache. */
+    public BundleContext createBundleContextInterceptor(BundleContext context) {
+        synchronized (m_bundleContextInterceptorMap) {
+            BundleContextInterceptor bundleContextInterceptor = m_bundleContextInterceptorMap.get(context);
+            if (bundleContextInterceptor == null) {
+                bundleContextInterceptor = new BundleContextInterceptor(this, context);
+                m_bundleContextInterceptorMap.put(context, bundleContextInterceptor);
+                m_currentVersion++;
+                // TODO figure out a good way to clean up bundle contexts that are no longer valid so they can be garbage collected
+            }
+            return bundleContextInterceptor;
+        }
+    }
+
+    public FilterIndex hasFilterIndexFor(String clazz, String filter) {
+        Iterator<FilterIndex> iterator = m_filterIndexList.iterator();
+        while (iterator.hasNext()) {
+            FilterIndex filterIndex = iterator.next();
+            if (filterIndex.isApplicable(clazz, filter)) {
+                return filterIndex;
+            }
+        }
+        return null;
+    }
+
+    public void serviceChangedForFilterIndices(ServiceEvent event) {
+        Iterator<FilterIndex> iterator = m_filterIndexList.iterator();
+        while (iterator.hasNext()) {
+            FilterIndex filterIndex = iterator.next();
+            filterIndex.serviceChanged(event);
+        }
+    }
+    
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("ServiceRegistryCache[");
+        sb.append("FilterIndices: " + m_filterIndexList.size());
+        sb.append(", BundleContexts intercepted: " + m_bundleContextInterceptorMap.size());
+        sb.append("]");
+        return sb.toString();
+    }
+
+	public List<FilterIndex> getFilterIndices() {
+		return m_filterIndexList;
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/Filter.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/Filter.java
new file mode 100644
index 0000000..602b4cc
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/Filter.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.index.multiproperty;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Filter {
+	private boolean m_valid = true;
+	private Map<String, Property> m_properties = new HashMap<>();
+	private Set<String> m_propertyKeys = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+	
+	private Filter() {
+	}
+	
+	// Sample valid filter string (&(objectClass=OBJECTCLASS)(&(model=MODEL)(concept=CONCEPT)(role=ROLE)(!(context=*))))
+	public static Filter parse(String filterString) {
+		Filter filter = new Filter();
+		StringTokenizer tokenizer = new StringTokenizer(filterString, "(&|=)", true);
+		
+		String token = null;
+		String prevToken = null;
+		String key = null;
+		StringBuilder valueBuilder = new StringBuilder();
+		boolean negate = false;
+
+		while (tokenizer.hasMoreTokens()) {
+			prevToken = token;
+			token = tokenizer.nextToken();
+			if (token.equals("|")) {
+				// we're not into OR's
+				filter.m_valid = false;
+				break;
+			}
+			if (token.equals("!")) {
+				negate = true;
+			} else if (token.equals("=")) {
+				key = prevToken.toLowerCase();
+			} else if (key != null) {
+				if (!token.equals(")")) {
+					valueBuilder.append(token); // might be superseded by a &
+				}
+				if (token.equals(")")) {
+					// set complete
+					if (filter.m_properties.containsKey(key)) {
+						// set current property to multivalue
+						Property property = filter.m_properties.get(key);
+						property.addValue(valueBuilder.toString(), negate);
+					} else {
+						Property property = new Property(negate, key, valueBuilder.toString());
+						filter.m_properties.put(key, property);
+						filter.m_propertyKeys.add(key);
+					}
+					negate = false;
+					key = null;
+					valueBuilder = new StringBuilder();
+				}
+			} 
+		}
+		return filter;
+	}
+	
+	public boolean containsProperty(String propertyKey) {
+		return m_properties.containsKey(propertyKey);
+	}
+	
+	public Set<String> getPropertyKeys() {
+		return m_properties.keySet();
+	}
+	
+	public Property getProperty(String key) {
+		return m_properties.get(key);
+	}
+	
+	public boolean isValid() {
+		if (!m_valid) {
+			return m_valid;
+		} else {
+			// also check the properties
+			Iterator<Property> propertiesIterator = m_properties.values().iterator();
+			while (propertiesIterator.hasNext()) {
+				Property property = propertiesIterator.next();
+				if (!property.isValid()) {
+					return false;
+				}
+			}
+		}
+		return true;
+	}
+	
+	public static void main(String args[]) {
+		Filter parser = Filter.parse("(&(objectClass=OBJECTCLASS)(&(a=x)(a=n)(a=y)(b=y)(c=z)))");
+		System.out.println("key: " + parser.createKey());
+	}
+
+	protected String createKey() {
+		StringBuilder builder = new StringBuilder();
+		Iterator<String> keys = m_propertyKeys.iterator();
+		
+		while (keys.hasNext()) {
+			String key = keys.next();
+			Property prop = m_properties.get(key);
+			if (!prop.isWildcard()) {
+				Iterator<String> values = prop.getValues().iterator();
+				while (values.hasNext()) {
+					String value = values.next();
+					builder.append(key);
+					builder.append("=");
+					builder.append(value);
+					if (keys.hasNext() || values.hasNext()) {
+						builder.append(";");
+					}
+				}
+			}
+		}
+		// strip the final ';' in case the last key was a wildcard property
+		if (builder.charAt(builder.length() - 1) == ';') {
+			return builder.toString().substring(0, builder.length() - 1);
+		} else {
+			return builder.toString();
+		}
+	}
+	
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/MultiPropertyFilterIndex.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/MultiPropertyFilterIndex.java
new file mode 100644
index 0000000..42cb5b7
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/MultiPropertyFilterIndex.java
@@ -0,0 +1,492 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.index.multiproperty;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.felix.dm.FilterIndex;
+import org.apache.felix.dm.tracker.ServiceTracker;
+import org.apache.felix.dm.tracker.ServiceTrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MultiPropertyFilterIndex implements FilterIndex, ServiceTrackerCustomizer {
+
+    private final Object m_lock = new Object();
+    private ServiceTracker m_tracker;
+    private BundleContext m_context;
+	private Map<String, Property> m_configProperties = new LinkedHashMap<>();
+	private List<String> m_negatePropertyKeys = new ArrayList<>();
+    private final Map<String, List<ServiceReference>> m_keyToServiceReferencesMap = new HashMap<>();
+    private final Map<String, List<ServiceListener>> m_keyToListenersMap = new HashMap<>();
+    private final Map<ServiceListener, String> m_listenerToFilterMap = new HashMap<>();
+
+	public MultiPropertyFilterIndex(String configString) {
+		parseConfig(configString);
+	}
+	
+	public boolean isApplicable(String clazz, String filterString) {
+		Filter filter = createFilter(clazz, filterString);
+		
+		if (!filter.isValid()) {
+			return false;
+		}
+		// compare property keys to the ones in the configuration
+		Set<String> filterPropertyKeys = filter.getPropertyKeys();
+		if (m_configProperties.size() != filterPropertyKeys.size()) {
+			return false;
+		}
+		Iterator<String> filterPropertyKeysIterator = filterPropertyKeys.iterator();
+		while (filterPropertyKeysIterator.hasNext()) {
+			String filterPropertyKey = filterPropertyKeysIterator.next();
+			if (!m_configProperties.containsKey(filterPropertyKey)) {
+				return false;
+			} else if ((m_configProperties.get(filterPropertyKey)).isNegate() != filter.getProperty(filterPropertyKey).isNegate()) {
+				// negation should be equal
+				return false;
+			} else if (!filter.getProperty(filterPropertyKey).isNegate() && filter.getProperty(filterPropertyKey).getValue().equals("*")) {
+				// no wildcards without negation allowed
+				return false;
+			} 
+		}
+		// our properties match so we're applicable
+		return true;
+	}
+	
+    public boolean isApplicable(ServiceReference ref) {
+    	String[] propertyKeys = ref.getPropertyKeys();
+        TreeSet<String> referenceProperties = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        for (int i = 0; i < propertyKeys.length; i++) {
+            referenceProperties.add(propertyKeys[i]);
+        }
+        Iterator<String> iterator = m_configProperties.keySet().iterator();
+        while (iterator.hasNext()) {
+            String item = iterator.next();
+            Property configProperty = m_configProperties.get(item);
+            if (!configProperty.isNegate() && !(referenceProperties.contains(item))) {
+                return false;
+            } else if (configProperty.isNegate() && referenceProperties.contains(item)) {
+            	return false;
+            }
+        }
+        return true;
+    }
+	
+	private void parseConfig(String configString) {
+		String[] propertyConfigs = configString.split(",");
+		for (int i = 0; i < propertyConfigs.length; i++) {
+			String propertyConfig = propertyConfigs[i];
+			Property property = new Property();
+			String key;
+			String value = null;
+			if (propertyConfig.startsWith("!")) {
+				property.setNegate(true);
+				key = propertyConfig.substring(1);
+			} else {
+				key = propertyConfig;
+			}
+			if (key.endsWith("*")) {
+				key = key.substring(0, key.indexOf("*"));
+				value = "*";
+			}
+			property.setKey(key.toLowerCase());
+			property.addValue(value, property.isNegate());
+			m_configProperties.put(key.toLowerCase(), property);
+			if (property.isNegate()) {
+				m_negatePropertyKeys.add(key);
+			}
+		}
+	}
+	
+	protected Collection<Property> getProperties() {
+		return m_configProperties.values();
+	}
+	
+    protected String createKeyFromFilter(String clazz, String filterString) {
+    	return createFilter(clazz, filterString).createKey();
+    }
+    
+    private Filter createFilter(String clazz, String filterString) {
+		String filterStringWithObjectClass = filterString;
+		if (clazz != null) {
+			if (filterString != null) {
+				if (!filterStringWithObjectClass.startsWith("(&(objectClass=")) {
+					filterStringWithObjectClass = "(&(objectClass=" + clazz + ")" + filterString + ")";
+				}
+			} else {
+				filterStringWithObjectClass = "(objectClass=" + clazz + ")";
+			}
+		}
+		Filter filter = Filter.parse(filterStringWithObjectClass);
+		return filter;
+    }
+    
+    protected List<String> createKeys(ServiceReference reference) {
+    	List<String> results = new ArrayList<>();
+    	List<List<String>> sets = new ArrayList<>();   	
+    	String[] keys = reference.getPropertyKeys();
+    	Arrays.sort(keys, String.CASE_INSENSITIVE_ORDER);
+    	for (int i = 0; i < keys.length; i++) {
+    		List<String> set = new ArrayList<>();
+    		String key = keys[i].toLowerCase();
+    		if (m_configProperties.containsKey(key)) {
+	    		Object valueObject = reference.getProperty(key);
+	    		if (valueObject instanceof String[]) {
+	    			set.addAll(getPermutations(key, (String[]) valueObject));
+	    		} else {
+	    			set.add(toKey(key, valueObject));
+	    		}
+	    		sets.add(set);
+    		}
+    	}
+    	
+    	List<List<String>> reversedSets = new ArrayList<>();
+    	int size = sets.size();
+    	for (int i = size - 1; i > -1; i--) {
+    		reversedSets.add(sets.get(i));
+    	}
+    	List<List<String>> products = carthesianProduct(0, reversedSets);
+    	// convert sets into strings
+    	for (int i = 0; i < products.size(); i++) {
+    		List<String> set = products.get(i);
+    		StringBuilder b = new StringBuilder();
+    		for (int j = 0; j < set.size(); j++) {
+    			String item = set.get(j);
+    			b.append(item);
+    			if (j < set.size() - 1) {
+    				b.append(";");
+    			}
+    		}
+    		results.add(b.toString());
+    	}
+    	
+    	return results;
+    }
+    
+    /**
+     * Note that we calculate the carthesian product for multi value properties. Use filters on these sparingly since memory
+     * consumption can get really high when multiple properties have a lot of values.
+     * 
+     * @param index
+     * @param sets
+     * @return
+     */
+    private List<List<String>> carthesianProduct(int index, List<List<String>> sets) {
+    	List<List<String>> result = new ArrayList<>();
+    	if (index == sets.size()) {
+    		result.add(new ArrayList<String>());
+    	} else {
+			List<String> set = sets.get(index);
+			for (int i = 0; i < set.size(); i++) {
+				String object = set.get(i);
+    			List<List<String>> pSets = carthesianProduct(index + 1, sets);
+    			for (int j = 0; j < pSets.size(); j++) {
+    				List<String> pSet = pSets.get(j);
+    				pSet.add(object);
+    				result.add(pSet);
+    			}
+    		}
+    	}
+    	return result;
+    }
+    
+    List<String> getPermutations(String key, String[] values) {
+    	List<String> results = new ArrayList<>();
+		Arrays.sort(values, String.CASE_INSENSITIVE_ORDER);
+		for (int v = 0; v < values.length; v++) {
+			String processValue = values[v];
+			List<String> items = new ArrayList<>();
+			items.add(processValue);
+			// per value get combinations
+			List<String> subItems = new ArrayList<>(items);
+			for (int w = v; w < values.length; w++) {
+				// make a copy of the current list
+				subItems = new ArrayList<>(subItems);
+				if (w != v) {
+					String value = values[w];
+					subItems.add(value);
+				}
+				results.add(toKey(key, subItems));
+			}
+		}
+		return results;
+    }
+    
+    protected String toKey(String key, List<String> values) {
+    	StringBuilder builder = new StringBuilder();
+    	for (int i = 0; i < values.size(); i++) {
+    		builder.append(toKey(key, values.get(i)));
+    		if (i < values.size() - 1) {
+    			builder.append(";");
+    		}
+    	}
+    	return builder.toString();
+    }
+    
+    protected String toKey(String key, Object value) {
+    	StringBuilder builder = new StringBuilder();
+    	builder.append(key);
+		builder.append("=");
+		builder.append(value.toString());
+		return builder.toString();
+    }
+    
+    public Object addingService(ServiceReference reference) {
+        BundleContext context;
+        synchronized (m_lock) {
+            context = m_context;
+        }
+        if (context != null) {
+            return context.getService(reference);
+        }
+        else {
+            throw new IllegalStateException("No valid bundle context.");
+        }
+    }
+
+    public void addedService(ServiceReference reference, Object service) {
+        if (isApplicable(reference) && shouldBeIndexed(reference)) {
+            handleServiceAdd(reference);
+        }
+    }
+
+    public void modifiedService(ServiceReference reference, Object service) {
+        if (isApplicable(reference)) {
+            handleServicePropertiesChange(reference);
+        }
+    }
+
+    public void removedService(ServiceReference reference, Object service) {
+        if (isApplicable(reference) && shouldBeIndexed(reference)) {
+            handleServiceRemove(reference);
+        }
+    }
+    
+    protected void handleServiceAdd(ServiceReference reference) {
+        List<String> keys = createKeys(reference);
+        synchronized (m_keyToServiceReferencesMap) {
+            for (int i = 0; i < keys.size(); i++) {
+                List<ServiceReference> references = m_keyToServiceReferencesMap.get(keys.get(i));
+                if (references == null) {
+                    references = new ArrayList<>();
+                    m_keyToServiceReferencesMap.put(keys.get(i), references);
+                }
+                references.add(reference);
+            }
+        }
+    }
+
+    protected void handleServicePropertiesChange(ServiceReference reference) {
+        
+        synchronized (m_keyToServiceReferencesMap) {
+            // TODO this is a quite expensive linear scan over the existing collection
+            // because we first need to remove any existing references and they can be
+            // all over the place :)
+            Iterator<List<ServiceReference>> iterator = m_keyToServiceReferencesMap.values().iterator();
+            while (iterator.hasNext()) {
+                List<ServiceReference> list = iterator.next();
+                if (list != null) {
+                    Iterator<ServiceReference> i2 = list.iterator();
+                    while (i2.hasNext()) {
+                        ServiceReference ref = i2.next();
+                        if (ref.equals(reference)) {
+                            i2.remove();
+                        }
+                    }
+                }
+            }
+            // only re-add the reference when it is still applicable for this filter index
+            if (shouldBeIndexed(reference)) {
+            	List<String> keys = createKeys(reference);
+	            for (int i = 0; i < keys.size(); i++) {
+	                List<ServiceReference> references = m_keyToServiceReferencesMap.get(keys.get(i));
+	                if (references == null) {
+	                    references = new ArrayList<>();
+	                    m_keyToServiceReferencesMap.put(keys.get(i), references);
+	                }
+	                references.add(reference);
+	            }
+            }
+        }
+    }
+
+    protected void handleServiceRemove(ServiceReference reference) {
+        List<String> keys = createKeys(reference);
+        synchronized (m_keyToServiceReferencesMap) {
+            for (int i = 0; i < keys.size(); i++) {
+                List<ServiceReference> references = m_keyToServiceReferencesMap.get(keys.get(i));
+                if (references != null) {
+                    references.remove(reference);
+                    if (references.isEmpty()) {
+                    	m_keyToServiceReferencesMap.remove(keys.get(i));
+                    }
+                }
+            }
+        }
+    }
+    
+    protected boolean shouldBeIndexed(ServiceReference reference) {
+    	// is already applicable, so we should only check whether there's a negate field in the filter which has a value in the reference
+    	Iterator<String> negatePropertyKeyIterator = m_negatePropertyKeys.iterator();
+    	while (negatePropertyKeyIterator.hasNext()) {
+    		String negatePropertyKey = negatePropertyKeyIterator.next();
+    		if (reference.getProperty(negatePropertyKey) != null) {
+    			return false;
+    		}
+    	}
+    	return true;
+    }
+
+    public void open(BundleContext context) {
+        synchronized (m_lock) {
+            if (m_context != null) {
+                throw new IllegalStateException("Filter already open.");
+            }
+            try {
+                m_tracker = new ServiceTracker(context, context.createFilter("(" + Constants.OBJECTCLASS + "=*)"), this);
+            }
+            catch (InvalidSyntaxException e) {
+                throw new Error();
+            }
+            m_context = context;
+        }
+        m_tracker.open(true, true);
+    }
+
+	public void close() {
+        ServiceTracker tracker;
+        synchronized (m_lock) {
+            if (m_context == null) {
+                throw new IllegalStateException("Filter already closed.");
+            }
+            tracker = m_tracker;
+            m_tracker = null;
+            m_context = null;
+        }
+        tracker.close();
+	}
+
+    public List<ServiceReference> getAllServiceReferences(String clazz, String filter) {
+        List<ServiceReference> result = new ArrayList<>();
+        String key = createKeyFromFilter(clazz, filter);
+        synchronized (m_keyToServiceReferencesMap) {
+            List<ServiceReference> references = m_keyToServiceReferencesMap.get(key);
+            if (references != null) {
+                result.addAll(references);
+            }
+        }
+        return result;
+    }
+
+    public void serviceChanged(ServiceEvent event) {
+        if (isApplicable(event.getServiceReference())) {
+            List<String> keys = createKeys(event.getServiceReference());
+            List<ServiceListener> list = new ArrayList<ServiceListener>();
+            synchronized (m_keyToListenersMap) {
+                for (int i = 0; i < keys.size(); i++) {
+                    String key = keys.get(i);
+                    List<ServiceListener> listeners = m_keyToListenersMap.get(key);
+                    if (listeners != null) {
+                        list.addAll(listeners);
+                    }
+                }
+            }
+            if (list != null) {
+                Iterator<ServiceListener> iterator = list.iterator();
+                while (iterator.hasNext()) {
+                    ServiceListener listener = iterator.next();
+                    listener.serviceChanged(event);
+                }
+            }
+        }
+    }
+
+    public void addServiceListener(ServiceListener listener, String filter) {
+        String key = createKeyFromFilter(null, filter);
+        synchronized (m_keyToListenersMap) {
+            List<ServiceListener> listeners = m_keyToListenersMap.get(key);
+            if (listeners == null) {
+                listeners = new CopyOnWriteArrayList<ServiceListener>();
+                m_keyToListenersMap.put(key, listeners);
+            }
+            listeners.add(listener);
+            m_listenerToFilterMap.put(listener, filter);
+        }
+    }
+
+    public void removeServiceListener(ServiceListener listener) {
+        synchronized (m_keyToListenersMap) {
+            String filter = m_listenerToFilterMap.remove(listener);
+            if (filter != null) {
+            	// the listener does exist
+        		String key = createKeyFromFilter(null, filter);
+        		
+        		boolean result = filter != null;
+        		if (result) {
+        			List<ServiceListener> listeners = m_keyToListenersMap.get(key);
+        			if (listeners != null) {
+        				listeners.remove(listener);
+        				if (listeners.isEmpty()) {
+        					m_keyToListenersMap.remove(key);
+        				}
+        			}
+        			// TODO actually, if listeners == null that would be strange....
+        		}
+            }
+        }
+    }
+    
+    protected Collection<ServiceListener> getServiceListeners() {
+    	return m_listenerToFilterMap.keySet();
+    }
+    
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(" dMultiPropertyExactFilter[");
+        sb.append("K2L: " + m_keyToListenersMap.size());
+        sb.append(", K2SR: " + m_keyToServiceReferencesMap.size());
+        sb.append(", L2F: " + m_listenerToFilterMap.size());
+        sb.append("]");
+        return sb.toString();
+    }
+
+	@Override
+	public void swappedService(ServiceReference reference, Object service,
+			ServiceReference newReference, Object newService) {
+		addedService(newReference, newService);
+		removedService(reference, service);
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/Property.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/Property.java
new file mode 100644
index 0000000..deb31c4
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/index/multiproperty/Property.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.dm.impl.index.multiproperty;
+
+import java.util.Set;
+import java.util.TreeSet;
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+
+public class Property {
+	boolean m_negate;
+	boolean m_valid = true;
+	String m_key;
+	String m_value;
+	Set<String> m_values = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+	
+	public Property() {
+	}
+	
+	public Property(boolean negate, String key, String value) {
+		super();
+		m_negate = negate;
+		m_key = key.toLowerCase();
+		m_values.add(value);
+		m_value = value;
+	}
+
+	public void setNegate(boolean negate) {
+		this.m_negate = negate;
+	}
+	
+	public void setKey(String key) {
+		this.m_key = key.toLowerCase();
+	}
+	
+	public void addValue(String value, boolean negate) {
+		if (this.m_negate != negate) {
+			// multiproperty with different negations, causes invalid configuration.
+			m_valid = false;
+		}
+		if (this.m_value == null) {
+			// value has not bee set yet
+			this.m_value = value;
+		}
+		if (value != null) {
+			m_values.add(value);
+		}
+	}
+	
+	public boolean isNegate() {
+		return m_negate;
+	}
+	
+	public String getKey() {
+		return m_key;
+	}
+	
+	public String getValue() {
+		return m_value;
+	}
+	
+	public Set<String> getValues() {
+		return m_values;
+	}
+	
+	public boolean isWildcard() {
+		return "*".equals(m_value);
+	}
+	
+	public boolean isMultiValue() {
+		return m_values.size() > 1;
+	}
+
+	public String toString() {
+		return "Property [negate=" + m_negate + ", key=" + m_key + ", values="
+				+ m_values + "]";
+	}
+	
+	public boolean isValid() {
+		return m_valid;
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/AttributeDefinitionImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/AttributeDefinitionImpl.java
new file mode 100644
index 0000000..3a72c95
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/AttributeDefinitionImpl.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.metatype;
+
+import org.osgi.service.metatype.AttributeDefinition;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class AttributeDefinitionImpl implements AttributeDefinition {
+    private PropertyMetaDataImpl m_propertyMetaData;
+    private Resource m_resource;
+
+    public AttributeDefinitionImpl(PropertyMetaDataImpl propertyMetaData, Resource resource) {
+        m_propertyMetaData = propertyMetaData;
+        m_resource = resource;
+    }
+
+    public int getCardinality() {
+        return m_propertyMetaData.getCardinality();
+    }
+
+    public String[] getDefaultValue() {
+        return m_propertyMetaData.getDefaults();
+    }
+
+    public String getDescription() {
+        return m_resource.localize(m_propertyMetaData.getDescription());
+    }
+
+    public String getID() {
+        return m_propertyMetaData.getId();
+    }
+
+    public String getName() {
+        return m_resource.localize(m_propertyMetaData.getHeading());
+    }
+
+    public String[] getOptionLabels() {
+        String[] labels = m_propertyMetaData.getOptionLabels();
+        if (labels != null) {
+            for (int i = 0; i < labels.length; i++) {
+                labels[i] = m_resource.localize(labels[i]);
+            }
+        }
+        return labels;
+    }
+
+    public String[] getOptionValues() {
+        return m_propertyMetaData.getOptionValues();
+    }
+
+    public int getType() {
+        return m_propertyMetaData.getType();
+    }
+
+    public String validate(String value) {
+        return null;
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/MetaTypeProviderImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/MetaTypeProviderImpl.java
new file mode 100644
index 0000000..d3bf2e2
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/MetaTypeProviderImpl.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.metatype;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import org.apache.felix.dm.Logger;
+import org.apache.felix.dm.PropertyMetaData;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+/**
+ * When a ConfigurationDepdendency is configured with properties metadata, we provide
+ * a specific ManagedService which also implements the MetaTypeProvider interface. This interface
+ * allows the MetaTypeService to retrieve our properties metadata, which will then be handled by webconsole.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MetaTypeProviderImpl implements MetaTypeProvider, ManagedService, ManagedServiceFactory {
+    private ManagedService m_managedServiceDelegate;
+    private ManagedServiceFactory m_managedServiceFactoryDelegate;
+    private ArrayList<PropertyMetaData> m_propertiesMetaData = new ArrayList<>();
+    private String m_description;
+    private String m_heading;
+    private String m_localization;
+    private HashMap<String, Properties> m_localesProperties = new HashMap<>();
+    private Logger m_logger;
+    private BundleContext m_bctx;
+    private String m_pid;
+
+    public MetaTypeProviderImpl(String pid, BundleContext ctx, Logger logger, ManagedService msDelegate, ManagedServiceFactory msfDelegate) {
+        m_pid = pid;
+        m_bctx = ctx;
+        m_logger = logger;
+        m_managedServiceDelegate = msDelegate;
+        m_managedServiceFactoryDelegate = msfDelegate;
+        // Set the default localization file base name (see core specification, in section Localization on page 68).
+        // By default, this file can be stored in OSGI-INF/l10n/bundle.properties (and corresponding localized version
+        // in OSGI-INF/l10n/bundle_en_GB_welsh.properties,  OSGI-INF/l10n/bundle_en_GB.properties, etc ...
+        // This default localization property file name can be overriden using the PropertyMetaData.setLocalization method.
+        m_localization = (String) m_bctx.getBundle().getHeaders().get(Constants.BUNDLE_LOCALIZATION);
+        if (m_localization == null) {
+            m_localization = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public MetaTypeProviderImpl(MetaTypeProviderImpl prototype, ManagedService msDelegate, ManagedServiceFactory msfDelegate) {
+        m_pid = prototype.m_pid;
+        m_bctx = prototype.m_bctx;
+        m_logger = prototype.m_logger;
+        m_localization = prototype.m_localization;
+        m_propertiesMetaData = prototype.m_propertiesMetaData != null ? (ArrayList<PropertyMetaData>) prototype.m_propertiesMetaData.clone() : null;
+        m_description = prototype.m_description;
+        m_heading = prototype.m_heading;
+        m_localization = prototype.m_localization;
+        m_localesProperties = prototype.m_localesProperties != null ? (HashMap<String, Properties>) prototype.m_localesProperties.clone() : null;
+        m_managedServiceDelegate = msDelegate;
+        m_managedServiceFactoryDelegate = msfDelegate;
+    }
+
+
+    /**
+     * Registers the metatype information of a given configuration property
+     * @param property
+     */
+    public void add(PropertyMetaData property) {
+        m_propertiesMetaData.add(property);
+    }
+
+    /**
+     * A human readable description of the PID this annotation is associated with. Example: "Configuration for the PrinterService bundle".
+     * @return A human readable description of the PID this annotation is associated with (may be localized)
+     */
+    public void setDescription(String description) {
+        m_description = description;
+    }
+
+    /**
+     * The label used to display the tab name (or section) where the properties are displayed. Example: "Printer Service".
+     * @return The label used to display the tab name where the properties are displayed (may be localized)
+     */
+    public void setName(String heading) {
+        m_heading = heading;
+    }
+
+    /**
+     * Points to the basename of the Properties file that can localize the Meta Type informations.
+     * By default, (e.g. <code>setLocalization("person")</code> would match person_du_NL.properties in the root bundle directory.
+     * The default localization base name for the properties is OSGI-INF/l10n/bundle, but can
+     * be overridden by the manifest Bundle-Localization header (see core specification, in section Localization on page 68).
+     */
+    public void setLocalization(String path) {
+        if (path.endsWith(".properties")) {
+            throw new IllegalArgumentException(
+                "path must point to the base name of the propertie file, "
+                + "excluding local suffixes. For example: "
+                + "foo/bar/person is valid and matches the property file \"foo/bar/person_bundle_en_GB_welsh.properties\"");
+        }
+        m_localization = path.startsWith("/") ? path.substring(1) : path;
+    }
+
+    // --------------- MetaTypeProvider interface -------------------------------------------------
+
+    /**
+     * Returns all the Locales our bundle is containing. For instance, if our bundle contains the following localization files:
+     * OSGI-INF/l10n/bundle_en_GB_welsh.properties and OSGI-INF/l10n/bundle_en_GB.properties, then this method will return
+     * "en_GB", "en_GB_welsh" ...
+     * @return the list of Locale supported by our bundle.
+     */
+    @SuppressWarnings("rawtypes")
+    public String[] getLocales() {
+        int lastSlash = m_localization.lastIndexOf("/");
+        String path = (lastSlash == -1) ? "/" : ("/" + m_localization.substring(0, lastSlash - 1));
+        String base = (lastSlash == -1) ? m_localization : m_localization.substring(lastSlash + 1);
+        Enumeration e = m_bctx.getBundle().findEntries(path,
+            base + "*.properties", false);
+        if (e == null) {
+            return null;
+        }
+        
+        TreeSet<String> set = new TreeSet<>();
+        while (e.hasMoreElements()) {
+            // We have found a locale property file in the form of "path/file[_language[_ country[_variation]].properties"
+            // And now, we have to get the "language[_country[_variation]]" part ...
+            URL url = (URL) e.nextElement();
+            String name = url.getPath();
+            name = name.substring(name.lastIndexOf("/") + 1);
+            int underscore = name.indexOf("_");
+            if (underscore != -1) {
+                name = name.substring(underscore + 1, name.length() - ".properties".length());
+            }
+            if (name.length() > 0) {
+                set.add(name);
+            }
+        }
+
+        String[] locales = (String[]) set.toArray(new String[set.size()]);
+        return locales.length == 0 ? null : locales;
+    }
+
+    /**
+     * Returns the ObjectClassDefinition for a given Pid/Locale.
+     */
+    public ObjectClassDefinition getObjectClassDefinition(String id, String locale) {
+        try {
+            // Check if the id matches our PID
+            if (!id.equals(m_pid)) {
+                m_logger.log(LogService.LOG_ERROR, "id " + id + " does not match pid " + m_pid);
+                return null;
+            }
+
+            Properties localeProperties = getLocaleProperties(locale);
+            return new ObjectClassDefinitionImpl(m_pid, m_heading,
+                m_description, m_propertiesMetaData, new Resource(localeProperties));
+        }
+
+        catch (Throwable t) {
+            m_logger.log(
+                Logger.LOG_ERROR,
+                "Unexpected exception while geting ObjectClassDefinition for " + id + " (locale="
+                    + locale + ")", t);
+            return null;
+        }
+    }
+
+    /**
+     * We also implements the ManagedService and we just delegates the configuration handling to
+     * our associated ConfigurationDependency.
+     */
+    @SuppressWarnings("rawtypes")
+    public void updated(Dictionary properties) throws ConfigurationException {
+        m_managedServiceDelegate.updated(properties);
+    }
+
+    /**
+     * Gets the properties for a given Locale.
+     * @param locale
+     * @return
+     * @throws IOException
+     */
+    private synchronized Properties getLocaleProperties(String locale) throws IOException {
+        locale = locale == null ? Locale.getDefault().toString() : locale;
+        Properties properties = (Properties) m_localesProperties.get(locale);
+        if (properties == null) {
+            properties = new Properties();
+            URL url = m_bctx.getBundle().getEntry(m_localization + ".properties");
+            if (url != null) {
+                loadLocale(properties, url);
+            }
+
+            String path = m_localization;
+            StringTokenizer tok = new StringTokenizer(locale, "_");
+            while (tok.hasMoreTokens()) {
+                path += "_" + tok.nextToken();
+                url = m_bctx.getBundle().getEntry(path + ".properties");
+                if (url != null) {
+                    properties = new Properties(properties);
+                    loadLocale(properties, url);
+                }
+            }
+            m_localesProperties.put(locale, properties);
+        }
+        return properties;
+    }
+
+    /**
+     * Loads a Locale Properties file.
+     * @param properties
+     * @param url
+     * @throws IOException
+     */
+    private void loadLocale(Properties properties, URL url) throws IOException {
+        InputStream in = null;
+        try {
+            in = url.openStream();
+            properties.load(in);
+        }
+        finally {
+            if (in != null) {
+                try {
+                    in.close();
+                }
+                catch (IOException ignored) {
+                }
+            }
+        }
+    }
+
+    // ManagedServiceFactory implementation
+    public void deleted(String pid) {
+        m_managedServiceFactoryDelegate.deleted(pid);
+    }
+
+    public String getName() {
+        return m_pid;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public void updated(String pid, Dictionary properties) throws ConfigurationException {
+        m_managedServiceFactoryDelegate.updated(pid, properties);
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/ObjectClassDefinitionImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/ObjectClassDefinitionImpl.java
new file mode 100644
index 0000000..bd0a980
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/ObjectClassDefinitionImpl.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.metatype;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.dm.PropertyMetaData;
+import org.osgi.service.metatype.AttributeDefinition;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+/**
+ * ObjectClassDefinition implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ObjectClassDefinitionImpl implements ObjectClassDefinition {
+    // Our OCD name (may be localized)
+    private String m_name;
+    
+    // Our OCD description (may be localized)
+    private String m_description;
+    
+    // Our OCD id
+    private String m_id;
+    
+    // The list of Properties MetaData objects (from DependencyManager API)
+    private final List<PropertyMetaData> m_propertiesMetaData;
+    
+    // The localized resource that can be used when localizing some parameters
+    private Resource m_resource;
+
+    public ObjectClassDefinitionImpl(String id, String name, String description, List<PropertyMetaData> propertiesMetaData, Resource resource) {
+        m_id = id;
+        m_name = name;
+        m_description = description;
+        m_propertiesMetaData = propertiesMetaData;
+        m_resource = resource;
+    }
+
+    // --------------------- ObjectClassDefinition ----------------------------------------
+
+    public AttributeDefinition[] getAttributeDefinitions(int filter) {
+        List<AttributeDefinition> attrs = new ArrayList<>();
+        for (int i = 0; i < m_propertiesMetaData.size(); i++) {
+            PropertyMetaDataImpl metaData = (PropertyMetaDataImpl) m_propertiesMetaData.get(i);
+            switch (filter) {
+                case ObjectClassDefinition.ALL:
+                    attrs.add(new AttributeDefinitionImpl(metaData, m_resource));
+                    break;
+                case ObjectClassDefinition.OPTIONAL:
+                    if (!metaData.isRequired()) {
+                        attrs.add(new AttributeDefinitionImpl(metaData, m_resource));
+                    }
+                    break;
+                case ObjectClassDefinition.REQUIRED:
+                    if (metaData.isRequired()) {
+                        attrs.add(new AttributeDefinitionImpl(metaData, m_resource));
+                    }
+                    break;
+                default:
+            }
+        }
+
+        AttributeDefinition[] array = new AttributeDefinitionImpl[attrs.size()];
+        return attrs.toArray(array);
+    }
+
+    public String getDescription() {
+        return m_resource.localize(m_description);
+    }
+
+    public String getID() {
+        return m_id;
+    }
+
+    public InputStream getIcon(int size) throws IOException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getName() {
+        return m_resource.localize(m_name);
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/PropertyMetaDataImpl.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/PropertyMetaDataImpl.java
new file mode 100644
index 0000000..583b014
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/PropertyMetaDataImpl.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.impl.metatype;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.dm.PropertyMetaData;
+import org.osgi.service.metatype.AttributeDefinition;
+
+/**
+ * DependencyManager PropertyMetaData Implementation. This class describes meta informations regarding
+ * one given configuration property.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PropertyMetaDataImpl implements PropertyMetaData {
+    /**
+     * List of option labels (may be localized)
+     */
+    List<String> m_optionsLabels = new ArrayList<>();
+    
+    /**
+     * List of option values
+     */
+    List<String> m_optionsValues = new ArrayList<>();
+    
+    /**
+     * Property cardinality.
+     * @see {@link AttributeDefinition#getCardinality()}
+     */
+    private int m_cardinality;
+    
+    /**
+     * Valid default property values
+     */
+    private String[] m_defaults;
+    
+    /**
+     * Property description.
+     */
+    private String m_description;
+    
+    /**
+     * Property title.
+     */
+    private String m_heading;
+    
+    /**
+     * Property unique Id
+     */
+    private String m_id;
+    
+    /**
+     * Required flag.
+     */
+    private boolean m_required;
+    
+    /**
+     * Property Type.
+     * @see {@link AttributeDefinition#getType()}
+     */
+    private int m_type = AttributeDefinition.STRING;
+    
+    /**
+     * Mapping between java types and valid MetaType types.
+     * @see {@link AttributeDefinition#getType()}
+     */
+    @SuppressWarnings({ "unchecked", "serial", "rawtypes" })
+    private final static Map<Class<?>, Integer> m_typeMapping = new HashMap() {{
+        put(Boolean.class, new Integer(AttributeDefinition.BOOLEAN));
+        put(Byte.class, new Integer(AttributeDefinition.BYTE));
+        put(Character.class, new Integer(AttributeDefinition.CHARACTER));
+        put(Double.class, new Integer(AttributeDefinition.FLOAT));
+        put(Integer.class, new Integer(AttributeDefinition.INTEGER));
+        put(Long.class, new Integer(AttributeDefinition.LONG));
+        put(Short.class, new Integer(AttributeDefinition.SHORT));
+        put(String.class, new Integer(AttributeDefinition.STRING));
+    }};
+
+    public PropertyMetaData addOption(String optionLabel, String optionValue) {
+        m_optionsLabels.add(optionLabel);
+        m_optionsValues.add(optionValue);
+        return this;
+    }
+
+    public PropertyMetaData setCardinality(int cardinality) {
+        m_cardinality = cardinality;
+        return this;
+    }
+
+    public PropertyMetaData setDefaults(String[] defaults) {
+        m_defaults = defaults;
+        return this;
+    }
+
+    public PropertyMetaData setDescription(String description) {
+        m_description = description;
+        return this;
+    }
+
+    public PropertyMetaData setHeading(String heading) {
+        m_heading = heading;
+        return this;
+    }
+
+    public PropertyMetaData setId(String id) {
+        m_id = id;
+        return this;
+    }
+
+    public PropertyMetaData setRequired(boolean required) {
+        m_required = required;
+        return this;
+    }
+
+    public PropertyMetaData setType(Class<?> classType) {
+        Integer type = (Integer) m_typeMapping.get(classType);
+        if (type == null) {
+            throw new IllegalArgumentException("Invalid type: " + classType + ". Valid types are "
+                + m_typeMapping.keySet());
+        }
+        m_type = type.intValue();
+        return this;
+    }
+
+    public String[] getOptionLabels() {
+        String[] optionLabels = new String[m_optionsLabels.size()];
+        return (String[]) m_optionsLabels.toArray(optionLabels);
+    }
+
+    public String[] getOptionValues() {
+        String[] optionValues = new String[m_optionsValues.size()];
+        return (String[]) m_optionsValues.toArray(optionValues);
+    }
+
+    public int getCardinality() {
+        return m_cardinality;
+    }
+
+    public String[] getDefaults() {
+        return m_defaults;
+    }
+
+    public String getDescription() {
+        return m_description;
+    }
+
+    public String getHeading() {
+        return m_heading;
+    }
+
+    public String getId() {
+        return m_id;
+    }
+
+    public boolean isRequired() {
+        return m_required;
+    }
+
+    public int getType() {
+        return m_type;
+    }
+    
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("cardinality=").append(m_cardinality);
+        sb.append("; defaults="); 
+        for (int i = 0; i < m_defaults.length; i ++) {
+            sb.append(m_defaults[i]).append(" ");
+        }
+        sb.append("; description=").append(m_description);
+        sb.append("; heading=").append(m_heading);
+        sb.append("; id=").append(m_id);
+        sb.append("; required=").append(m_required);
+        sb.append("; type=").append(getType());
+        sb.append("; optionLabels=");
+        for (int i = 0; i < m_optionsLabels.size(); i ++) {
+            sb.append(m_optionsLabels.get(i)).append(" ");
+        }
+        sb.append("; optionValues=");
+        for (int i = 0; i < m_optionsValues.size(); i ++) {
+            sb.append(m_optionsValues.get(i)).append(" ");
+        }
+        return sb.toString();
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/Resource.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/Resource.java
new file mode 100644
index 0000000..c588a0c
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/impl/metatype/Resource.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.dm.impl.metatype;
+
+import java.util.Properties;
+
+/**
+ * Helper class used to localize a given Property Meta Data.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Resource {
+    private Properties m_properties;
+
+    public Resource(Properties properties) {
+        m_properties = properties;
+    }
+    
+    public String localize(String param) {
+        if (m_properties != null && param != null && param.startsWith("%")) {
+            param = param.substring(1);
+            return m_properties.getProperty(param);
+        }
+        return param;
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo
new file mode 100644
index 0000000..bd33369
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/packageinfo
@@ -0,0 +1 @@
+version 4.0.0
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/AbstractCustomizerActionSet.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/AbstractCustomizerActionSet.java
new file mode 100644
index 0000000..4add2c2
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/AbstractCustomizerActionSet.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.tracker;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Actions which can be performed on a given customizer interface.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class AbstractCustomizerActionSet {
+
+	enum Type { ADDED, MODIFIED, REMOVED }
+
+	final List<CustomizerAction> m_actions = new ArrayList<>();
+
+	public void addCustomizerAdded(Object item, Object related, Object object) {
+		m_actions.add(new CustomizerAction(Type.ADDED, item, related, object));
+	}
+	
+	public void addCustomizerModified(Object item, Object related, Object object) {
+		m_actions.add(new CustomizerAction(Type.MODIFIED, item, related, object));
+	}
+	
+	public void addCustomizerRemoved(Object item, Object related, Object object) {
+		m_actions.add(new CustomizerAction(Type.REMOVED, item, related, object));
+	}
+	
+	public void appendActionSet(AbstractCustomizerActionSet actionSet) {
+		for (CustomizerAction action : actionSet.getActions()) {
+			m_actions.add(action);
+		}
+	}
+	
+	abstract void execute();
+	
+	public List<CustomizerAction> getActions() {
+		return m_actions;
+	}
+	
+	@Override
+	public String toString() {
+		return "AbstractCustomizerActionSet [m_actions=" + m_actions + "]";
+	}
+
+	static class CustomizerAction {
+		private final Type m_type;
+		private final Object m_item;
+		private final Object m_related;
+		private final Object m_object;
+		
+		public CustomizerAction(Type type, Object item, Object related, Object object) {
+			m_type = type;
+			m_item = item;
+			m_related = related;
+			m_object = object;
+		}
+		
+		public Type getType() {
+			return m_type;
+		}
+		
+		public Object getItem() {
+			return m_item;
+		}
+		
+		public Object getRelated() {
+			return m_related;
+		}
+		
+		public Object getObject() {
+			return m_object;
+		}
+
+		@Override
+		public String toString() {
+			return "CustomizerAction [m_type=" + m_type + ", m_item=" + m_item
+					+ ", m_related=" + m_related + ", m_object=" + m_object
+					+ "]";
+		}
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/AbstractTracked.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/AbstractTracked.java
new file mode 100644
index 0000000..5e254ad
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/AbstractTracked.java
@@ -0,0 +1,486 @@
+package org.apache.felix.dm.tracker;
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
+ * 
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.dm.impl.SerialExecutor;
+
+/**
+ * Abstract class to track items. If a Tracker is reused (closed then reopened),
+ * then a new AbstractTracked object is used. This class acts a map of tracked
+ * item -> customized object. Subclasses of this class will act as the listener
+ * object for the tracker. This class is used to synchronize access to the
+ * tracked items. This is not a public class. It is only for use by the
+ * implementation of the Tracker class.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 5871 $
+ * @since 1.4
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+abstract class AbstractTracked {
+	/* set this to true to compile in debug messages */
+	private static final boolean		DEBUG	= false;
+
+	/**
+	 * Map of tracked items to customized objects.
+	 * 
+	 * @GuardedBy this
+	 */
+	private Map			tracked;
+
+	/**
+	 * Modification count. This field is initialized to zero and incremented by
+	 * modified.
+	 * 
+	 * @GuardedBy this
+	 */
+	private int					trackingCount;
+
+	/**
+	 * List of items in the process of being added. This is used to deal with
+	 * nesting of events. Since events may be synchronously delivered, events
+	 * 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 List			adding;
+
+	/**
+	 * true if the tracked object is closed.
+	 * 
+	 * This field is volatile because it is set by one thread and read by
+	 * another.
+	 */
+	volatile boolean			closed;
+
+	/**
+	 * Initial list of items for the tracker. This is used to correctly process
+	 * the initial items which could be modified before they are tracked. This
+	 * is necessary since the initial set of tracked items are not "announced"
+	 * by events and therefore the event which makes the item untracked could be
+	 * delivered before we track the item.
+	 * 
+	 * An item must not be in both the initial and adding lists at the same
+	 * time. An item 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;
+	
+	private final SerialExecutor m_executor = new SerialExecutor(null); 
+
+	/**
+	 * AbstractTracked constructor.
+	 */
+    AbstractTracked() {
+	    this.tracked = new HashMap();
+	    trackingCount = 0;
+	    adding = new ArrayList(6);
+	    initial = new LinkedList();
+	    closed = false;
+	}
+	
+	void setTracked(HashMap map) {
+	    this.tracked = map;
+	}
+
+	/**
+	 * Set initial list of items into tracker before events begin to be
+	 * received.
+	 * 
+	 * This method must be called from Tracker's open method while synchronized
+	 * on this object in the same synchronized block as the add listener call.
+	 * 
+	 * @param list The initial list of items to be tracked. <code>null</code>
+	 *        entries in the list are ignored.
+	 * @GuardedBy this
+	 */
+    void setInitial(Object[] list) {
+		if (list == null) {
+			return;
+		}
+		int size = list.length;
+		for (int i = 0; i < size; i++) {
+			Object item = list[i];
+			if (item == null) {
+				continue;
+			}
+			if (DEBUG) {
+				System.out.println("AbstractTracked.setInitial: " + item); //$NON-NLS-1$
+			}
+			initial.add(item);
+		}
+	}
+
+	/**
+	 * Track the initial list of items. This is called after events can begin to
+	 * be received.
+	 * 
+	 * This method must be called from Tracker's open method while not
+	 * synchronized on this object after the add listener call.
+	 * 
+	 */
+	void trackInitial() {
+		while (true) {
+			Object item;
+			synchronized (this) {
+				if (closed || (initial.size() == 0)) {
+					/*
+					 * if there are no more initial items
+					 */
+					return; /* we are done */
+				}
+				/*
+				 * move the first item from the initial list to the adding list
+				 * within this synchronized block.
+				 */
+				item = initial.removeFirst();
+				if (tracked.get(item) != null) {
+					/* if we are already tracking this item */
+					if (DEBUG) {
+						System.out
+								.println("AbstractTracked.trackInitial[already tracked]: " + item); //$NON-NLS-1$
+					}
+					continue; /* skip this item */
+				}
+				if (adding.contains(item)) {
+					/*
+					 * if this item is already in the process of being added.
+					 */
+					if (DEBUG) {
+						System.out
+								.println("AbstractTracked.trackInitial[already adding]: " + item); //$NON-NLS-1$
+					}
+					continue; /* skip this item */
+				}
+				adding.add(item);
+				final AbstractCustomizerActionSet actionSet = trackAdding(item, null);
+				m_executor.schedule(new Runnable() {
+
+					@Override
+					public void run() {
+						actionSet.execute();
+						
+					}
+					
+				});
+			}
+			if (DEBUG) {
+				System.out.println("AbstractTracked.trackInitial: " + item); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Called by the owning Tracker object when it is closed.
+	 */
+	void close() {
+		closed = true;
+	}
+
+	abstract AbstractCustomizerActionSet createCustomizerActionSet();
+	
+	/**
+	 * Begin to track an item.
+	 * 
+	 * @param item Item to be tracked.
+	 * @param related Action related object.
+	 */
+	AbstractCustomizerActionSet track(final Object item, final Object related) {
+		final Object object;
+		final AbstractCustomizerActionSet actionSet = createCustomizerActionSet();
+		synchronized (this) {
+			if (closed) {
+				return actionSet;
+			}
+			object = tracked.get(item);
+			if (object == null) { /* we are not tracking the item */
+				if (adding.contains(item)) {
+					/* if this item is already in the process of being added. */
+					if (DEBUG) {
+						System.out
+								.println("AbstractTracked.track[already adding]: " + item); //$NON-NLS-1$
+					}
+					return actionSet;
+				}
+				adding.add(item); /* mark this item is being added */
+			}
+			else { /* we are currently tracking this item */
+				if (DEBUG) {
+					System.out
+							.println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
+				}
+				modified(); /* increment modification count */
+			}
+		}
+
+		if (object == null) { /* we are not tracking the item */
+			actionSet.appendActionSet(trackAdding(item, related));
+		}
+		else {
+			/* Call customizer outside of synchronized region */
+			actionSet.addCustomizerModified(item, related, object);
+			/*
+			 * If the customizer throws an unchecked exception, it is safe to
+			 * let it propagate
+			 */
+		}
+		return actionSet;
+	}
+
+	/**
+	 * Common logic to add an item to the tracker used by track and
+	 * trackInitial. The specified item must have been placed in the adding list
+	 * before calling this method.
+	 * 
+	 * @param item Item to be tracked.
+	 * @param related Action related object.
+	 */
+	private AbstractCustomizerActionSet trackAdding(final Object item, final Object related) {
+		final AbstractCustomizerActionSet actionSet = createCustomizerActionSet();
+		if (DEBUG) {
+			System.out.println("AbstractTracked.trackAdding: " + item); //$NON-NLS-1$
+		}
+		Object object = null;
+		boolean becameUntracked = false;
+		/* Call customizer outside of synchronized region */
+		try {
+			object = customizerAdding(item, related);
+			/*
+			 * If the customizer throws an unchecked exception, it will
+			 * propagate after the finally
+			 */
+		}
+		finally {
+			boolean needToCallback = false;
+			synchronized (this) {
+				if (adding.remove(item) && !closed) {
+					/*
+					 * if the item was not untracked during the customizer
+					 * callback
+					 */
+					if (object != null) {
+						tracked.put(item, object);
+						modified(); /* increment modification count */
+						notifyAll(); /* notify any waiters */
+						needToCallback = true; /* marrs: invoke added callback */
+					}
+				}
+				else {
+					becameUntracked = true;
+				}
+			}
+			if (needToCallback) {
+				actionSet.addCustomizerAdded(item, related, object);
+			}
+		}
+		/*
+		 * The item became untracked during the customizer callback.
+		 */
+		if (becameUntracked && (object != null)) {
+			if (DEBUG) {
+				System.out
+						.println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
+			}
+			/* Call customizer outside of synchronized region */
+			actionSet.addCustomizerRemoved(item, related, object);
+			/*
+			 * If the customizer throws an unchecked exception, it is safe to
+			 * let it propagate
+			 */
+		}
+		return actionSet;
+	}
+
+	/**
+	 * Discontinue tracking the item.
+	 * 
+	 * @param item Item to be untracked.
+	 * @param related Action related object.
+	 */
+	AbstractCustomizerActionSet untrack(final Object item, final Object related) {
+		AbstractCustomizerActionSet actionSet = createCustomizerActionSet();
+		final Object object;
+		synchronized (this) {
+			if (initial.remove(item)) { /*
+										 * if this item is already in the list
+										 * of initial references to process
+										 */
+				if (DEBUG) {
+					System.out
+							.println("AbstractTracked.untrack[removed from initial]: " + item); //$NON-NLS-1$
+				}
+				return actionSet; /*
+						 * we have removed it from the list and it will not be
+						 * processed
+						 */
+			}
+
+			if (adding.remove(item)) { /*
+										 * if the item is in the process of
+										 * being added
+										 */
+				if (DEBUG) {
+					System.out
+							.println("AbstractTracked.untrack[being added]: " + item); //$NON-NLS-1$
+				}
+				return actionSet; /*
+						 * in case the item is untracked while in the process of
+						 * adding
+						 */
+			}
+			object = tracked.remove(item); /*
+											 * must remove from tracker before
+											 * calling customizer callback
+											 */
+			if (object == null) { /* are we actually tracking the item */
+				return actionSet;
+			}
+			modified(); /* increment modification count */
+		}
+		if (DEBUG) {
+			System.out.println("AbstractTracked.untrack[removed]: " + item); //$NON-NLS-1$
+		}
+		/* Call customizer outside of synchronized region */
+		actionSet.addCustomizerRemoved(item, related, object);
+		/*
+		 * If the customizer throws an unchecked exception, it is safe to let it
+		 * propagate
+		 */
+		return actionSet;
+	}
+
+	/**
+	 * Returns the number of tracked items.
+	 * 
+	 * @return The number of tracked items.
+	 * 
+	 * @GuardedBy this
+	 */
+	int size() {
+		return tracked.size();
+	}
+
+	/**
+	 * Return the customized object for the specified item
+	 * 
+	 * @param item The item to lookup in the map
+	 * @return The customized object for the specified item.
+	 * 
+	 * @GuardedBy this
+	 */
+	Object getCustomizedObject(final Object item) {
+		return tracked.get(item);
+	}
+
+	/**
+	 * Return the list of tracked items.
+	 * 
+	 * @param list An array to contain the tracked items.
+	 * @return The specified list if it is large enough to hold the tracked
+	 *         items or a new array large enough to hold the tracked items.
+	 * @GuardedBy this
+	 */
+	Object[] getTracked(final Object[] list) {
+		return tracked.keySet().toArray(list);
+	}
+
+	/**
+	 * Increment the modification count. If this method is overridden, the
+	 * overriding method MUST call this method to increment the tracking count.
+	 * 
+	 * @GuardedBy this
+	 */
+	void modified() {
+		trackingCount++;
+	}
+
+	/**
+	 * Returns the tracking count for this <code>ServiceTracker</code> object.
+	 * 
+	 * The tracking count is initialized to 0 when this object is opened. Every
+	 * time an item is added, modified or removed from this object the tracking
+	 * count is incremented.
+	 * 
+	 * @GuardedBy this
+	 * @return The tracking count for this object.
+	 */
+	int getTrackingCount() {
+		return trackingCount;
+	}
+	
+	/**
+	 * Returns the serial executor used by this tracked.
+	 * @return
+	 */
+	SerialExecutor getExecutor() {
+		return m_executor;
+	}
+
+	/**
+	 * Call the specific customizer adding method. This method must not be
+	 * called while synchronized on this object.
+	 * 
+	 * @param item Item to be tracked.
+	 * @param related Action related object.
+	 * @return Customized object for the tracked item or <code>null</code> if
+	 *         the item is not to be tracked.
+	 */
+	abstract Object customizerAdding(final Object item, final Object related);
+
+	/** marrs: Call the specific customizer added method. */
+	abstract void customizerAdded(final Object item, final Object related, final Object object);
+	
+	/**
+	 * Call the specific customizer modified method. This method must not be
+	 * called while synchronized on this object.
+	 * 
+	 * @param item Tracked item.
+	 * @param related Action related object.
+	 * @param object Customized object for the tracked item.
+	 */
+	abstract void customizerModified(final Object item, final Object related,
+			final Object object);
+
+	/**
+	 * Call the specific customizer removed method. This method must not be
+	 * called while synchronized on this object.
+	 * 
+	 * @param item Tracked item.
+	 * @param related Action related object.
+	 * @param object Customized object for the tracked item.
+	 */
+	abstract void customizerRemoved(final Object item, final Object related,
+			final Object object);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/BundleTracker.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/BundleTracker.java
new file mode 100644
index 0000000..e3b1677
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/BundleTracker.java
@@ -0,0 +1,505 @@
+package org.apache.felix.dm.tracker;
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
+ * 
+ * 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.
+ */
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * The <code>BundleTracker</code> class simplifies tracking bundles much like
+ * the <code>ServiceTracker</code> simplifies tracking services.
+ * <p>
+ * A <code>BundleTracker</code> is constructed with state criteria and a
+ * <code>BundleTrackerCustomizer</code> object. A <code>BundleTracker</code> can
+ * use the <code>BundleTrackerCustomizer</code> to select which bundles are
+ * tracked and to create a customized object to be tracked with the bundle. The
+ * <code>BundleTracker</code> can then be opened to begin tracking all bundles
+ * whose state matches the specified state criteria.
+ * <p>
+ * The <code>getBundles</code> method can be called to get the
+ * <code>Bundle</code> objects of the bundles being tracked. The
+ * <code>getObject</code> method can be called to get the customized object for
+ * a tracked bundle.
+ * <p>
+ * The <code>BundleTracker</code> class is thread-safe. It does not call a
+ * <code>BundleTrackerCustomizer</code> while holding any locks.
+ * <code>BundleTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 5894 $
+ * @since 1.4
+ */
+public class BundleTracker implements BundleTrackerCustomizer {
+	/* set this to true to compile in debug messages */
+	static final boolean			DEBUG	= false;
+
+	/**
+	 * The Bundle Context used by this <code>BundleTracker</code>.
+	 */
+	protected final BundleContext	context;
+
+	/**
+	 * The <code>BundleTrackerCustomizer</code> object for this tracker.
+	 */
+	final BundleTrackerCustomizer	customizer;
+
+	/**
+	 * Tracked bundles: <code>Bundle</code> object -> customized Object and
+	 * <code>BundleListener</code> object
+	 */
+	private volatile Tracked		tracked;
+
+	/**
+	 * Accessor method for the current Tracked object. This method is only
+	 * intended to be used by the unsynchronized methods which do not modify the
+	 * tracked field.
+	 * 
+	 * @return The current Tracked object.
+	 */
+	private Tracked tracked() {
+		return tracked;
+	}
+
+	/**
+	 * State mask for bundles being tracked. This field contains the ORed values
+	 * of the bundle states being tracked.
+	 */
+	final int						mask;
+
+	/**
+	 * Create a <code>BundleTracker</code> for bundles whose state is present in
+	 * the specified state mask.
+	 * 
+	 * <p>
+	 * Bundles whose state is present on the specified state mask will be
+	 * tracked by this <code>BundleTracker</code>.
+	 * 
+	 * @param context The <code>BundleContext</code> against which the tracking
+	 *        is done.
+	 * @param stateMask The bit mask of the <code>OR</code>ing of the bundle
+	 *        states to be tracked.
+	 * @param customizer The customizer object to call when bundles are added,
+	 *        modified, or removed in this <code>BundleTracker</code>. If
+	 *        customizer is <code>null</code>, then this
+	 *        <code>BundleTracker</code> will be used as the
+	 *        <code>BundleTrackerCustomizer</code> and this
+	 *        <code>BundleTracker</code> will call the
+	 *        <code>BundleTrackerCustomizer</code> methods on itself.
+	 * @see Bundle#getState()
+	 */
+	public BundleTracker(BundleContext context, int stateMask,
+			BundleTrackerCustomizer customizer) {
+		this.context = context;
+		this.mask = stateMask;
+		this.customizer = (customizer == null) ? this : customizer;
+	}
+
+	/**
+	 * Open this <code>BundleTracker</code> and begin tracking bundles.
+	 * 
+	 * <p>
+	 * Bundle which match the state criteria specified when this
+	 * <code>BundleTracker</code> was created are now tracked by this
+	 * <code>BundleTracker</code>.
+	 * 
+	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+	 *         with which this <code>BundleTracker</code> was created is no
+	 *         longer valid.
+	 * @throws java.lang.SecurityException If the caller and this class do not
+	 *         have the appropriate
+	 *         <code>AdminPermission[context bundle,LISTENER]</code>, and the
+	 *         Java Runtime Environment supports permissions.
+	 */
+	public void open() {
+		final Tracked t;
+		synchronized (this) {
+			if (tracked != null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("BundleTracker.open"); //$NON-NLS-1$
+			}
+			t = new Tracked();
+			synchronized (t) {
+				context.addBundleListener(t);
+				Bundle[] bundles = context.getBundles();
+				if (bundles != null) {
+					int length = bundles.length;
+					for (int i = 0; i < length; i++) {
+						int state = bundles[i].getState();
+						if ((state & mask) == 0) {
+							/* null out bundles whose states are not interesting */
+							bundles[i] = null;
+						}
+					}
+					/* set tracked with the initial bundles */
+					t.setInitial(bundles); 
+				}
+			}
+			tracked = t;
+		}
+		/* Call tracked outside of synchronized region */
+		t.trackInitial(); /* process the initial references */
+	}
+
+	/**
+	 * Close this <code>BundleTracker</code>.
+	 * 
+	 * <p>
+	 * This method should be called when this <code>BundleTracker</code> should
+	 * end the tracking of bundles.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getBundles()} to get the list of
+	 * tracked bundles to remove.
+	 */
+	public void close() {
+		final Bundle[] bundles;
+		final Tracked outgoing;
+		synchronized (this) {
+			outgoing = tracked;
+			if (outgoing == null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("BundleTracker.close"); //$NON-NLS-1$
+			}
+			outgoing.close();
+			bundles = getBundles();
+			tracked = null;
+			try {
+				context.removeBundleListener(outgoing);
+			}
+			catch (IllegalStateException e) {
+				/* In case the context was stopped. */
+			}
+		}
+		if (bundles != null) {
+			for (int i = 0; i < bundles.length; i++) {
+				outgoing.untrack(bundles[i], null);
+			}
+		}
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>BundleTrackerCustomizer.addingBundle</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>BundleTracker</code> has been
+	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation simply returns the specified <code>Bundle</code>.
+	 * 
+	 * <p>
+	 * This method can be overridden in a subclass to customize the object to be
+	 * tracked for the bundle being added.
+	 * 
+	 * @param bundle The <code>Bundle</code> being added to this
+	 *        <code>BundleTracker</code> object.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or <code>null</code> if there is no bundle event associated
+	 *        with the call to this method.
+	 * @return The specified bundle.
+	 * @see BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)
+	 */
+	public Object addingBundle(Bundle bundle, BundleEvent event) {
+		return bundle;
+	}
+	
+	public void addedBundle(Bundle bundle, BundleEvent event, Object object) {
+		/* do nothing */
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>BundleTrackerCustomizer.modifiedBundle</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>BundleTracker</code> has been
+	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation does nothing.
+	 * 
+	 * @param bundle The <code>Bundle</code> whose state has been modified.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or <code>null</code> if there is no bundle event associated
+	 *        with the call to this method.
+	 * @param object The customized object for the specified Bundle.
+	 * @see BundleTrackerCustomizer#modifiedBundle(Bundle, BundleEvent, Object)
+	 */
+	public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+		/* do nothing */
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>BundleTrackerCustomizer.removedBundle</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>BundleTracker</code> has been
+	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation does nothing.
+	 * 
+	 * @param bundle The <code>Bundle</code> being removed.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or <code>null</code> if there is no bundle event associated
+	 *        with the call to this method.
+	 * @param object The customized object for the specified bundle.
+	 * @see BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)
+	 */
+	public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+		/* do nothing */
+	}
+
+	/**
+	 * Return an array of <code>Bundle</code>s for all bundles being tracked by
+	 * this <code>BundleTracker</code>.
+	 * 
+	 * @return An array of <code>Bundle</code>s or <code>null</code> if no
+	 *         bundles are being tracked.
+	 */
+	public Bundle[] getBundles() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			int length = t.size();
+			if (length == 0) {
+				return null;
+			}
+			return (Bundle[]) t.getTracked(new Bundle[length]);
+		}
+	}
+
+	/**
+	 * Returns the customized object for the specified <code>Bundle</code> if
+	 * the specified bundle is being tracked by this <code>BundleTracker</code>.
+	 * 
+	 * @param bundle The <code>Bundle</code> being tracked.
+	 * @return The customized object for the specified <code>Bundle</code> or
+	 *         <code>null</code> if the specified <code>Bundle</code> is not
+	 *         being tracked.
+	 */
+	public Object getObject(Bundle bundle) {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			return t.getCustomizedObject(bundle);
+		}
+	}
+
+	/**
+	 * Remove a bundle from this <code>BundleTracker</code>.
+	 * 
+	 * The specified bundle will be removed from this <code>BundleTracker</code>
+	 * . If the specified bundle was being tracked then the
+	 * <code>BundleTrackerCustomizer.removedBundle</code> method will be called
+	 * for that bundle.
+	 * 
+	 * @param bundle The <code>Bundle</code> to be removed.
+	 */
+	public void remove(Bundle bundle) {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return;
+		}
+		t.untrack(bundle, null);
+	}
+
+	/**
+	 * Return the number of bundles being tracked by this
+	 * <code>BundleTracker</code>.
+	 * 
+	 * @return The number of bundles being tracked.
+	 */
+	public int size() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return 0;
+		}
+		synchronized (t) {
+			return t.size();
+		}
+	}
+
+	/**
+	 * Returns the tracking count for this <code>BundleTracker</code>.
+	 * 
+	 * The tracking count is initialized to 0 when this
+	 * <code>BundleTracker</code> is opened. Every time a bundle is added,
+	 * modified or removed from this <code>BundleTracker</code> the tracking
+	 * count is incremented.
+	 * 
+	 * <p>
+	 * The tracking count can be used to determine if this
+	 * <code>BundleTracker</code> has added, modified or removed a bundle by
+	 * comparing a tracking count value previously collected with the current
+	 * tracking count value. If the value has not changed, then no bundle has
+	 * been added, modified or removed from this <code>BundleTracker</code>
+	 * since the previous tracking count was collected.
+	 * 
+	 * @return The tracking count for this <code>BundleTracker</code> or -1 if
+	 *         this <code>BundleTracker</code> is not open.
+	 */
+	public int getTrackingCount() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return -1;
+		}
+		synchronized (t) {
+			return t.getTrackingCount();
+		}
+	}
+
+	/**
+	 * Inner class which subclasses AbstractTracked. This class is the
+	 * <code>SynchronousBundleListener</code> object for the tracker.
+	 * 
+	 * @ThreadSafe
+	 * @since 1.4
+	 */
+	class Tracked extends AbstractTracked implements SynchronousBundleListener {
+		/**
+		 * Tracked constructor.
+		 */
+		Tracked() {
+			super();
+		}
+
+		/**
+		 * <code>BundleListener</code> method for the <code>BundleTracker</code>
+		 * class. This method must NOT be synchronized to avoid deadlock
+		 * potential.
+		 * 
+		 * @param event <code>BundleEvent</code> object from the framework.
+		 */
+		public void bundleChanged(final BundleEvent event) {
+			/*
+			 * Check if we had a delayed call (which could happen when we
+			 * close).
+			 */
+			if (closed) {
+				return;
+			}
+			final Bundle bundle = event.getBundle();
+			final int state = bundle.getState();
+			if (DEBUG) {
+				System.out
+						.println("BundleTracker.Tracked.bundleChanged[" + state + "]: " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			if ((state & mask) != 0) {
+				track(bundle, event);
+				/*
+				 * If the customizer throws an unchecked exception, it is safe
+				 * to let it propagate
+				 */
+			}
+			else {
+				untrack(bundle, event);
+				/*
+				 * If the customizer throws an unchecked exception, it is safe
+				 * to let it propagate
+				 */
+			}
+		}
+
+		/**
+		 * Call the specific customizer adding method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Item to be tracked.
+		 * @param related Action related object.
+		 * @return Customized object for the tracked item or <code>null</code>
+		 *         if the item is not to be tracked.
+		 */
+		Object customizerAdding(final Object item,
+				final Object related) {
+			return customizer
+					.addingBundle((Bundle) item, (BundleEvent) related);
+		}
+		
+		void customizerAdded(final Object item, final Object related, final Object object) {
+			customizer.addedBundle((Bundle) item, (BundleEvent) related, object);
+		}
+
+		/**
+		 * Call the specific customizer modified method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
+		 */
+		void customizerModified(final Object item,
+				final Object related, final Object object) {
+			customizer.modifiedBundle((Bundle) item, (BundleEvent) related,
+					object);
+		}
+
+		/**
+		 * Call the specific customizer removed method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
+		 */
+		void customizerRemoved(final Object item,
+				final Object related, final Object object) {
+			customizer.removedBundle((Bundle) item, (BundleEvent) related,
+					object);
+		}
+
+		@Override
+		AbstractCustomizerActionSet createCustomizerActionSet() {
+			return new AbstractCustomizerActionSet() {
+				
+				@Override
+				public void addCustomizerAdded(Object item, Object related, Object object) {
+					customizerAdded(item, related, object);
+				}
+
+				@Override
+				public void addCustomizerModified(Object item, Object related,
+						Object object) {
+					customizerModified(item, related, object);
+				}
+				@Override
+				public void addCustomizerRemoved(Object item, Object related,
+						Object object) {
+					customizerRemoved(item, related, object);
+				}
+						
+				@Override
+				void execute() {
+					// nothing to be done here, since this actionSet executes the actions immediately.
+				}
+			};
+		}
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/BundleTrackerCustomizer.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/BundleTrackerCustomizer.java
new file mode 100644
index 0000000..0fd340e
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/BundleTrackerCustomizer.java
@@ -0,0 +1,106 @@
+package org.apache.felix.dm.tracker;
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
+ * 
+ * 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.
+ */
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+
+/**
+ * The <code>BundleTrackerCustomizer</code> interface allows a
+ * <code>BundleTracker</code> to customize the <code>Bundle</code>s that are
+ * tracked. A <code>BundleTrackerCustomizer</code> is called when a bundle is
+ * being added to a <code>BundleTracker</code>. The
+ * <code>BundleTrackerCustomizer</code> can then return an object for the
+ * tracked bundle. A <code>BundleTrackerCustomizer</code> is also called when a
+ * tracked bundle is modified or has been removed from a
+ * <code>BundleTracker</code>.
+ * 
+ * <p>
+ * The methods in this interface may be called as the result of a
+ * <code>BundleEvent</code> being received by a <code>BundleTracker</code>.
+ * Since <code>BundleEvent</code>s are received synchronously by the
+ * <code>BundleTracker</code>, it is highly recommended that implementations of
+ * these methods do not alter bundle states while being synchronized on any
+ * object.
+ * 
+ * <p>
+ * The <code>BundleTracker</code> class is thread-safe. It does not call a
+ * <code>BundleTrackerCustomizer</code> while holding any locks.
+ * <code>BundleTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 5874 $
+ * @since 1.4
+ */
+public interface BundleTrackerCustomizer {
+	/**
+	 * A bundle is being added to the <code>BundleTracker</code>.
+	 * 
+	 * <p>
+	 * This method is called before a bundle which matched the search parameters
+	 * of the <code>BundleTracker</code> is added to the
+	 * <code>BundleTracker</code>. This method should return the object to be
+	 * tracked for the specified <code>Bundle</code>. The returned object is
+	 * stored in the <code>BundleTracker</code> and is available from the
+	 * {@link BundleTracker#getObject(Bundle) getObject} method.
+	 * 
+	 * @param bundle The <code>Bundle</code> being added to the
+	 *        <code>BundleTracker</code>.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or <code>null</code> if there is no bundle event associated
+	 *        with the call to this method.
+	 * @return The object to be tracked for the specified <code>Bundle</code>
+	 *         object or <code>null</code> if the specified <code>Bundle</code>
+	 *         object should not be tracked.
+	 */
+	public Object addingBundle(Bundle bundle, BundleEvent event);
+	
+	/** marrs: A bundle has been added to the BundleTracker. */
+	public void addedBundle(Bundle bundle, BundleEvent event, Object object);
+
+	/**
+	 * A bundle tracked by the <code>BundleTracker</code> has been modified.
+	 * 
+	 * <p>
+	 * This method is called when a bundle being tracked by the
+	 * <code>BundleTracker</code> has had its state modified.
+	 * 
+	 * @param bundle The <code>Bundle</code> whose state has been modified.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or <code>null</code> if there is no bundle event associated
+	 *        with the call to this method.
+	 * @param object The tracked object for the specified bundle.
+	 */
+	public void modifiedBundle(Bundle bundle, BundleEvent event,
+			Object object);
+
+	/**
+	 * A bundle tracked by the <code>BundleTracker</code> has been removed.
+	 * 
+	 * <p>
+	 * This method is called after a bundle is no longer being tracked by the
+	 * <code>BundleTracker</code>.
+	 * 
+	 * @param bundle The <code>Bundle</code> that has been removed.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or <code>null</code> if there is no bundle event associated
+	 *        with the call to this method.
+	 * @param object The tracked object for the specified bundle.
+	 */
+	public void removedBundle(Bundle bundle, BundleEvent event,
+			Object object);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTracker.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTracker.java
new file mode 100644
index 0000000..f682bbd
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTracker.java
@@ -0,0 +1,1477 @@
+package org.apache.felix.dm.tracker;
+/*
+ * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * 
+ * 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.
+ */
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.felix.dm.impl.ServiceUtil;
+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;
+import org.osgi.framework.Version;
+
+/**
+ * The <code>ServiceTracker</code> class simplifies using services from the
+ * Framework's service registry.
+ * <p>
+ * A <code>ServiceTracker</code> object is constructed with search criteria and
+ * a <code>ServiceTrackerCustomizer</code> object. A <code>ServiceTracker</code>
+ * can use a <code>ServiceTrackerCustomizer</code> to customize the service
+ * objects to be tracked. The <code>ServiceTracker</code> can then be opened to
+ * begin tracking all services in the Framework's service registry that match
+ * the specified search criteria. The <code>ServiceTracker</code> correctly
+ * handles all of the details of listening to <code>ServiceEvent</code>s and
+ * getting and ungetting services.
+ * <p>
+ * The <code>getServiceReferences</code> method can be called to get references
+ * to the services being tracked. The <code>getService</code> and
+ * <code>getServices</code> methods can be called to get the service objects for
+ * the tracked service.
+ * <p>
+ * The <code>ServiceTracker</code> class is thread-safe. It does not call a
+ * <code>ServiceTrackerCustomizer</code> while holding any locks.
+ * <code>ServiceTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 6386 $
+ */
+public class ServiceTracker implements ServiceTrackerCustomizer {
+	/* set this to true to compile in debug messages */
+	static final boolean				DEBUG			= false;
+	/**
+	 * The Bundle Context used by this <code>ServiceTracker</code>.
+	 */
+	protected final BundleContext		context;
+	/**
+	 * The Filter used by this <code>ServiceTracker</code> which specifies the
+	 * search criteria for the services to track.
+	 * 
+	 * @since 1.1
+	 */
+	protected final Filter				filter;
+	/**
+	 * The <code>ServiceTrackerCustomizer</code> 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> -> customized Object and
+	 * <code>ServiceListener</code> object
+	 */
+	private volatile Tracked			tracked;
+
+	/**
+	 * Accessor method for the current Tracked object. This method is only
+	 * intended to be used by the unsynchronized methods which do not modify the
+	 * tracked field.
+	 * 
+	 * @return The current Tracked object.
+	 */
+	private Tracked tracked() {
+		return tracked;
+	}
+
+	/**
+	 * 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;
+
+	/**
+	 * org.osgi.framework package version which introduced
+	 * {@link ServiceEvent#MODIFIED_ENDMATCH}
+	 */
+	private static final Version		endMatchVersion	= new Version(1, 5, 0);
+
+	/**
+	 * Flag that gets set when opening the tracker, determines if the tracker should
+	 * track all aspects or just the highest ranked ones.
+	 */
+    public boolean m_trackAllAspects;
+    
+    private boolean debug = false;
+    private String debugKey;
+    
+    public void setDebug(String debugKey) {
+    	this.debug = true;
+    	this.debugKey = debugKey;
+    }
+
+	/**
+	 * Create a <code>ServiceTracker</code> on the specified
+	 * <code>ServiceReference</code>.
+	 * 
+	 * <p>
+	 * The service referenced by the specified <code>ServiceReference</code>
+	 * will be tracked by this <code>ServiceTracker</code>.
+	 * 
+	 * @param context The <code>BundleContext</code> against which the tracking
+	 *        is done.
+	 * @param reference The <code>ServiceReference</code> 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>. If
+	 *        customizer is <code>null</code>, then this
+	 *        <code>ServiceTracker</code> will be used as the
+	 *        <code>ServiceTrackerCustomizer</code> and this
+	 *        <code>ServiceTracker</code> will call the
+	 *        <code>ServiceTrackerCustomizer</code> methods on itself.
+	 */
+	public ServiceTracker(final BundleContext context,
+			final ServiceReference reference,
+			final 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() + ")"; 
+		try {
+			this.filter = context.createFilter(listenerFilter);
+		}
+		catch (InvalidSyntaxException e) {
+			/*
+			 * we could only get this exception if the ServiceReference was
+			 * invalid
+			 */
+			IllegalArgumentException iae = new IllegalArgumentException(
+					"unexpected InvalidSyntaxException: " + e.getMessage());
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Create a <code>ServiceTracker</code> on the specified class name.
+	 * 
+	 * <p>
+	 * Services registered under the specified class name will be tracked by
+	 * this <code>ServiceTracker</code>.
+	 * 
+	 * @param context The <code>BundleContext</code> against which the tracking
+	 *        is done.
+	 * @param clazz The 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>. If
+	 *        customizer is <code>null</code>, then this
+	 *        <code>ServiceTracker</code> will be used as the
+	 *        <code>ServiceTrackerCustomizer</code> and this
+	 *        <code>ServiceTracker</code> will call the
+	 *        <code>ServiceTrackerCustomizer</code> methods on itself.
+	 */
+	public ServiceTracker(final BundleContext context, final String clazz,
+			final ServiceTrackerCustomizer customizer) {
+		this.context = context;
+		this.trackReference = null;
+		this.trackClass = clazz;
+		this.customizer = (customizer == null) ? this : customizer;
+		// we call clazz.toString to verify clazz is non-null!
+		this.listenerFilter = "(" + Constants.OBJECTCLASS + "="
+				+ clazz.toString() + ")"; 
+		try {
+			this.filter = context.createFilter(listenerFilter);
+		}
+		catch (InvalidSyntaxException e) {
+			/*
+			 * we could only get this exception if the clazz argument was
+			 * malformed
+			 */
+			IllegalArgumentException iae = new IllegalArgumentException(
+					"unexpected InvalidSyntaxException: " + e.getMessage());
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Create a <code>ServiceTracker</code> 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>.
+	 * 
+	 * @param context The <code>BundleContext</code> against which the tracking
+	 *        is done.
+	 * @param filter The <code>Filter</code> 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>. If
+	 *        customizer is null, then this <code>ServiceTracker</code> will be
+	 *        used as the <code>ServiceTrackerCustomizer</code> and this
+	 *        <code>ServiceTracker</code> will call the
+	 *        <code>ServiceTrackerCustomizer</code> methods on itself.
+	 * @since 1.1
+	 */
+	public ServiceTracker(final BundleContext context, final Filter filter,
+			final ServiceTrackerCustomizer customizer) {
+		this.context = context;
+		this.trackReference = null;
+		this.trackClass = null;
+		final Version frameworkVersion = (Version) AccessController
+				.doPrivileged(new PrivilegedAction<Version>() {
+					public Version run() {
+						String version = context
+								.getProperty(Constants.FRAMEWORK_VERSION);
+						return (version == null) ? Version.emptyVersion
+								: new Version(version);
+					}
+				});
+		final boolean endMatchSupported = (frameworkVersion
+				.compareTo(endMatchVersion) >= 0);
+		this.listenerFilter = endMatchSupported ? filter.toString() : 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> and begin tracking services.
+	 * 
+	 * <p>
+	 * This implementation calls <code>open(false)</code>.
+	 * 
+	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+	 *         with which this <code>ServiceTracker</code> was created is no
+	 *         longer valid.
+	 * @see #open(boolean)
+	 */
+	public void open() {
+		open(false);
+	}
+
+	/**
+	 * Open this <code>ServiceTracker</code> and begin tracking services.
+	 * 
+	 * <p>
+	 * Services which match the search criteria specified when this
+	 * <code>ServiceTracker</code> was created are now tracked by this
+	 * <code>ServiceTracker</code>.
+	 * 
+	 * @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 accessible to the bundle whose
+	 *        <code>BundleContext</code> is used by this
+	 *        <code>ServiceTracker</code>.
+	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+	 *         with which this <code>ServiceTracker</code> was created is no
+	 *         longer valid.
+	 * @since 1.3
+	 */
+    public void open(boolean trackAllServices) {
+        open(trackAllServices, false);
+    }
+	
+    /**
+     * Open this <code>ServiceTracker</code> and begin tracking services.
+     * 
+     * <p>
+     * Services which match the search criteria specified when this
+     * <code>ServiceTracker</code> was created are now tracked by this
+     * <code>ServiceTracker</code>.
+     * 
+     * @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 accessible to the bundle whose
+     *        <code>BundleContext</code> is used by this
+     *        <code>ServiceTracker</code>.
+     * @param trackAllAspects If <code>true</code> then this
+     *        <code>ServiceTracker</code> will track all aspects regardless
+     *        of their rank. If <code>false</code> only the highest ranked
+     *        aspects (or the original service if there are no aspects) will
+     *        be tracked. The latter is the default.
+     * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+     *         with which this <code>ServiceTracker</code> was created is no
+     *         longer valid.
+     */
+	public void open(boolean trackAllServices, boolean trackAllAspects) {
+		if (debug) {
+			System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " open");
+		}
+		final Tracked t;
+		synchronized (this) {
+			if (tracked != null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("ServiceTracker.open: " + filter); 
+			}
+			m_trackAllAspects = trackAllAspects;
+			t = trackAllServices ? new AllTracked() : new Tracked();
+			synchronized (t) {
+				try {
+					context.addServiceListener(t, listenerFilter);
+					ServiceReference[] references = null;
+					if (trackClass != null) {
+						references = getInitialReferences(trackAllServices,
+								trackClass, null);
+					}
+					else {
+						if (trackReference != null) {
+							if (trackReference.getBundle() != null) {
+								references = new ServiceReference[] {trackReference};
+							}
+						}
+						else { /* user supplied filter */
+							references = getInitialReferences(trackAllServices,
+									null,
+									(listenerFilter != null) ? listenerFilter
+											: filter.toString());
+						}
+					}
+					/* set tracked with the initial references */
+					t.setInitial(references);
+					
+					// only actually schedules the actions for execution within this synchronized block,
+					// but do the actual execution afterwards.
+					t.trackInitial(); 
+
+				}
+				catch (InvalidSyntaxException e) {
+					throw new RuntimeException(
+							"unexpected InvalidSyntaxException: "
+									+ e.getMessage(), e); 
+				}
+			}
+			tracked = t;
+		}
+		/* Call tracked outside of synchronized region */
+		// just trigger the executor
+		t.getExecutor().execute();
+	}
+
+	/**
+	 * Returns the list of initial <code>ServiceReference</code>s that will be
+	 * tracked by this <code>ServiceTracker</code>.
+	 * 
+	 * @param trackAllServices If <code>true</code>, use
+	 *        <code>getAllServiceReferences</code>.
+	 * @param className The class name with which the service was registered, or
+	 *        <code>null</code> for all services.
+	 * @param filterString The filter criteria or <code>null</code> for all
+	 *        services.
+	 * @return The list of initial <code>ServiceReference</code>s.
+	 * @throws InvalidSyntaxException If the specified filterString has an
+	 *         invalid syntax.
+	 */
+	private ServiceReference[] getInitialReferences(boolean trackAllServices,
+			String className, String filterString)
+			throws InvalidSyntaxException {
+		if (trackAllServices) {
+			return context.getAllServiceReferences(className, filterString);
+		}
+		return context.getServiceReferences(className, filterString);
+	}
+
+	/**
+	 * Close this <code>ServiceTracker</code>.
+	 * 
+	 * <p>
+	 * This method should be called when this <code>ServiceTracker</code> should
+	 * end the tracking of services.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of tracked services to remove.
+	 */
+	public void close() {
+		final Tracked outgoing;
+		final ServiceReference[] references;
+		synchronized (this) {
+			outgoing = tracked;
+			if (outgoing == null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("ServiceTracker.close: " + filter); 
+			}
+			outgoing.close();
+			references = getServiceReferences();
+			tracked = null;
+			try {
+				context.removeServiceListener(outgoing);
+			}
+			catch (IllegalStateException e) {
+				/* In case the context was stopped. */
+			}
+		}
+		modified(); /* clear the cache */
+		synchronized (outgoing) {
+			outgoing.notifyAll(); /* wake up any waiters */
+		}
+		if (references != null) {
+			for (int i = 0; i < references.length; i++) {
+				outgoing.untrack(references[i], null).execute();
+			}
+		}
+		if (DEBUG) {
+			if ((cachedReference == null) && (cachedService == null)) {
+				System.out
+						.println("ServiceTracker.close[cached cleared]: "
+						+ filter); 
+			}
+		}
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>ServiceTrackerCustomizer.addingService</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>ServiceTracker</code> has been
+	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation returns the result of calling <code>getService</code>
+	 * on the <code>BundleContext</code> with which this
+	 * <code>ServiceTracker</code> was created passing the specified
+	 * <code>ServiceReference</code>.
+	 * <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
+	 * {@link #removedService(ServiceReference, Object) removedService} to unget
+	 * the service.
+	 * 
+	 * @param reference The reference to the service being added to this
+	 *        <code>ServiceTracker</code>.
+	 * @return The service object to be tracked for the service added to this
+	 *         <code>ServiceTracker</code>.
+	 * @see ServiceTrackerCustomizer#addingService(ServiceReference)
+	 */
+	public Object addingService(ServiceReference reference) {
+		return context.getService(reference);
+	}
+	
+	public void addedService(ServiceReference reference, Object service) {
+		/* do nothing */
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>ServiceTrackerCustomizer.modifiedService</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>ServiceTracker</code> has been
+	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation does nothing.
+	 * 
+	 * @param reference The reference to modified service.
+	 * @param service The service object for the modified service.
+	 * @see ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
+	 */
+	public void modifiedService(ServiceReference reference, Object service) {
+		/* do nothing */
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>ServiceTrackerCustomizer.removedService</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>ServiceTracker</code> has been
+	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation calls <code>ungetService</code>, on the
+	 * <code>BundleContext</code> with which this <code>ServiceTracker</code>
+	 * was created, passing the specified <code>ServiceReference</code>.
+	 * <p>
+	 * This method can be overridden in a subclass. If the default
+	 * implementation of {@link #addingService(ServiceReference) addingService}
+	 * method was used, this method must unget the service.
+	 * 
+	 * @param reference The reference to removed service.
+	 * @param service The service object for the removed service.
+	 * @see ServiceTrackerCustomizer#removedService(ServiceReference, Object)
+	 */
+	public void removedService(ServiceReference reference, Object service) {
+		context.ungetService(reference);
+	}
+
+	/**
+	 * Wait for at least one service to be tracked by this
+	 * <code>ServiceTracker</code>. This method will also return when this
+	 * <code>ServiceTracker</code> is closed.
+	 * 
+	 * <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.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getService()} to determine if a service
+	 * is being tracked.
+	 * 
+	 * @param timeout The time interval in milliseconds to wait. If zero, the
+	 *        method will wait indefinitely.
+	 * @return Returns the result of {@link #getService()}.
+	 * @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"); 
+		}
+		Object object = getService(); 
+		while (object == null) {
+			final Tracked t = tracked();
+			if (t == null) { /* if ServiceTracker is not open */
+				return null;
+			}
+			synchronized (t) {
+				if (t.size() == 0) {
+					t.wait(timeout);
+				}
+			}
+			object = getService(); 
+			if (timeout > 0) {
+				return object;
+			}
+		}
+		return object;
+	}
+
+	/**
+	 * Return an array of <code>ServiceReference</code>s for all services being
+	 * tracked by this <code>ServiceTracker</code>.
+	 * 
+	 * @return Array of <code>ServiceReference</code>s or <code>null</code> if
+	 *         no services are being tracked.
+	 */
+	public ServiceReference[] getServiceReferences() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			int length = t.size();
+			if (length == 0) {
+				return null;
+			}
+			return (ServiceReference[]) t
+					.getTracked(new ServiceReference[length]);
+		}
+	}
+	
+	/**
+	 * Returns a boolean indicating whether this <code>ServiceTracker</code> is tracking any services.
+	 * 
+	 * @return true if services are being tracked, false if no services are being tracked.
+	 */
+	public boolean hasReference() {
+		if (cachedReference != null) {
+			return true;
+		}
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return false;
+		}
+		synchronized (t) {
+			int length = t.size();
+			return length > 0;
+		}
+	}
+
+	/**
+	 * Returns a <code>ServiceReference</code> for one of the services being
+	 * tracked by this <code>ServiceTracker</code>.
+	 * 
+	 * <p>
+	 * If multiple services are being tracked, the service with the highest
+	 * ranking (as specified in its <code>service.ranking</code> property) is
+	 * returned. 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. This is the same
+	 * algorithm used by <code>BundleContext.getServiceReference</code>.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of references for the tracked services.
+	 * 
+	 * @return A <code>ServiceReference</code> or <code>null</code> if no
+	 *         services are being tracked.
+	 * @since 1.1
+	 */
+	public ServiceReference getServiceReference() {
+		ServiceReference reference = cachedReference;
+		if (reference != null) {
+			if (DEBUG) {
+				System.out
+						.println("ServiceTracker.getServiceReference[cached]: "
+								+ filter); 
+			}
+			return reference;
+		}
+		if (DEBUG) {
+			System.out.println("ServiceTracker.getServiceReference: " + filter); 
+		}
+		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> if the specified referenced service is
+	 * being tracked by this <code>ServiceTracker</code>.
+	 * 
+	 * @param reference The reference to the desired service.
+	 * @return A service object or <code>null</code> if the service referenced
+	 *         by the specified <code>ServiceReference</code> is not being
+	 *         tracked.
+	 */
+	public Object getService(ServiceReference reference) {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			return t.getCustomizedObject(reference);
+		}
+	}
+
+	/**
+	 * Return an array of service objects for all services being tracked by this
+	 * <code>ServiceTracker</code>.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of references for the tracked services and then calls
+	 * {@link #getService(ServiceReference)} for each reference to get the
+	 * tracked service object.
+	 * 
+	 * @return An array of service objects or <code>null</code> if no services
+	 *         are being tracked.
+	 */
+	public Object[] getServices() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			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>.
+	 * 
+	 * <p>
+	 * If any services are being tracked, this implementation returns the result
+	 * of calling <code>getService(getServiceReference())</code>.
+	 * 
+	 * @return A service object or <code>null</code> if no services are being
+	 *         tracked.
+	 */
+	public Object getService() {
+		Object service = cachedService;
+		if (service != null) {
+			if (DEBUG) {
+				System.out
+						.println("ServiceTracker.getService[cached]: "
+						+ filter); 
+			}
+			return service;
+		}
+		if (DEBUG) {
+			System.out.println("ServiceTracker.getService: " + filter); 
+		}
+		ServiceReference reference = getServiceReference(); 
+		if (reference == null) {
+			return null;
+		}
+		return cachedService = getService(reference); 
+	}
+
+	/**
+	 * Remove a service from this <code>ServiceTracker</code>.
+	 * 
+	 * The specified service will be removed from this
+	 * <code>ServiceTracker</code>. If the specified service was being tracked
+	 * then the <code>ServiceTrackerCustomizer.removedService</code> method will
+	 * be called for that service.
+	 * 
+	 * @param reference The reference to the service to be removed.
+	 */
+	public void remove(ServiceReference reference) {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return;
+		}
+		t.untrack(reference, null).execute();
+	}
+
+	/**
+	 * Return the number of services being tracked by this
+	 * <code>ServiceTracker</code>.
+	 * 
+	 * @return The number of services being tracked.
+	 */
+	public int size() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return 0;
+		}
+		synchronized (t) {
+			return t.size();
+		}
+	}
+
+	/**
+	 * Returns the tracking count for this <code>ServiceTracker</code>.
+	 * 
+	 * The tracking count is initialized to 0 when this
+	 * <code>ServiceTracker</code> is opened. Every time a service is added,
+	 * modified or removed from this <code>ServiceTracker</code>, the tracking
+	 * count is incremented.
+	 * 
+	 * <p>
+	 * The tracking count can be used to determine if this
+	 * <code>ServiceTracker</code> 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>
+	 * since the previous tracking count was collected.
+	 * 
+	 * @since 1.2
+	 * @return The tracking count for this <code>ServiceTracker</code> or -1 if
+	 *         this <code>ServiceTracker</code> is not open.
+	 */
+	public int getTrackingCount() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return -1;
+		}
+		synchronized (t) {
+			return t.getTrackingCount();
+		}
+	}
+
+	/**
+	 * Called by the Tracked object whenever the set of tracked services is
+	 * modified. Clears the cache.
+	 */
+	/*
+	 * This method must not be synchronized since it is called by Tracked while
+	 * Tracked is synchronized. We don't want synchronization interactions
+	 * between the listener thread and the user thread.
+	 */
+	void modified() {
+		cachedReference = null; /* clear cached value */
+		cachedService = null; /* clear cached value */
+		if (DEBUG) {
+			System.out.println("ServiceTracker.modified: " + filter); 
+		}
+	}
+
+	/**
+	 * Inner class which subclasses AbstractTracked. This class is the
+	 * <code>ServiceListener</code> object for the tracker.
+	 * 
+	 * @ThreadSafe
+	 */
+	class Tracked extends AbstractTracked implements ServiceListener {
+	    /**
+	     * A list of services that are currently hidden because there is an aspect available with a higher ranking.
+	     * @GuardedBy this
+	     */
+	    private final Map<Long, TreeSet<ServiceReference>> m_highestTrackedCache = new HashMap<>();
+	    private final Map<Long, TreeSet<ServiceReference>> m_highestHiddenCache = new HashMap<>();
+        
+        private ServiceReference highestTrackedCache(long serviceId) {
+            Long sid = Long.valueOf(serviceId);
+            synchronized (this) {
+            	TreeSet<ServiceReference> services = m_highestTrackedCache.get(sid);
+            	if (services != null && services.size() > 0) {
+            		ServiceReference result = (ServiceReference) services.last();
+            		return result;
+            	}
+			}
+            return null;
+        }
+        
+        private void addHighestTrackedCache(ServiceReference reference) {
+            Long serviceId = ServiceUtil.getServiceIdObject(reference);
+            synchronized (this) {
+            	TreeSet<ServiceReference> services = m_highestTrackedCache.get(serviceId);
+            	if (services == null) {
+            		services = new TreeSet<ServiceReference>();
+            		m_highestTrackedCache.put(serviceId, services);
+            	}
+            	services.add(reference);
+			}
+        }
+        
+        private void removeHighestTrackedCache(ServiceReference reference) {
+            Long serviceId = ServiceUtil.getServiceIdObject(reference);
+            synchronized (this) {
+            	TreeSet<ServiceReference> services = m_highestTrackedCache.get(serviceId);
+            	if (services != null) {
+            		services.remove(reference);
+            	}
+			}
+        }
+        
+        private void clearHighestTrackedCache() {
+        	synchronized (this) {
+        		m_highestTrackedCache.clear();
+			}
+        }
+        
+        private ServiceReference highestHiddenCache(long serviceId) {
+            Long sid = Long.valueOf(serviceId);
+            synchronized (this) {
+            	TreeSet<ServiceReference> services = m_highestHiddenCache.get(sid);
+	            if (services != null && services.size() > 0) {
+	                ServiceReference result = (ServiceReference) services.last();
+	                return result;
+	            }
+            }
+            return null;
+        }
+        
+        private void addHighestHiddenCache(ServiceReference reference) {
+            Long serviceId = ServiceUtil.getServiceIdObject(reference);
+            synchronized (this) {
+            	TreeSet<ServiceReference> services = m_highestHiddenCache.get(serviceId);
+            	if (services == null) {
+            		services = new TreeSet<ServiceReference>();
+            		m_highestHiddenCache.put(serviceId, services);
+            	}
+            	services.add(reference);
+			}
+        }
+        
+        private void removeHighestHiddenCache(ServiceReference reference) {
+            Long serviceId = ServiceUtil.getServiceIdObject(reference);
+            synchronized (this) {
+            	TreeSet<ServiceReference> services = m_highestHiddenCache.get(serviceId);
+            	if (services != null) {
+            		services.remove(reference);
+            	}
+			}
+        }
+
+        /**
+         * Hide a service reference, placing it in the list of hidden services.
+         * 
+         * @param ref the service reference to add to the hidden list
+         */
+        private void hide(ServiceReference ref) {
+            addHighestHiddenCache(ref);
+        }
+        
+        /**
+         * Unhide a service reference, removing it from the list of hidden services.
+         * 
+         * @param ref the service reference to remove from the hidden list
+         */
+        private void unhide(ServiceReference ref) {
+            removeHighestHiddenCache(ref);
+        }
+	    
+		/**
+		 * Tracked constructor.
+		 */
+		Tracked() {
+			super();
+			setTracked(new HashMapCache<Object, Object>());
+		}
+		
+		void setInitial(Object[] list) {
+		    if (list == null) {
+		        return;
+		    }
+		    if (m_trackAllAspects) {
+		    	// not hiding aspects
+		    	super.setInitial(list);
+		    } else { 
+			    Map<Long, RankedService> highestRankedServiceMap = new HashMap<>();
+			    for (int i = 0; i < list.length; i++) {
+			    	ServiceReference sr = (ServiceReference) list[i];
+			    	if (sr != null) {
+				    	Long serviceId = ServiceUtil.getServiceIdAsLong(sr);
+				    	int ranking = ServiceUtil.getRanking(sr);
+				    	
+				    	RankedService rs = (RankedService) highestRankedServiceMap.get(serviceId);
+				    	if (rs == null) {
+				    	    // the service did not exist yet in our map
+				    	    highestRankedServiceMap.put(serviceId, new RankedService(ranking, sr));
+				    	}
+				    	else if (ranking > rs.getRanking()) {
+	                        // the service replaces a lower ranked one
+				    	    hide(rs.getServiceReference());
+				    	    rs.update(ranking, sr);
+				    	}
+				    	else {
+	                        // the service does NOT replace a lower ranked one
+				    	    hide(sr);
+				    	}
+			    	}
+			    }
+			    if (highestRankedServiceMap.size() > 0) {
+			        Object[] result = new Object[highestRankedServiceMap.size()];
+			        int index = 0;
+			        for(Iterator<Entry<Long, RankedService>> it = highestRankedServiceMap.entrySet().iterator(); it.hasNext(); ) {
+			        	Entry<Long, RankedService> entry = it.next();
+			        	result[index] = ((RankedService)entry.getValue()).getServiceReference();
+			        	index++;
+			        }
+			        super.setInitial(result);	    	
+			    }
+		    }
+		}
+
+		/**
+		 * <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(final ServiceEvent event) {
+			if (m_trackAllAspects) {
+				serviceChangedIncludeAspects(event);
+			}
+			else {
+				serviceChangedHideAspects(event);
+			}
+		}
+		
+        public void serviceChangedIncludeAspects(final ServiceEvent event) {
+            /*
+             * Check if we had a delayed call (which could happen when we
+             * close).
+             */
+            if (closed) {
+                return;
+            }
+            final ServiceReference reference = event.getServiceReference();
+			if (debug) {
+				System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " [serviceChangedIncludeAspects] " + reference.getProperty("service.ranking"));
+			}            
+            if (DEBUG) {
+                System.out
+                        .println("ServiceTracker.Tracked.serviceChanged["
+                        + event.getType() + "]: " + reference);  
+            }
+
+            switch (event.getType()) {
+                case ServiceEvent.REGISTERED :
+                case ServiceEvent.MODIFIED :
+                    if (listenerFilter != null) { // service listener added with
+                        // filter
+                        track(reference, event).execute();
+                        /*
+                         * If the customizer throws an unchecked exception, it
+                         * is safe to let it propagate
+                         */
+                    }
+                    else { // service listener added without filter
+                        if (filter.match(reference)) {
+                            track(reference, event).execute();
+                            /*
+                             * If the customizer throws an unchecked exception,
+                             * it is safe to let it propagate
+                             */
+                        }
+                        else {
+                            untrack(reference, event).execute();
+                            /*
+                             * If the customizer throws an unchecked exception,
+                             * it is safe to let it propagate
+                             */
+                        }
+                    }
+                    break;
+                case 8 /* ServiceEvent.MODIFIED_ENDMATCH */ :
+                case ServiceEvent.UNREGISTERING :
+                    untrack(reference, event).execute();
+                    /*
+                     * If the customizer throws an unchecked exception, it is
+                     * safe to let it propagate
+                     */
+                    break;
+            }
+        }
+        
+        private boolean isModifiedEndmatchSupported() {
+        	return listenerFilter != null;
+        }
+        
+        private AtomicInteger step = new AtomicInteger();
+		
+		public void serviceChangedHideAspects(final ServiceEvent event) {
+			int n = step.getAndIncrement();
+			/*
+			 * Check if we had a delayed call (which could happen when we
+			 * close).
+			 */
+			if (closed) {
+				return;
+			}
+			final ServiceReference reference = event.getServiceReference();
+			if (DEBUG) {
+				System.out
+						.println(n + " ServiceTracker.Tracked.serviceChanged["
+						+ event.getType() + "]: " + reference);  
+			}
+
+			long sid = ServiceUtil.getServiceId(reference);
+			AbstractCustomizerActionSet actionSet = null;
+			synchronized(this) {
+				switch (event.getType()) {
+					case ServiceEvent.REGISTERED :
+					case ServiceEvent.MODIFIED :
+					    ServiceReference higherRankedReference = null;
+					    ServiceReference lowerRankedReference = null;
+					    ServiceReference highestTrackedReference = highestTrackedCache(sid);
+					    if (highestTrackedReference != null) {
+					        int ranking = ServiceUtil.getRanking(reference);
+					        int highestTrackedRanking = ServiceUtil.getRanking(highestTrackedReference);
+					        if (ranking > highestTrackedRanking) {
+					            // found a higher ranked one!
+					            if (DEBUG) {
+					                System.out.println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: Found a higher ranked aspect: " + ServiceUtil.toString(reference) + " vs " + ServiceUtil.toString(highestTrackedReference));
+					            }
+					            higherRankedReference = highestTrackedReference;
+					        }
+					        else if (ranking < highestTrackedRanking) {
+					            // found lower ranked one!
+	                            if (DEBUG) {
+	                                System.out.println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: Found a lower ranked aspect: " + ServiceUtil.toString(reference) + " vs " + ServiceUtil.toString(highestTrackedReference));
+	                            }
+					            lowerRankedReference = highestTrackedReference;
+					        }
+					    }
+						if (isModifiedEndmatchSupported()) { // either registered or modified
+							actionSet = registerOrUpdate(event, reference, higherRankedReference, lowerRankedReference);
+						}
+						else { // service listener added without filter
+							if (filter.match(reference)) {
+		                        actionSet = registerOrUpdate(event, reference, higherRankedReference, lowerRankedReference);
+							}
+							else {
+			                    actionSet = unregister(event, reference, sid);
+							}
+						}
+						break;
+	                case 8 /* ServiceEvent.MODIFIED_ENDMATCH */ : // handle as unregister
+					case ServiceEvent.UNREGISTERING :
+						actionSet = unregister(event, reference, sid);
+						/*
+						 * If the customizer throws an unchecked exception, it is
+						 * safe to let it propagate
+						 */
+						break;
+				}
+				// schedule the actionset for execution. We'll use a serial executor to prevent the actions to
+				// be performed out of order.
+				final AbstractCustomizerActionSet commandActionSet = actionSet;
+				if (commandActionSet != null) {
+                    getExecutor().schedule(new Runnable() {
+
+                        @Override
+                        public void run() {
+                            commandActionSet.execute();
+                        }
+
+                    });
+				}
+			}
+			getExecutor().execute();
+		}
+		
+		private AbstractCustomizerActionSet registerOrUpdate(final ServiceEvent event,
+				final ServiceReference reference, ServiceReference higher,
+				ServiceReference lower) {
+			if (debug) {
+//				System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " [registerOrUpdate] lower: " + lower + ", higher: " + higher);
+			}
+			AbstractCustomizerActionSet actionSet = null;
+			if (lower != null) {
+			    hide(reference);
+			}
+			else {
+				actionSet = track(reference, event);
+		        if (higher != null) {
+	                actionSet.appendActionSet(untrack(higher, null));
+	                hide(higher);
+			    }
+			}
+			/*
+			 * If the customizer throws an unchecked exception, it
+			 * is safe to let it propagate
+			 */
+			return actionSet;
+		}
+
+		private AbstractCustomizerActionSet unregister(final ServiceEvent event,
+				final ServiceReference reference, long sid) {
+			if (debug) {
+				System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " [unregister] " + reference.getProperty("service.ranking"));
+			}
+			AbstractCustomizerActionSet actionSet = null;
+			ServiceReference ht = highestTrackedCache(sid);
+			if (reference.equals(ht)) {
+		        ServiceReference hh = highestHiddenCache(sid);
+		        
+		        if (hh != null) {
+		            unhide(hh);
+		            actionSet = track(hh, null);
+		        }
+		        if (actionSet == null) {
+		        	actionSet = untrack(reference, event);
+		        } else {
+		        	actionSet.appendActionSet(untrack(reference, event));
+		        }
+			}
+			else {
+			    unhide(reference);
+			}
+			return actionSet;
+		}
+		
+		
+
+		/**
+		 * Increment the tracking count and tell the tracker there was a
+		 * modification.
+		 * 
+		 * @GuardedBy this
+		 */
+		void modified() {
+			super.modified(); /* increment the modification count */
+			ServiceTracker.this.modified();
+		}
+
+		/**
+		 * Call the specific customizer adding method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Item to be tracked.
+		 * @param related Action related object.
+		 * @return Customized object for the tracked item or <code>null</code>
+		 *         if the item is not to be tracked.
+		 */
+		Object customizerAdding(final Object item,
+				final Object related) {
+			return customizer.addingService((ServiceReference) item);
+		}
+		
+		void customizerAdded(final Object item, final Object related, final Object object) {
+			customizer.addedService((ServiceReference) item, object);
+		}
+
+		/**
+		 * Call the specific customizer modified method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
+		 */
+		void customizerModified(final Object item,
+				final Object related, final Object object) {
+			customizer.modifiedService((ServiceReference) item, object);
+		}
+
+		/**
+		 * Call the specific customizer removed method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
+		 */
+		void customizerRemoved(final Object item,
+				final Object related, final Object object) {
+			customizer.removedService((ServiceReference) item, object);
+		}
+		
+		class HashMapCache<K, V> extends LinkedHashMap<K, V> {
+
+			private static final long serialVersionUID = 1627005136730183946L;
+
+			public V put(K key, V value) {
+		        addHighestTrackedCache((ServiceReference) key);
+		        return super.put(key, value);
+		    }
+
+		    public void putAll(Map<? extends K, ? extends V> m) {
+		        Iterator<? extends K> i = m.keySet().iterator();
+		        while (i.hasNext()) {
+		            addHighestTrackedCache((ServiceReference) i.next());
+		        }
+		        super.putAll(m);
+		    }
+
+		    public V remove(Object key) {
+		        removeHighestTrackedCache((ServiceReference) key);
+		        return super.remove(key);
+		    }
+
+		    public void clear() {
+		        clearHighestTrackedCache();
+		        super.clear();
+		    }
+		}
+
+		@Override
+		AbstractCustomizerActionSet createCustomizerActionSet() {
+			// This actions set deliberately postpones invocation of the customizer methods to be able to combine added and removed
+			// into a single swap call.
+			return new AbstractCustomizerActionSet() {
+				
+				@Override
+				public void addCustomizerAdded(Object item, Object related,
+						Object object) {
+					if (debug) {
+//						System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " addCustomizerAdded " + object);
+					}
+					super.addCustomizerAdded(item, related, object);
+				}
+				
+				@Override
+				public void addCustomizerModified(Object item, Object related,
+						Object object) {
+					if (debug) {
+//						System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " addCustomizerModified " + object);
+					}					
+					super.addCustomizerModified(item, related, object);
+				}
+				
+				@Override
+				public void addCustomizerRemoved(Object item, Object related,
+						Object object) {
+					if (debug) {
+//						System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " addCustomizerRemoved " + object);
+					}					
+					super.addCustomizerRemoved(item, related, object);
+				}
+				
+				@Override
+				void execute() {
+					// inspect the actions and check whether we should perform a swap
+					List<CustomizerAction> actions = getActions();
+					if (actions.size() > 2) {
+						throw new IllegalStateException("Unexpected action count: " + actions.size());
+					}
+					if (actions.size() == 2 && actions.get(0).getType() == Type.ADDED && actions.get(1).getType() == Type.REMOVED) {
+						// ignore related
+						// item = ServiceReference
+						// object = service
+						debug("swapped");
+						if (debug) {
+							System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " swapping " + actions.get(1).getObject() + " with " + actions.get(0).getObject());
+						}
+						customizer.swappedService((ServiceReference)actions.get(1).getItem(), actions.get(1).getObject(), (ServiceReference)actions.get(0).getItem(), actions.get(0).getObject());
+					} else {
+						// just sequentially call the customizer methods
+						for (CustomizerAction action : getActions()) {
+							try {
+								switch (action.getType()) {
+									case ADDED: 
+										debug(Thread.currentThread().getId() + " added");
+										if (debug) {
+											System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " adding " + action.getObject());
+										}
+										customizerAdded(action.getItem(), action.getRelated(), action.getObject());
+										break;
+									case MODIFIED:
+										debug("modified");
+										customizerModified(action.getItem(), action.getRelated(), action.getObject());
+										break;
+									case REMOVED:
+										debug("removed");
+										if (debug) {
+											System.out.println("[ServiceTracker] " + debugKey + " T" + Thread.currentThread().getId() + " removing " + action.getObject());
+										}
+										customizerRemoved(action.getItem(), action.getRelated(), action.getObject());
+								}
+							} catch (Exception e) {
+								// just continue. log messages will be printed elsewhere.
+							}
+						}
+					}
+				}
+			};
+		}
+
+	}
+	
+	private void debug(String message) {
+		if (customizer.toString().equals("ServiceDependency[interface dm.it.AspectRaceTest$S (&(!(org.apache.felix.dependencymanager.aspect=*))(id=1))]")) {
+//			System.out.println(message);
+		}
+	}
+
+	/**
+	 * 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 {
+		/**
+		 * AllTracked constructor.
+		 */
+		AllTracked() {
+			super();
+            setTracked(new HashMapCache<Object, Object>());
+		}
+	}
+	
+	/**
+	 * Holds a ranking and a service reference that can be updated if necessary.
+	 */
+	private static final class RankedService {
+		private int m_ranking;
+		private ServiceReference m_serviceReference;
+		
+		public RankedService(int ranking, ServiceReference serviceReference) {
+			m_ranking = ranking;
+			m_serviceReference = serviceReference;
+		}
+		
+        public void update(int ranking, ServiceReference serviceReference) {
+            m_ranking = ranking;
+            m_serviceReference = serviceReference;
+        }
+		
+		public int getRanking() {
+			return m_ranking;
+		}
+		
+		public ServiceReference getServiceReference() {
+			return m_serviceReference;
+		}
+	}
+
+	@Override
+	public void swappedService(ServiceReference reference, Object service,
+			ServiceReference newReference, Object newService) {
+		
+	}
+
+	// Package private, used for unit testing Tracked
+	Tracked getTracked() {
+		return tracked;
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTrackerCustomizer.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTrackerCustomizer.java
new file mode 100644
index 0000000..ab3abd2
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTrackerCustomizer.java
@@ -0,0 +1,115 @@
+package org.apache.felix.dm.tracker;
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ * 
+ * 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.
+ */
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>ServiceTrackerCustomizer</code> interface allows a
+ * <code>ServiceTracker</code> to customize the service objects that are
+ * tracked. A <code>ServiceTrackerCustomizer</code> is called when a service is
+ * being added to a <code>ServiceTracker</code>. The
+ * <code>ServiceTrackerCustomizer</code> can then return an object for the
+ * tracked service. A <code>ServiceTrackerCustomizer</code> is also called when
+ * a tracked service is modified or has been removed from a
+ * <code>ServiceTracker</code>.
+ * 
+ * <p>
+ * The methods in this interface may be called as the result of a
+ * <code>ServiceEvent</code> being received by a <code>ServiceTracker</code>.
+ * Since <code>ServiceEvent</code>s are synchronously delivered by the
+ * Framework, it is highly recommended that implementations of these methods do
+ * not register (<code>BundleContext.registerService</code>), modify (
+ * <code>ServiceRegistration.setProperties</code>) or unregister (
+ * <code>ServiceRegistration.unregister</code>) a service while being
+ * synchronized on any object.
+ * 
+ * <p>
+ * The <code>ServiceTracker</code> class is thread-safe. It does not call a
+ * <code>ServiceTrackerCustomizer</code> while holding any locks.
+ * <code>ServiceTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 5874 $
+ */
+public interface ServiceTrackerCustomizer {
+	/**
+	 * A service is being added to the <code>ServiceTracker</code>.
+	 * 
+	 * <p>
+	 * This method is called before a service which matched the search
+	 * parameters of the <code>ServiceTracker</code> is added to the
+	 * <code>ServiceTracker</code>. This method should return the service object
+	 * to be tracked for the specified <code>ServiceReference</code>. The
+	 * returned service object is stored in the <code>ServiceTracker</code> and
+	 * is available from the <code>getService</code> and
+	 * <code>getServices</code> methods.
+	 * 
+	 * @param reference The reference to the service being added to the
+	 *        <code>ServiceTracker</code>.
+	 * @return The service object to be tracked for the specified referenced
+	 *         service or <code>null</code> if the specified referenced service
+	 *         should not be tracked.
+	 */
+	public Object addingService(ServiceReference reference);
+
+	/** marrs: A service has been added to the ServiceTracker. */
+	public void addedService(ServiceReference reference, Object service);
+
+	/**
+	 * A service tracked by the <code>ServiceTracker</code> has been modified.
+	 * 
+	 * <p>
+	 * This method is called when a service being tracked by the
+	 * <code>ServiceTracker</code> has had it properties modified.
+	 * 
+	 * @param reference The reference to the service that has been modified.
+	 * @param service The service object for the specified referenced service.
+	 */
+	public void modifiedService(ServiceReference reference, Object service);
+	
+	/**
+	 * A service tracked by the <code>ServiceTracker</code> has an aspect service 
+	 * added or removed for a tracked service.
+	 * 
+	 * <p>
+	 * This method is called when an aspect service has been either added or removed 
+	 * for a tracked service. This method will only be called when there's a new 
+	 * highest ranked service as result of adding or removal of the aspect service.
+	 * In this case the previously highest ranked service is 'swapped' for the new
+	 * highest ranked service ensuring the client always gets the highest ranked
+	 * aspect. 
+	 * 
+	 * @param reference The reference for the old highest ranked service.
+	 * @param service The service object for the old highest ranked service.
+	 * @param newReference The reference to the new highest ranked service.
+	 * @param newService The service object for the new highest ranked service.
+	 */
+	public void swappedService(ServiceReference reference, Object service, ServiceReference newReference, Object newService);
+
+	/**
+	 * A service tracked by the <code>ServiceTracker</code> has been removed.
+	 * 
+	 * <p>
+	 * This method is called after a service is no longer being tracked by the
+	 * <code>ServiceTracker</code>.
+	 * 
+	 * @param reference The reference to the service that has been removed.
+	 * @param service The service object for the specified referenced service.
+	 */
+	public void removedService(ServiceReference reference, Object service);
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/packageinfo b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/packageinfo
new file mode 100644
index 0000000..bd33369
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/packageinfo
@@ -0,0 +1 @@
+version 4.0.0
\ No newline at end of file
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/.gitignore b/dependencymanager/org.apache.felix.dependencymanager/test/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/.gitignore
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/org/apache/felix/dm/tracker/TrackedTest.java b/dependencymanager/org.apache.felix.dependencymanager/test/org/apache/felix/dm/tracker/TrackedTest.java
new file mode 100644
index 0000000..9b71939
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/org/apache/felix/dm/tracker/TrackedTest.java
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.tracker;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.tracker.ServiceTracker;
+import org.apache.felix.dm.tracker.ServiceTrackerCustomizer;
+import org.apache.felix.dm.tracker.ServiceTracker.Tracked;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TrackedTest {
+
+	@Test
+	public void testSetInitialHideAspects() {
+		System.out.println("testSetInitialHideAspects");
+		TestCustomizer customizer = new TestCustomizer();
+		
+		ServiceTracker tracker = new TestTracker(customizer);
+		tracker.open();
+		Tracked tracked = tracker.getTracked();
+
+		Object[] initialReferences = new Object[] {
+				createServiceReference(1L),
+				createServiceReference(2L, 1L, 10),
+				createServiceReference(3L),
+				createServiceReference(4L, 1L, 5),
+				createServiceReference(5L, 3L, 5),
+		};
+		tracked.setInitial(initialReferences);
+		tracked.trackInitial();
+		tracked.getExecutor().execute();
+		assertArrayEquals(new Long[] { 2L, 5L }, customizer.getServiceReferenceIds());
+	}
+	
+	@Test
+	public void testUnHideAspect() {
+		System.out.println("testUnhideAspect");
+		TestCustomizer customizer = new TestCustomizer();
+		
+		ServiceTracker tracker = new TestTracker(customizer);
+		tracker.open();
+		Tracked tracked = tracker.getTracked();
+		
+		ServiceReference[] initialReferences = new ServiceReference[] {
+				createServiceReference(1L),
+				createServiceReference(2L, 1L, 10),
+				createServiceReference(3L),
+				createServiceReference(4L, 1L, 5),
+				createServiceReference(5L, 3L, 5),
+		};
+		tracked.setInitial(initialReferences);
+		tracked.trackInitial();
+		tracked.getExecutor().execute();
+		assertArrayEquals(new Long[] { 2L, 5L }, customizer.getServiceReferenceIds());
+		
+		// create a service event that unregisters service with id 2, we would expect it to be swapped with 4.
+		ServiceEvent event = new ServiceEvent(ServiceEvent.UNREGISTERING, initialReferences[1]);
+		tracked.serviceChanged(event);
+		assertArrayEquals(new Long[] { 5L, 4L }, customizer.getServiceReferenceIds());
+		// create a service event that unregisters service with id 4, we would expect it to be swapped with 1.
+		event = new ServiceEvent(ServiceEvent.UNREGISTERING, initialReferences[3]);
+		tracked.serviceChanged(event);
+		assertArrayEquals(new Long[] { 5L, 1L }, customizer.getServiceReferenceIds());
+	}	
+	
+	@Test
+	public void testHideAspect() {
+		System.out.println("testHideAspect");
+		TestCustomizer customizer = new TestCustomizer();
+		
+		ServiceTracker tracker = new TestTracker(customizer);
+		tracker.open();
+		Tracked tracked = tracker.getTracked();
+		
+		ServiceReference[] initialReferences = new ServiceReference[] {
+				createServiceReference(1L),
+				createServiceReference(2L, 1L, 10),
+				createServiceReference(3L),
+				createServiceReference(4L, 1L, 5),
+				createServiceReference(5L, 3L, 5),
+		};
+		tracked.setInitial(initialReferences);
+		tracked.trackInitial();
+		tracked.getExecutor().execute();
+		assertArrayEquals(new Long[] { 2L, 5L }, customizer.getServiceReferenceIds());
+		
+		// create a service event that registers another but lower ranked aspect for service with id 1. 
+		ServiceReference newReference = createServiceReference(6L, 1L, 8);
+		ServiceEvent event = new ServiceEvent(ServiceEvent.REGISTERED, newReference);
+		tracked.serviceChanged(event);
+		assertArrayEquals(new Long[] { 2L, 5L }, customizer.getServiceReferenceIds());
+		
+		// create a service event that unregisters service with id 2, we would expect it to be swapped with 6.
+		event = new ServiceEvent(ServiceEvent.UNREGISTERING, initialReferences[1]);
+		tracked.serviceChanged(event);
+		assertArrayEquals(new Long[] { 5L, 6L }, customizer.getServiceReferenceIds());
+		
+		// create a service event that unregisters service with id 6, we would expect it to be swapped with 4.
+		event = new ServiceEvent(ServiceEvent.UNREGISTERING, newReference);
+		tracked.serviceChanged(event);
+		assertArrayEquals(new Long[] { 5L, 4L }, customizer.getServiceReferenceIds());	
+		
+		// create a service event that registers a higher ranked aspect for service with id 1.
+		ServiceReference higherRankedReference = createServiceReference(7L, 1L, 15);
+		ServiceEvent addHigherRankedEvent = new ServiceEvent(ServiceEvent.REGISTERED, higherRankedReference);
+		tracked.serviceChanged(addHigherRankedEvent);
+		assertArrayEquals(new Long[] { 5L, 7L }, customizer.getServiceReferenceIds());	
+	}		
+	
+	@Test
+	public void testSetInitialTrackAspects() {
+		System.out.println("testSetInitialTrackAspects");
+		TestCustomizer customizer = new TestCustomizer();
+		
+		ServiceTracker tracker = new TestTracker(customizer);
+		tracker.open(false, true);
+		Tracked tracked = tracker.getTracked();
+		
+		Object[] initialReferences = new Object[] {
+				createServiceReference(1L),
+				createServiceReference(2L, 1L, 10),
+				createServiceReference(3L, 1L, 5)
+		};
+		tracked.setInitial(initialReferences);
+		tracked.trackInitial();
+		tracked.getExecutor().execute();
+		assertArrayEquals(new Long[] { 1L, 2L, 3L }, customizer.getServiceReferenceIds());
+	}	
+	
+	private static BundleContext createBundleContext() {
+		BundleContext context = mock(BundleContext.class);
+		when(context.getProperty(Constants.FRAMEWORK_VERSION)).thenReturn(null);
+		return context;
+	}
+	
+	private ServiceReference createServiceReference(Long serviceId) {
+		return createServiceReference(serviceId, null, null);
+	}
+
+	private ServiceReference createServiceReference(Long serviceId, Long aspectId, Integer ranking) {
+		return new TestServiceReference(serviceId, aspectId, ranking);
+	}
+
+	class TestTracker extends ServiceTracker {
+
+		public TestTracker(ServiceTrackerCustomizer customizer) {
+			super(createBundleContext(), "(objectClass=*)", customizer);
+		}
+		
+	}
+	
+	class TestCustomizer implements ServiceTrackerCustomizer {
+		
+		List<ServiceReference> serviceReferences = new ArrayList<>();
+
+		@Override
+		public Object addingService(ServiceReference reference) {
+			System.out.println("adding service: " + reference);
+			return new Object();
+		}
+
+		@Override
+		public void addedService(ServiceReference reference, Object service) {
+			System.out.println("added service: " + reference);
+			serviceReferences.add(reference);
+		}
+
+		@Override
+		public void modifiedService(ServiceReference reference, Object service) {
+			System.out.println("modified service: " + reference);
+		}
+
+		@Override
+		public void swappedService(ServiceReference reference, Object service,
+				ServiceReference newReference, Object newService) {
+			System.out.println("swapped service: " + reference);
+			serviceReferences.remove(reference);
+			serviceReferences.add(newReference);
+		}
+
+		@Override
+		public void removedService(ServiceReference reference, Object service) {
+			System.out.println("removed service: " + reference);
+			serviceReferences.remove(reference);
+		}
+		
+		public Long[] getServiceReferenceIds() {
+			Long[] ids = new Long[serviceReferences.size()];
+			for (int i = 0; i < serviceReferences.size(); i++) {
+				ids[i] = (Long) serviceReferences.get(i).getProperty(Constants.SERVICE_ID);
+			}
+			return ids;
+		}
+		
+	}
+	
+	class TestServiceReference implements ServiceReference {
+		
+		Properties props = new Properties();
+
+		public TestServiceReference(Long serviceId, Long aspectId,
+				Integer ranking) {
+			props.put(Constants.SERVICE_ID, serviceId);
+			if (aspectId != null) {
+				props.put(DependencyManager.ASPECT, aspectId);
+			}
+			if (ranking != null) {
+				props.put(Constants.SERVICE_RANKING, ranking);
+			}
+		}
+
+		@Override
+		public Object getProperty(String key) {
+			return props.get(key);
+		}
+
+		@Override
+		public String[] getPropertyKeys() {
+			return props.keySet().toArray(new String[]{});
+		}
+
+		@Override
+		public Bundle getBundle() {
+			return null;
+		}
+
+		@Override
+		public Bundle[] getUsingBundles() {
+			return null;
+		}
+
+		@Override
+		public boolean isAssignableTo(Bundle bundle, String className) {
+			return false;
+		}
+
+		@Override
+		public int compareTo(Object reference) // Kindly borrowed from the Apache Felix ServiceRegistrationImpl.ServiceReferenceImpl
+        {
+            ServiceReference other = (ServiceReference) reference;
+
+            Long id = (Long) getProperty(Constants.SERVICE_ID);
+            Long otherId = (Long) other.getProperty(Constants.SERVICE_ID);
+
+            if (id.equals(otherId))
+            {
+                return 0; // same service
+            }
+
+            Object rankObj = getProperty(Constants.SERVICE_RANKING);
+            Object otherRankObj = other.getProperty(Constants.SERVICE_RANKING);
+
+            // If no rank, then spec says it defaults to zero.
+            rankObj = (rankObj == null) ? new Integer(0) : rankObj;
+            otherRankObj = (otherRankObj == null) ? new Integer(0) : otherRankObj;
+
+            // If rank is not Integer, then spec says it defaults to zero.
+            Integer rank = (rankObj instanceof Integer)
+                ? (Integer) rankObj : new Integer(0);
+            Integer otherRank = (otherRankObj instanceof Integer)
+                ? (Integer) otherRankObj : new Integer(0);
+
+            // Sort by rank in ascending order.
+            if (rank.compareTo(otherRank) < 0)
+            {
+                return -1; // lower rank
+            }
+            else if (rank.compareTo(otherRank) > 0)
+            {
+                return 1; // higher rank
+            }
+
+            // If ranks are equal, then sort by service id in descending order.
+            return (id.compareTo(otherId) < 0) ? 1 : -1;
+        }
+
+		@Override
+		public String toString() {
+			return "TestServiceReference [props=" + props + "]";
+		}
+
+	}
+	
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/ComponentTest.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/ComponentTest.java
new file mode 100644
index 0000000..9a79f70
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/ComponentTest.java
@@ -0,0 +1,699 @@
+/*
+ * 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 test;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentState;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.context.AbstractDependency;
+import org.apache.felix.dm.impl.ComponentImpl;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings("unused")
+public class ComponentTest {
+	static class MyComponent {
+		public MyComponent() {
+		}
+	}
+	
+	@Test
+	public void createStartAndStopComponent() {
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(MyComponent.class);
+		Assert.assertEquals("should not be available until started", false, c.isAvailable());
+		c.start();
+		Assert.assertEquals("should be available", true, c.isAvailable());
+		c.stop();
+		Assert.assertEquals("should no longer be available when stopped", false, c.isAvailable());
+	}
+	
+	@Test
+	public void testInitCallbackOfComponent() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			void init() {
+				e.step(2);
+			}
+            void start() {
+				e.step(3);
+			}
+			void stop() {
+				e.step(5);
+			}
+			void destroy() {
+				e.step(6);
+			}
+		});
+		e.step(1);
+		c.start();
+		e.step(4);
+		c.stop();
+		e.step(7);
+	}
+
+	@Test
+	public void testAddDependencyFromInitCallback() {
+		final Ensure e = new Ensure();
+		final SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setRequired(true);
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			void init(Component c) {
+				e.step(2);
+				c.add(d);
+			}
+			void start() {
+				e.step(4);
+			}
+			void stop() {
+				e.step(6);
+			}
+			void destroy() {
+				e.step(7);
+			}
+		});
+		e.step(1);
+		c.start();
+		e.step(3);
+		d.add(new EventImpl()); // NPE?!
+		e.step(5);
+		d.remove(new EventImpl());
+		c.stop();
+		e.step(8);
+	}
+	
+    @Test
+    public void testAddAvailableDependencyFromInitCallback() {
+        final Ensure e = new Ensure();
+        final SimpleServiceDependency d = new SimpleServiceDependency();
+        d.setRequired(true);
+        final SimpleServiceDependency d2 = new SimpleServiceDependency();
+        d2.setRequired(true);
+        ComponentImpl c = new ComponentImpl();
+        c.setImplementation(new Object() {
+            void init(Component c) {
+                System.out.println("init");
+                e.step(2);
+                c.add(d);
+                d.add(new EventImpl());
+                c.add(d2);
+            }
+            void start() {
+                System.out.println("start");
+                e.step();
+            }
+            void stop() {
+                System.out.println("stop");
+                e.step();
+            }
+            void destroy() {
+                System.out.println("destroy");
+                e.step(9);
+            }
+        });
+        e.step(1);
+        c.start();
+        e.step(5);
+        d2.add(new EventImpl());
+        e.step(7);
+        d.remove(new EventImpl());
+        c.stop();
+        e.step(10);
+    }
+    
+	@Test
+	public void testAtomicallyAddMultipleDependenciesFromInitCallback() {
+		final Ensure e = new Ensure();
+		final SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setRequired(true);
+
+		final SimpleServiceDependency d2 = new SimpleServiceDependency();
+		d2.setRequired(true);
+
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			void init(Component c) {
+				System.out.println("init");
+				e.step(2);
+				c.add(d, d2); 
+				d.add(new EventImpl()); // won't trigger start because d2 is not yet available
+			}
+			void start() {
+				System.out.println("start");
+				e.step(4);
+			}
+			void stop() {
+				System.out.println("stop");
+				e.step(6);
+			}
+			void destroy() {
+				System.out.println("destroy");
+				e.step(7);
+			}
+		});
+		e.step(1);
+		c.start();
+		e.step(3);
+		d2.add(new EventImpl());
+		e.step(5);
+		d.remove(new EventImpl());
+		c.stop();
+		e.step(8);
+	}
+
+	@Test
+	public void createComponentAddDependencyAndStartComponent() {
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(MyComponent.class);
+		SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setRequired(true);
+		c.add(d);
+		c.start();
+		Assert.assertEquals("should not be available when started because of missing dependency", false, c.isAvailable());
+		c.stop();
+		c.remove(d);
+	}
+	
+	@Test
+	public void createComponentStartItAndAddDependency() {
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(MyComponent.class);
+		SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setRequired(true);
+		c.start();
+		Assert.assertEquals("should be available when started", true, c.isAvailable());
+		c.add(d);
+		Assert.assertEquals("dependency should not be available", false, d.isAvailable());
+		Assert.assertEquals("Component should not be available", false, c.isAvailable());
+		c.remove(d);
+		c.stop();
+	}
+	
+	@Test
+	public void createComponentStartItAddDependencyAndMakeDependencyAvailable() {
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(MyComponent.class);
+		SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setRequired(true);
+		c.start();
+		c.add(d);
+		Assert.assertEquals("Component should not be available: it is started but the dependency is not available", false, c.isAvailable());
+		d.add(new EventImpl());
+		Assert.assertEquals("dependency is available, component should be too", true, c.isAvailable());
+		d.remove(new EventImpl());
+		Assert.assertEquals("dependency is no longer available, component should not be either", false, c.isAvailable());
+		c.remove(d);
+		Assert.assertEquals("dependency is removed, component should be available again", true, c.isAvailable());
+		c.stop();
+		Assert.assertEquals("Component is stopped, should be unavailable now", false, c.isAvailable());
+	}
+	
+	@Test
+	public void createComponentStartItAddDependencyAndListenerMakeDependencyAvailableAndUnavailableImmediately() {
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(MyComponent.class);
+		final SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setRequired(true);
+		ComponentStateListener l = new ComponentStateListener() {
+			@Override
+			public void changed(Component c, ComponentState state) {
+				// make the dependency unavailable
+				d.remove(new EventImpl());
+			}
+		};
+		c.start();
+		c.add(d);
+		// we add a listener here which immediately triggers an 'external event' that
+		// makes the dependency unavailable again as soon as it's invoked
+		c.add(l);
+		Assert.assertEquals("Component unavailable, dependency unavailable", false, c.isAvailable());
+		// so even though we make the dependency available here, before our call returns it
+		// is made unavailable again
+		d.add(new EventImpl());
+		Assert.assertEquals("Component *still* unavailable, because the listener immediately makes the dependency unavailable", false, c.isAvailable());
+		c.remove(l);
+		Assert.assertEquals("listener removed, component still unavailable", false, c.isAvailable());
+		c.remove(d);
+		Assert.assertEquals("dependency removed, component available", true, c.isAvailable());
+		c.stop();
+		Assert.assertEquals("Component stopped, should be unavailable", false, c.isAvailable());
+	}
+	
+	@Test
+	public void createComponentAddTwoDependenciesMakeBothAvailableAndUnavailable() {
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(MyComponent.class);
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setRequired(true);
+		SimpleServiceDependency d2 = new SimpleServiceDependency();
+		d2.setRequired(true);
+		c.start();
+		c.add(d1);
+		c.add(d2);
+		Assert.assertEquals("Component should be unavailable, both dependencies are too", false, c.isAvailable());
+		d1.add(new EventImpl());
+		Assert.assertEquals("one dependency available, component should still be unavailable", false, c.isAvailable());
+		d2.add(new EventImpl());
+		Assert.assertEquals("both dependencies available, component should be available", true, c.isAvailable());
+		d1.remove(new EventImpl());
+		Assert.assertEquals("one dependency unavailable again, component should be unavailable too", false, c.isAvailable());
+		d2.remove(new EventImpl());
+		Assert.assertEquals("both dependencies unavailable, component should be too", false, c.isAvailable());
+		c.remove(d2);
+		Assert.assertEquals("removed one dependency, still unavailable", false, c.isAvailable());
+		c.remove(d1);
+		Assert.assertEquals("removed the other dependency, component should be available now", true, c.isAvailable());
+		c.stop();
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+
+	@Test
+	public void createComponentAddDependencyMakeAvailableAndUnavailableWithCallbacks() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+            public void add() {
+				e.step(1);
+			}
+            public void remove() {
+				e.step(3);
+			}
+		});
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setCallbacks("add", "remove");
+		d1.setRequired(true);
+		// add the dependency to the component
+		c.add(d1);
+		// start the component
+		c.start();
+		// make the dependency available, we expect the add callback
+		// to be invoked here
+		d1.add(new EventImpl());
+		e.step(2);
+		// remove the dependency, should trigger the remove callback
+		d1.remove(new EventImpl());
+		e.step(4);
+		c.stop();
+		c.remove(d1);
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+	
+	@Test
+	public void createAndStartComponentAddDependencyMakeAvailableAndUnavailableWithCallbacks() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			public void add() {
+				e.step(1);
+			}
+			public void remove() {
+				e.step(3);
+			}
+		});
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setCallbacks("add", "remove");
+		d1.setRequired(true);
+		// start the ComponentImpl (it should become available)
+		c.start();
+		// add the dependency (it should become unavailable)
+		c.add(d1);
+		// make the dependency available, which should invoke the
+		// add callback
+		d1.add(new EventImpl());
+		e.step(2);
+		// make the dependency unavailable, should trigger the
+		// remove callback
+		d1.remove(new EventImpl());
+		e.step(4);
+		c.remove(d1);
+		c.stop();
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+
+	@Test
+	public void createComponentAddTwoDependenciesMakeBothAvailableAndUnavailableWithCallbacks() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			public void add() {
+				e.step();
+			}
+			public void remove() {
+				e.step();
+			}
+		});
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setCallbacks("add", "remove");
+		d1.setRequired(true);
+		SimpleServiceDependency d2 = new SimpleServiceDependency();
+		d2.setCallbacks("add", "remove");
+		d2.setRequired(true);
+		// start the component, which should become active because there are no
+		// dependencies yet
+		c.start();
+		// now add the dependencies, making the ComponentImpl unavailable
+		c.add(d1);
+		c.add(d2);
+		// make the first dependency available, should have no effect on the
+		// component
+		d1.add(new EventImpl());
+		e.step(1);
+		// second dependency available, now all the add callbacks should be
+		// invoked
+		d2.add(new EventImpl());
+		e.step(4);
+		// remove the first dependency, triggering the remove callbacks
+		d1.remove(new EventImpl());
+		e.step(7);
+		// remove the second dependency, should not trigger more callbacks
+		d2.remove(new EventImpl());
+		e.step(8);
+		c.remove(d2);
+		c.remove(d1);
+		c.stop();
+		// still, no more callbacks should have been invoked
+		e.step(9);
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+	
+	@Test
+	public void createAndStartComponentAddTwoDependenciesMakeBothAvailableAndUnavailableWithCallbacks() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			public void add() {
+				e.step();
+			}
+			public void remove() {
+				e.step();
+			}
+		});
+		// start the component, it should become available
+		c.start();
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setCallbacks("add", "remove");
+		d1.setRequired(true);
+		SimpleServiceDependency d2 = new SimpleServiceDependency();
+		d2.setCallbacks("add", "remove");
+		d2.setRequired(true);
+		// add the first dependency, ComponentImpl should be unavailable
+		c.add(d1);
+		c.add(d2);
+		// make first dependency available, ComponentImpl should still be unavailable
+		d1.add(new EventImpl());
+		e.step(1);
+		// make second dependency available, ComponentImpl available, callbacks should
+		// be invoked
+		d2.add(new EventImpl());
+		e.step(4);
+		// remove the first dependency, callbacks should be invoked
+		d1.remove(new EventImpl());
+		e.step(7);
+		// remove second dependency, no callbacks should be invoked
+		d2.remove(new EventImpl());
+		e.step(8);
+		c.remove(d2);
+		c.remove(d1);
+		c.stop();
+		e.step(9);
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+
+	@Test
+	public void createAndStartComponentAddTwoDependenciesWithMultipleServicesWithCallbacks() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			public void add() {
+				e.step();
+			}
+			public void remove() {
+				e.step();
+			}
+		});
+		// start component
+		c.start();
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setCallbacks("add", "remove");
+		d1.setRequired(true);
+		SimpleServiceDependency d2 = new SimpleServiceDependency();
+		d2.setCallbacks("add", "remove");
+		d2.setRequired(true);
+		c.add(d1);
+		c.add(d2);
+		// add three instances to first dependency, no callbacks should
+		// be triggered
+		d1.add(new EventImpl(1));
+		d1.add(new EventImpl(2));
+		d1.add(new EventImpl(3));
+		e.step(1);
+		// add two instances to the second dependency, callbacks should
+		// be invoked (4x)
+		d2.add(new EventImpl(1));
+		e.step(6);
+		// add another dependency, triggering another callback
+		d2.add(new EventImpl(2));
+		e.step(8);
+		// remove first dependency (all three of them) which makes the 
+		// ComponentImpl unavailable so it should trigger calling remove for
+		// all of them (so 5x)
+		d1.remove(new EventImpl(1));
+		d1.remove(new EventImpl(2));
+		d1.remove(new EventImpl(3));
+		e.step(14);
+		// remove second dependency, should not trigger further callbacks
+		d2.remove(new EventImpl(1));
+		d2.remove(new EventImpl(2));
+		e.step(15);
+		c.remove(d2);
+		c.remove(d1);
+		c.stop();
+		e.step(16);
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+	
+	@Test
+	public void createComponentAddDependencyMakeAvailableChangeAndUnavailableWithCallbacks() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			public void add() {
+				e.step(1);
+			}
+			public void change() {
+				e.step(3);
+			}
+			public void remove() {
+				e.step(5);
+			}
+		});
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setCallbacks("add", "change", "remove");
+		d1.setRequired(true);
+		// add the dependency to the component
+		c.add(d1);
+		// start the component
+		c.start();
+		// make the dependency available, we expect the add callback
+		// to be invoked here
+		d1.add(new EventImpl());
+		e.step(2);
+		// change the dependency
+		d1.change(new EventImpl());
+		e.step(4);
+		// remove the dependency, should trigger the remove callback
+		d1.remove(new EventImpl());
+		e.step(6);
+		c.stop();
+		c.remove(d1);
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+
+	@Test
+	public void createComponentWithOptionalDependency() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			public void add() {
+				e.step(1);
+			}
+			public void change() {
+				e.step(3);
+			}
+			public void remove() {
+				e.step(5);
+			}
+		});
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setCallbacks("add", "change", "remove");
+		d1.setRequired(false);
+		// add the dependency to the component
+		c.add(d1);
+		// start the component
+		c.start();
+		Assert.assertEquals("Component started with an optional dependency, should be available", true, c.isAvailable());
+		// make the dependency available, we expect the add callback
+		// to be invoked here
+		d1.add(new EventImpl());
+		e.step(2);
+		Assert.assertEquals("Component started with an optional dependency, should be available", true, c.isAvailable());
+		// change the dependency
+		d1.change(new EventImpl());
+		e.step(4);
+		Assert.assertEquals("Component started with an optional dependency, should be available", true, c.isAvailable());
+		// remove the dependency, should trigger the remove callback
+		d1.remove(new EventImpl());
+		Assert.assertEquals("Component started with an optional dependency, should be available", true, c.isAvailable());
+		e.step(6);
+		c.stop();
+		c.remove(d1);
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+
+	@Test
+	public void createComponentWithOptionalAndRequiredDependency() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			public void add() {
+				e.step();
+			}
+			public void remove() {
+				e.step();
+			}
+		});
+		SimpleServiceDependency d1 = new SimpleServiceDependency();
+		d1.setCallbacks("add", "remove");
+		d1.setRequired(false);
+		SimpleServiceDependency d2 = new SimpleServiceDependency();
+		d2.setCallbacks("add", "remove");
+		d2.setRequired(true);
+		// add the dependencies to the component
+		c.add(d1);
+		c.add(d2);
+		// start the component
+		c.start();
+		Assert.assertEquals("Component started with a required and optional dependency, should not be available", false, c.isAvailable());
+		// make the optional dependency available
+		d1.add(new EventImpl());
+		e.step(1);
+		Assert.assertEquals("Component should not be available", false, c.isAvailable());
+		// make the required dependency available
+		d2.add(new EventImpl());
+		e.step(4);
+		Assert.assertEquals("Component should be available", true, c.isAvailable());
+		// remove the optional dependency
+		d1.remove(new EventImpl());
+		e.step(6);
+		Assert.assertEquals("Component should be available", true, c.isAvailable());
+		// remove the required dependency
+		d1.remove(new EventImpl());
+		e.step(8);
+		Assert.assertEquals("Component should be available", true, c.isAvailable());
+		c.stop();
+		c.remove(d1);
+		Assert.assertEquals("Component stopped, should be unavailable again", false, c.isAvailable());
+	}
+	
+	@Test
+	public void createComponentAddAvailableDependencyRemoveDependencyCheckStopCalledBeforeUnbind() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			void add() {
+				e.step(1);
+			}
+			void start() {
+				e.step(2);
+			}
+			void stop() {
+				e.step(4);
+			}
+			void remove() {
+				e.step(5);
+			}
+		});
+		SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setCallbacks("add", "remove");
+		d.setRequired(true);
+		// add the dependency to the component
+		c.add(d);
+		// start the component
+		c.start();
+		// make the dependency available, we expect the add callback
+		// to be invoked here, then start is called.
+		d.add(new EventImpl());
+		e.step(3);
+		// remove the dependency, should trigger the stop, then remove callback
+		d.remove(new EventImpl());
+		e.step(6);
+		c.stop();
+		c.remove(d);
+		Assert.assertEquals("Component stopped, should be unavailable", false, c.isAvailable());
+	}
+	
+	@Test
+	public void createDependenciesWithCallbackInstance() {
+		final Ensure e = new Ensure();
+		ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object() {
+			void start() {
+				e.step(2);
+			}
+			
+			void stop() {
+				e.step(4);
+			}
+		});
+		
+		Object callbackInstance = new Object() {
+			void add() {
+				e.step(1);
+			}
+			
+			void remove() {
+				e.step(5);
+			}
+		};		
+		
+		SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setCallbacks(callbackInstance, "add", "remove");
+		d.setRequired(true);
+		// add the dependency to the component
+		c.add(d);
+		// start the component
+		c.start();
+		// make the dependency available, we expect the add callback
+		// to be invoked here, then start is called.
+		d.add(new EventImpl());
+		e.step(3);
+		// remove the dependency, should trigger the stop, then remove callback
+		d.remove(new EventImpl());
+		e.step(6);
+		c.stop();
+		c.remove(d);
+		Assert.assertEquals("Component stopped, should be unavailable", false, c.isAvailable());
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/ConcurrencyTest.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/ConcurrencyTest.java
new file mode 100644
index 0000000..7f999bc
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/ConcurrencyTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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 test;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentState;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.impl.ComponentImpl;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ConcurrencyTest {
+	
+	/**
+	 * Ensure actions from another thread than the current thread executing in the SerialExecutor are being
+	 * scheduled (added to the queue) rather than being executed immediately.  
+	 */
+	@Test
+	public void createComponentAddDependencyAndListenerAndAddAnotherDependencyInAParallelThread() {
+		final Semaphore s = new Semaphore(0);
+		final ComponentImpl c = new ComponentImpl();
+		final SimpleServiceDependency d = new SimpleServiceDependency();
+		d.setRequired(true);
+		final SimpleServiceDependency d2 = new SimpleServiceDependency();
+		d2.setRequired(true);
+		final Thread t = new Thread() {
+			public void run() {
+				c.add(d2);
+				s.release();
+			}
+		};
+		ComponentStateListener l = new ComponentStateListener() {
+			@Override
+			public void changed(Component component, ComponentState state) {
+				try {
+				    c.remove(this);
+				    // launch a second thread interacting with our ComponentImpl and block this thread until the
+				    // second thread finished its interaction with our component. We want to ensure the work of 
+				    // the second thread is scheduled after our current job in the serial executor and does not
+				    // get executed immediately.
+				    t.start();
+				    s.acquire();
+				    Assert.assertEquals("dependency count should be 1", 1, c.getDependencies().size());
+				}
+				catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+		};
+		
+		c.setImplementation(new Object()); // If not, we may see NullPointers when invoking lifecycle callbacks
+		c.start();
+		c.add(d);
+		c.add(l);
+		Assert.assertEquals("component should not be available", false, c.isAvailable());
+		d.add(new EventImpl()); // sets dependency d to available and triggers our ComponentStateListener
+		
+		// due to the dependency added by the second thread in the serial executor we still expect our component
+		// to be unavailable. This work was scheduled in the serial executor and will be executed by the current
+		// thread after it finished handling the job for handling the changed() method.
+		Assert.assertEquals("component should not be available", false, c.isAvailable());
+		c.remove(l);
+		Assert.assertEquals("component should not be available", false, c.isAvailable());
+		c.remove(d);
+		Assert.assertEquals("component should not be available", false, c.isAvailable());
+		c.remove(d2);
+		Assert.assertEquals("component should be available", true, c.isAvailable());
+		c.stop();
+		Assert.assertEquals("component should not be available", false, c.isAvailable());
+	}
+
+	@Test
+	public void createComponentAddAndRemoveDependenciesInParallelThreads() throws Exception {
+		final ComponentImpl c = new ComponentImpl();
+		c.setImplementation(new Object()); // If not, we may see NullPointers when invoking lifecycle callbacks
+		ExecutorService e = Executors.newFixedThreadPool(16); 
+		c.start();
+		for (int i = 0; i < 1000; i++) {
+			e.execute(new Runnable() {
+				@Override
+				public void run() {
+				    SimpleServiceDependency d = new SimpleServiceDependency();
+					d.setRequired(true);
+					c.add(d);
+//					d.changed(new EventImpl(true));
+//					d.changed(new EventImpl(false));
+					c.remove(d);
+				}});
+		}
+		e.shutdown();
+		e.awaitTermination(10, TimeUnit.SECONDS);
+//		Assert.assertEquals("component should not be available", false, c.isAvailable());
+		c.stop();
+		Assert.assertEquals("component should not be available", false, c.isAvailable());
+	}
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/ConfigurationTest.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/ConfigurationTest.java
new file mode 100644
index 0000000..bf58bcf
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/ConfigurationTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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 test;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.impl.ComponentImpl;
+import org.apache.felix.dm.impl.ConfigurationDependencyImpl;
+import org.junit.Test;
+import org.osgi.service.cm.ConfigurationException;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes", "unused"})
+public class ConfigurationTest extends TestBase {
+    @Test
+    public void testConfigurationFailure() throws Throwable {
+        final Ensure e = new Ensure();
+
+        // Create our configuration dependency
+        final ConfigurationDependencyImpl conf = new ConfigurationDependencyImpl();
+
+        // Create another required dependency
+        final SimpleServiceDependency requiredDependency = new SimpleServiceDependency();
+        requiredDependency.setRequired(true);
+        requiredDependency.setCallbacks("addDep", null);
+
+        // Create our component, which will fail when handling configuration update
+        ComponentImpl c = new ComponentImpl();
+
+        c.setImplementation(new Object() {
+            volatile Dictionary m_conf;
+
+            public void updated(Dictionary conf) {
+                debug("updated: conf=%s", conf);
+                m_conf = conf;
+                if ("invalid".equals(conf.get("conf"))) {
+                    // We refuse the first configuration. 
+                    debug("refusing configuration");
+                    e.step(1);
+                    // Set our acceptUpdate flag to true, so next update will be successful
+                    throw new RuntimeException("update failed (expected)");
+                }
+                else {
+                    debug("accepting configuration");
+                    e.step(2);
+                }
+            }
+
+            public void addDep() {
+                if ("invalid".equals(m_conf.get("conf"))) {
+                    e.throwable(new Exception("addDep should not be called"));
+                }
+                e.step(3);
+                debug("addDep");
+            }
+
+            void init(Component c) {
+                if ("invalid".equals(m_conf.get("conf"))) {
+                    e.throwable(new Exception("init should not be called"));
+                }
+                e.step(4);
+                debug("init");
+            }
+
+            void start() {
+                if ("invalid".equals(m_conf.get("conf"))) {
+                    e.throwable(new Exception("start should not be called"));
+                }
+                e.step(5);
+                debug("start");
+            }
+        });
+
+        // Add the dependencies
+        c.add(conf);
+        c.add(requiredDependency);
+
+        // Start our component ("requiredDependency" is not yet available, so we'll stay in WAITING_FOR_REQUIRED state).
+        c.start();
+        
+        // Enabled "requiredDependency"
+        requiredDependency.add(new EventImpl());
+
+        // Now, act as the configuration admin service and inject a wrong dependency
+        try {
+            Hashtable props = new Hashtable();
+            props.put("conf", "invalid");
+            conf.updated(props);
+        }
+        catch (ConfigurationException err) {
+            warn("got expected configuration error");
+        }
+        e.waitForStep(1, 5000);
+        e.ensure();
+        
+        // Now, inject another valid configuration
+        try {
+            Hashtable props = new Hashtable();
+            props.put("conf", "valid");
+            conf.updated(props);
+        }
+        catch (ConfigurationException err) {
+            warn("got expected configuration error");
+        }
+        
+        // This time, our component should be started properly.
+        e.waitForStep(5, 5000);
+        e.ensure();
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/Ensure.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/Ensure.java
new file mode 100644
index 0000000..4d2378f
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/Ensure.java
@@ -0,0 +1,186 @@
+/*
+ * 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 test;
+
+import java.io.PrintStream;
+
+import org.junit.Assert;
+
+/**
+ * Helper class to make sure that steps in a test happen in the correct order. Instantiate
+ * this class and subsequently invoke <code>step(nr)</code> with steps starting at 1. You
+ * can also have threads wait until you arrive at a certain step.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Ensure {
+    private final boolean DEBUG;
+    private static long INSTANCE = 0;
+    private static final int RESOLUTION = 100;
+    private static PrintStream STREAM = System.out;
+    int step = 0;
+    private Throwable m_throwable;
+	private boolean previousStepFailed;
+    
+    public Ensure() {
+        this(true);
+    }
+    
+    public Ensure(boolean debug) {
+        DEBUG = debug;
+        if (DEBUG) {
+            INSTANCE++;
+        }
+    }
+
+    public void setStream(PrintStream output) {
+        STREAM = output;
+    }
+    
+    /**
+     * Mark this point as step <code>nr</code>.
+     * 
+     * @param nr the step we are in
+     */
+    public synchronized void step(int nr) {
+    	if (previousStepFailed) {
+    		throw new RuntimeException("can not enter into step " + nr + " (some previous steps failed)");
+    	}
+        step++;
+        try {
+        	Assert.assertEquals(nr, step);
+        } catch (Throwable e) {
+        	previousStepFailed = true;
+        	throw e;
+        }
+        if (DEBUG) {
+            String info = getLineInfo(3);
+            STREAM.println("[Ensure " + INSTANCE + "] step " + step + " [" + currentThread() + "] " + info);
+        }
+        notifyAll();
+    }
+
+    private String getLineInfo(int depth) {
+        StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+        String info = trace[depth].getClassName() + "." + trace[depth].getMethodName() + ":" + trace[depth].getLineNumber();
+        return info;
+    }
+    
+    /**
+     * Mark this point as the next step.
+     */
+    public synchronized void step() {
+    	if (previousStepFailed) {
+    		throw new RuntimeException("can not enter into step " + (step+1) + " (some previous steps failed)");
+    	}
+        step++;
+        if (DEBUG) {
+            String info = getLineInfo(3);
+            STREAM.println("[Ensure " + INSTANCE + "] next step " + step + " [" + currentThread() + "] " + info);
+        }
+        notifyAll();
+    }
+
+    /**
+     * Wait until we arrive at least at step <code>nr</code> in the process, or fail if that
+     * takes more than <code>timeout</code> milliseconds. If you invoke wait on a thread,
+     * you are effectively assuming some other thread will invoke the <code>step(nr)</code>
+     * method.
+     * 
+     * @param nr the step to wait for
+     * @param timeout the number of milliseconds to wait
+     */
+    public synchronized void waitForStep(int nr, int timeout) {
+        final int initialTimeout = timeout;
+        if (DEBUG) {
+            String info = getLineInfo(3);
+            STREAM.println("[Ensure " + INSTANCE + "] waiting for step " + nr + " [" + currentThread() + "] " + info);
+        }
+        while (step < nr && timeout > 0) {
+            try {
+                wait(RESOLUTION);
+                timeout -= RESOLUTION;
+            }
+            catch (InterruptedException e) {}
+        }
+        if (step < nr) {
+            throw new IllegalStateException("Timed out waiting for " + initialTimeout + " ms for step " + nr + ", we are still at step " + step);
+        }
+        if (DEBUG) {
+            String info = getLineInfo(3);
+            STREAM.println("[Ensure " + INSTANCE + "] arrived at step " + nr + " [" + currentThread() + "] " + info);
+        }
+    }
+    
+    private String currentThread() {
+        Thread thread = Thread.currentThread();
+        return thread.getId() + " " + thread.getName();
+    }
+    
+    public static Runnable createRunnableStep(final Ensure ensure, final int nr) {
+        return new Runnable() { public void run() { ensure.step(nr); }};
+    }
+    
+    public synchronized void steps(Steps steps) {
+        steps.next(this);
+    }
+    
+    /** 
+     * Helper class for naming a list of step numbers. If used with the steps(Steps) method
+     * you can define at which steps in time this point should be passed. That means you can
+     * check methods that will get invoked multiple times during a test.
+     */
+    public static class Steps {
+        private final int[] m_steps;
+        private int m_stepIndex;
+
+        /** 
+         * Create a list of steps and initialize the step counter to zero.
+         */
+        public Steps(int... steps) {
+            m_steps = steps;
+            m_stepIndex = 0;
+        }
+
+        /**
+         * Ensure we're at the right step. Will throw an index out of bounds exception if we enter this step more often than defined.
+         */
+        public void next(Ensure ensure) {
+            ensure.step(m_steps[m_stepIndex++]);
+        }
+    }
+
+    /**
+     * Saves a thrown exception that occurred in a different thread. You can only save one exception
+     * at a time this way.
+     */
+    public synchronized void throwable(Throwable throwable) {
+        m_throwable = throwable;
+    }
+
+    /**
+     * Throws a <code>Throwable</code> if one occurred in a different thread and that thread saved it
+     * using the <code>throwable()</code> method.
+     */
+    public synchronized void ensure() throws Throwable {
+        if (m_throwable != null) {
+            throw m_throwable;
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/EventImpl.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/EventImpl.java
new file mode 100644
index 0000000..28c5455
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/EventImpl.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 test;
+
+import org.apache.felix.dm.context.Event;
+
+/** in real life, this event might contain a service reference and service instance
+ * or something similar
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class EventImpl extends Event { // the actual event object (a Service, a Bundle, a Configuration, etc ...)
+	private final int m_id;
+
+	public EventImpl() {
+		this(1);
+	}
+	/** By constructing events with different IDs, we can simulate different unique instances. */
+	public EventImpl(int id) {
+		this (id, null);
+	}
+	
+	public EventImpl(int id, Object event) {
+	    super(event);
+	    m_id = id;
+	}
+	
+
+	@Override
+	public int hashCode() {
+		return m_id;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		// an instanceof check here is not "strong" enough with subclasses overriding the
+		// equals: we need to be sure that a.equals(b) == b.equals(a) at all times
+		if (obj != null && obj.getClass().equals(EventImpl.class)) {
+			return ((EventImpl) obj).m_id == m_id;
+		}
+		return false;
+	}
+	
+    @Override
+    public int compareTo(Event o) {
+        EventImpl a = this, b = (EventImpl) o;
+        if (a.m_id < b.m_id) {
+            return -1;
+        } else if (a.m_id == b.m_id){
+            return 0;
+        } else {
+            return 1;
+        }
+    }            
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/SerialExecutorTest.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/SerialExecutorTest.java
new file mode 100644
index 0000000..feb04c4
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/SerialExecutorTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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 test;
+
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.felix.dm.Logger;
+import org.apache.felix.dm.impl.SerialExecutor;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Validates SerialExecutor used by DM implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SerialExecutorTest extends TestBase {
+    final Random m_rnd = new Random();
+    final int TESTS = 100000;
+    
+    @Test
+    public void testSerialExecutor() {
+        info("Testing serial executor");
+        int cores = Math.max(10, Runtime.getRuntime().availableProcessors());
+        ExecutorService threadPool = null;
+
+        try {
+            threadPool = Executors.newFixedThreadPool(cores);
+            final SerialExecutor serial = new SerialExecutor(new Logger(null));
+
+            long timeStamp = System.currentTimeMillis();
+            for (int i = 0; i < TESTS; i++) {
+                final CountDownLatch latch = new CountDownLatch(cores * 2 /* each task reexecutes itself one time */);
+                final SerialTask task = new SerialTask(serial, latch);
+                for (int j = 0; j < cores; j ++) {
+                    threadPool.execute(new Runnable() {
+                        public void run() {
+                            serial.execute(task);
+                        }
+                    });
+                }
+                Assert.assertTrue("Test " + i + " did not terminate timely", latch.await(20000, TimeUnit.MILLISECONDS));
+            }
+            long now = System.currentTimeMillis();
+            System.out.println("Performed " + TESTS + " tests in " + (now - timeStamp) + " ms.");
+            timeStamp = now;
+        }
+        catch (Throwable t) {
+            t.printStackTrace();
+            Assert.fail("Test failed: " + t.getMessage());
+        }
+        finally {
+        	if (threadPool != null) {
+        		shutdown(threadPool);
+        	}
+        }
+    }
+
+    void shutdown(ExecutorService exec) {
+        exec.shutdown();
+        try {
+            exec.awaitTermination(5, TimeUnit.SECONDS);
+        }
+        catch (InterruptedException e) {
+        }
+    }
+
+    class SerialTask implements Runnable {
+        final AtomicReference<Thread> m_executingThread = new AtomicReference<Thread>();
+        final CountDownLatch m_latch;
+        private boolean m_firstExecution;
+        private final SerialExecutor m_exec;          
+        
+        SerialTask(SerialExecutor exec, CountDownLatch latch) {
+            m_latch = latch;
+            m_exec = exec;
+            m_firstExecution = true;
+        }
+        
+        public void run() {
+            Thread self = Thread.currentThread();
+            if (m_firstExecution) {
+                // The first time we are executed, the previous executing thread stored in our m_executingThread should be null
+                if (!m_executingThread.compareAndSet(null, self)) {
+                    System.out.println("detected concurrent call to SerialTask: currThread=" + self
+                        + ", other executing thread=" + m_executingThread);
+                    return;
+                }
+            } else {
+                // The second time we are executed, the previous executing thread stored in our m_executingThread should be 
+                // the current running thread.
+                if (m_executingThread.get() != self) {
+                    System.out.println("expect to execute reentrant tasks in same thread, but current thread=" + self
+                        + ", while expected is " + m_executingThread);
+                    return;
+                }
+            }
+                        
+            if (m_firstExecution) {
+                m_firstExecution = false;
+                m_exec.execute(this); // Our run method must be called immediately
+            } else {
+                if (! m_executingThread.compareAndSet(self, null)) {
+                    System.out.println("detected concurrent call to SerialTask: currThread=" + self
+                        + ", other executing thread=" + m_executingThread);
+                    return;                    
+                }
+                m_firstExecution = true;
+            }
+            
+            m_latch.countDown();
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/ServiceRaceTest.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/ServiceRaceTest.java
new file mode 100644
index 0000000..90873e7
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/ServiceRaceTest.java
@@ -0,0 +1,255 @@
+/*
+ * 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 test;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentState;
+import org.apache.felix.dm.ComponentStateListener;
+import org.apache.felix.dm.context.Event;
+import org.apache.felix.dm.impl.ComponentImpl;
+import org.apache.felix.dm.impl.ConfigurationDependencyImpl;
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.service.cm.ConfigurationException;
+
+/**
+ * This test class simulates a client having many dependencies being registered/unregistered concurrently.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class ServiceRaceTest extends TestBase {
+    final static int STEP_WAIT = 5000;
+    final static int DEPENDENCIES = 10;
+    final static int LOOPS = 10000;
+
+    // Executor used to bind/unbind service dependencies.
+    ExecutorService m_threadpool;
+    // Timestamp used to log the time consumed to execute 100 tests.
+    long m_timeStamp;
+
+    /**
+     * Creates many service dependencies, and activate/deactivate them concurrently.  
+     */
+    @Test
+    public void createParallelComponentRegistgrationUnregistration() {
+        info("Starting createParallelComponentRegistgrationUnregistration test");
+        int cores = Math.max(16, Runtime.getRuntime().availableProcessors());
+        info("using " + cores + " cores.");
+
+        m_threadpool = Executors.newFixedThreadPool(Math.max(cores, DEPENDENCIES + 3 /* start/stop/configure */));
+
+        try {
+            m_timeStamp = System.currentTimeMillis();
+            for (int loop = 0; loop < LOOPS; loop++) {
+                doTest(loop);
+            }
+        }
+        catch (Throwable t) {
+            warn("got unexpected exception", t);
+        }
+        finally {
+            shutdown(m_threadpool);
+        }
+    }
+
+    void shutdown(ExecutorService exec) {
+        exec.shutdown();
+        try {
+            exec.awaitTermination(5, TimeUnit.SECONDS);
+        }
+        catch (InterruptedException e) {
+        }
+    }
+
+    void doTest(int loop) throws Throwable {
+        debug("loop#%d -------------------------", loop);
+
+        final Ensure step = new Ensure(false);
+
+        // Create one client component, which depends on many service dependencies
+        final ComponentImpl client = new ComponentImpl();
+        final Client theClient = new Client(step);
+        client.setImplementation(theClient);
+
+        // Create client service dependencies
+        final SimpleServiceDependency[] dependencies = new SimpleServiceDependency[DEPENDENCIES];
+        for (int i = 0; i < DEPENDENCIES; i++) {
+            dependencies[i] = new SimpleServiceDependency();
+            dependencies[i].setRequired(true);
+            dependencies[i].setCallbacks("add", "remove");
+            client.add(dependencies[i]);
+        }
+        final ConfigurationDependencyImpl confDependency = new ConfigurationDependencyImpl();
+        confDependency.setPid("mypid");
+        client.add(confDependency);
+
+        // Create Configuration (concurrently).
+        // We have to simulate the configuration update, using a component state listener, which will
+        // trigger an update thread, but only once the component is started.
+        final ComponentStateListener listener = new ComponentStateListener() {
+            private volatile Dictionary m_conf;
+
+            public void changed(Component c, ComponentState state) {
+                if (state == ComponentState.WAITING_FOR_REQUIRED && m_conf == null) {
+                    m_conf = new Hashtable();
+                    m_conf.put("foo", "bar");
+                    m_threadpool.execute(new Runnable() {
+                        public void run() {
+                            try {
+                                confDependency.updated(m_conf);
+                            }
+                            catch (ConfigurationException e) {
+                                warn("configuration failed", e);
+                            }
+                        }
+                    });
+                }
+            }
+        };
+        client.add(listener);
+
+
+        // Start the client (concurrently)
+        m_threadpool.execute(new Runnable() {
+            public void run() {
+                client.start();
+                
+                // Activate the client service dependencies concurrently.
+                // We *must* do this after having started the component (in a reality, the dependencies can be 
+                // injected only one the tracker has been opened ...
+                for (int i = 0; i < DEPENDENCIES; i++) {
+                    final SimpleServiceDependency dep = dependencies[i];
+                    final Event added = new EventImpl(i);
+                    m_threadpool.execute(new Runnable() {
+                        public void run() {
+                            dep.add(added);
+                        }
+                    });
+                }
+
+            }
+        });
+
+        // Ensure that client has been started.
+        int expectedStep = 1 /* conf */ + DEPENDENCIES + 1 /* start */;
+        step.waitForStep(expectedStep, STEP_WAIT);
+        Assert.assertEquals(DEPENDENCIES, theClient.getDependencies());
+        Assert.assertNotNull(theClient.getConfiguration());
+        client.remove(listener);
+
+        // Stop the client and all dependencies concurrently.
+        for (int i = 0; i < DEPENDENCIES; i++) {
+            final SimpleServiceDependency dep = dependencies[i];
+            final Event removed = new EventImpl(i);
+            m_threadpool.execute(new Runnable() {
+                public void run() {
+                    dep.remove(removed);
+                }
+            });
+        }
+        m_threadpool.execute(new Runnable() {
+            public void run() {
+                client.stop();
+            }
+        });
+        m_threadpool.execute(new Runnable() {
+            public void run() {
+                try {
+                    confDependency.updated(null);
+                }
+                catch (ConfigurationException e) {
+                    warn("error while unconfiguring", e);
+                }
+            }
+        });
+
+        // Ensure that client has been stopped, then destroyed, then unbound from all dependencies
+        expectedStep += 2; // stop/destroy
+        expectedStep += DEPENDENCIES; // removed all dependencies
+        expectedStep += 1; // removed configuration
+        step.waitForStep(expectedStep, STEP_WAIT);
+        step.ensure();
+        Assert.assertEquals(0, theClient.getDependencies());
+        Assert.assertNull(theClient.getConfiguration());
+
+        debug("finished one test loop");
+        if ((loop + 1) % 100 == 0) {
+            long duration = System.currentTimeMillis() - m_timeStamp;
+            warn("Performed 100 tests (total=%d) in %d ms.", (loop + 1), duration);
+            m_timeStamp = System.currentTimeMillis();
+        }
+    }
+
+    public class Client {
+        final Ensure m_step;
+        int m_dependencies;
+        volatile Dictionary m_conf;
+        
+        public Client(Ensure step) {
+            m_step = step;
+        }
+
+        public void updated(Dictionary conf) throws ConfigurationException {
+            m_conf = conf;
+            if (conf != null) {
+                Assert.assertEquals("bar", conf.get("foo"));
+                m_step.step(1);
+            } else {
+                m_step.step();
+            }
+        }
+        
+        synchronized void add() {
+            m_step.step();
+            m_dependencies++;
+        }
+        
+        synchronized void remove() {
+            m_step.step();
+            m_dependencies--;
+        }
+                
+        void start() {
+            m_step.step((DEPENDENCIES + 1) /* deps + conf */ + 1 /* start */);
+        }
+
+        void stop() {
+            m_step.step((DEPENDENCIES + 1) /* deps + conf */ + 1 /* start */ + 1 /* stop */);
+        }
+        
+        void destroy() {
+            m_step.step((DEPENDENCIES + 1) /* deps + conf */ + 1 /* start */ + 1 /* stop */  + 1 /* destroy */);
+        }
+        
+        synchronized int getDependencies() {
+            return m_dependencies;
+        }
+        
+        Dictionary getConfiguration() {
+            return m_conf;
+        }
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/SimpleServiceDependency.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/SimpleServiceDependency.java
new file mode 100644
index 0000000..323fffc
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/SimpleServiceDependency.java
@@ -0,0 +1,94 @@
+/*
+ * 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 test;
+
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.context.AbstractDependency;
+import org.apache.felix.dm.context.DependencyContext;
+import org.apache.felix.dm.context.Event;
+import org.apache.felix.dm.context.EventType;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SimpleServiceDependency extends AbstractDependency<Dependency> {
+    @Override
+    public String getType() {
+        return "SimpleServiceDependency";
+    }
+
+    @Override
+    public String getSimpleName() {
+        return "SimpleServiceDependency";
+    }
+
+    @Override
+    public DependencyContext createCopy() {
+        return new SimpleServiceDependency();
+    }
+    
+    @Override
+    public void invokeCallback(EventType type, Event ... e) {
+        switch (type) {
+        case ADDED:
+            if (m_add != null) {
+                invoke (m_add, e[0], getInstances());
+            }
+            break;
+        case CHANGED:
+            if (m_change != null) {
+                invoke (m_change, e[0], getInstances());
+            }
+            break;
+        case REMOVED:
+            if (m_remove != null) {
+                invoke (m_remove, e[0], getInstances());
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    public void invoke(String method, Event e, Object[] instances) {
+        // specific for this type of dependency
+        m_component.invokeCallbackMethod(instances, method, new Class[][] { {} }, new Object[][] { {} });
+    }
+
+    public void add(final Event e) {
+        m_component.handleEvent(this, EventType.ADDED, e);
+    }
+    
+    public void change(final Event e) {
+        m_component.handleEvent(this, EventType.CHANGED, e);
+    }
+
+    public void remove(final Event e) {
+        m_component.handleEvent(this, EventType.REMOVED, e);
+    }
+    
+    public void swap(final Event event, final Event newEvent) {
+        m_component.handleEvent(this, EventType.SWAPPED, event, newEvent);
+    }
+
+    @Override
+    public Class<?> getAutoConfigType() {
+        return null; // we don't support auto config mode.
+    }
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/TestBase.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/TestBase.java
new file mode 100644
index 0000000..948a596
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/TestBase.java
@@ -0,0 +1,70 @@
+/*
+ * 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 test;
+
+import static java.lang.System.out;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Base class for all tests.
+ * For now, this class provides logging support.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TestBase {
+    final int WARN = 1;
+    final int INFO = 2;
+    final int DEBUG = 3;
+    
+    // Set the enabled log level.
+    final int m_level = WARN;
+    
+    @SuppressWarnings("unused")
+    void debug(String format, Object ... params) {
+        if (m_level >= DEBUG) {
+            out.println(Thread.currentThread().getName() + " - " + String.format(format, params));
+        }
+    }
+    
+    void warn(String format, Object ... params) {
+        warn(format, null, params);
+    }
+    
+    @SuppressWarnings("unused")
+    void info(String format, Object ... params) {
+        if (m_level >= INFO) {
+            out.println(Thread.currentThread().getName() + " - " + String.format(format, params));
+        }
+    }
+
+    void warn(String format, Throwable t, Object ... params) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(Thread.currentThread().getName()).append(" - ").append(String.format(format, params));
+        if (t != null) {
+            StringWriter buffer = new StringWriter();
+            PrintWriter pw = new PrintWriter(buffer);
+            t.printStackTrace(pw);
+            sb.append(System.getProperty("line.separator"));
+            sb.append(buffer.toString());
+        }
+        System.out.println(sb.toString());
+    }
+}
