diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/DiagnosticsTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/DiagnosticsTest.java
new file mode 100644
index 0000000..5a459d5
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/DiagnosticsTest.java
@@ -0,0 +1,464 @@
+/*
+ * 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.itest.api;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentDeclaration;
+import org.apache.felix.dm.ConfigurationDependency;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
+import org.apache.felix.dm.diagnostics.CircularDependency;
+import org.apache.felix.dm.diagnostics.DependencyGraph;
+import org.apache.felix.dm.diagnostics.DependencyGraph.ComponentState;
+import org.apache.felix.dm.diagnostics.DependencyGraph.DependencyState;
+import org.apache.felix.dm.diagnostics.MissingDependency;
+import org.apache.felix.dm.itest.util.TestBase;
+
+public class DiagnosticsTest extends TestBase {
+	
+	// there is one TestComponent created by org.apache.felix.dm.itest.bundle
+	// this component is always registered, so we only need to take it into 
+	// account when we build the graph with ALL components
+	private static final int InitialComponentCount = 1;
+	
+	private boolean checkComponentCount(int expected, int count) {
+		return count == expected + InitialComponentCount;
+	}
+	
+	public void testWithoutComponents() throws Exception {
+		
+		DependencyGraph graph = DependencyGraph.getGraph(
+				ComponentState.ALL, 
+				DependencyState.ALL);
+	
+		assertTrue(checkComponentCount(0, graph.getAllComponents().size()));
+		assertTrue(graph.getAllDependencies().isEmpty());
+	}
+	
+	public void testSingleComponent() throws Exception {
+		
+		DependencyManager dm = getDM();
+		
+		Component component = dm.createComponent()
+								.setImplementation(Object.class);
+							
+		dm.add(component);
+		
+		DependencyGraph graph = DependencyGraph.getGraph(
+				ComponentState.ALL, DependencyState.ALL);
+		
+		assertTrue(checkComponentCount(1, graph.getAllComponents().size()));
+		assertTrue(graph.getAllDependencies().isEmpty());
+		
+		graph = DependencyGraph.getGraph(
+				ComponentState.UNREGISTERED, DependencyState.ALL_UNAVAILABLE);
+		
+		assertTrue(graph.getAllComponents().isEmpty());
+		assertTrue(graph.getAllDependencies().isEmpty());
+	}
+
+	public void testServiceDependencyMissing() throws Exception {
+		
+		DependencyManager dm = getDM();
+		
+		ServiceDependency serviceDependency1 = dm.createServiceDependency()
+				.setService(S1.class)
+				.setRequired(true);
+		ServiceDependency serviceDependency2 = dm.createServiceDependency()
+				.setService(S2.class)
+				.setRequired(true);
+		
+		Component component1 = dm.createComponent()
+				.setImplementation(C0.class)
+				.add(serviceDependency1);
+		Component component2 = dm.createComponent()
+				.setImplementation(S1Impl1.class)
+				.setInterface(S1.class.getName(), null)
+				.add(serviceDependency2);
+		
+		dm.add(component1);
+		dm.add(component2);
+		
+		DependencyGraph graph = DependencyGraph.getGraph(
+				ComponentState.UNREGISTERED, DependencyState.REQUIRED_UNAVAILABLE);
+		
+		assertEquals(2, graph.getAllComponents().size());
+		assertEquals(2, graph.getAllDependencies().size());
+		
+		List<MissingDependency> missingDependencies = graph.getMissingDependencies("service");
+		assertEquals(1, missingDependencies.size());
+		assertEquals(S2.class.getName(), missingDependencies.get(0).getName());
+		
+		assertTrue(graph.getMissingDependencies("configuration").isEmpty());
+		assertTrue(graph.getMissingDependencies("bundle").isEmpty());
+		assertTrue(graph.getMissingDependencies("resource").isEmpty());
+		
+	}
+	
+	public void testConfigurationDependencyMissing() throws Exception {
+		
+		DependencyManager dm = getDM();
+		
+		ConfigurationDependency configurationDependency1 = dm.createConfigurationDependency()
+				.setPid("missing.configuration.pid");
+		
+		Component component1 = dm.createComponent()
+				.setImplementation(Object.class)
+				.add(configurationDependency1);
+		m_dm.add(component1);
+		
+		DependencyGraph graph = DependencyGraph.getGraph(ComponentState.UNREGISTERED, DependencyState.REQUIRED_UNAVAILABLE);
+		
+		assertEquals(1, graph.getAllComponents().size());
+		assertEquals(1, graph.getAllDependencies().size());
+		
+		List<MissingDependency> missingServiceDependencies = graph.getMissingDependencies("service");
+		assertTrue(missingServiceDependencies.isEmpty());
+		
+		List<MissingDependency> missingConfigDependencies = graph.getMissingDependencies("configuration");
+		assertEquals(1, missingConfigDependencies.size());
+		
+		MissingDependency missingConfigDependency = missingConfigDependencies.get(0);
+		assertEquals("missing.configuration.pid", missingConfigDependency.getName());
+	}
+
+	public void testProvidersWithoutProperties() throws Exception {
+		DependencyManager dm = getDM();
+		
+		ServiceDependency serviceDependency1 = dm.createServiceDependency()
+				.setService(S1.class)
+				.setRequired(true);
+		
+		Component component1 = dm.createComponent()
+				.setImplementation(C0.class)
+				.add(serviceDependency1);
+		
+		Component component2 = dm.createComponent()
+				.setImplementation(S1Impl1.class)
+				.setInterface(S1.class.getName(), null);
+		Component component3 = dm.createComponent()
+				.setImplementation(S1Impl2.class)
+				.setInterface(S1.class.getName(), null);
+		
+		dm.add(component1);
+		dm.add(component2);
+		dm.add(component3);
+		
+		DependencyGraph graph = DependencyGraph.getGraph(ComponentState.ALL, DependencyState.ALL);
+		
+		List<ComponentDeclaration> providers = graph.getProviders(serviceDependency1);
+		assertEquals(2, providers.size());
+		assertTrue(providers.contains(component2));
+		assertTrue(providers.contains(component3));
+	}
+	
+	public void testProvidersWithProperties() throws Exception {
+		
+		DependencyManager dm = getDM();
+		
+		ServiceDependency serviceDependency1 = dm.createServiceDependency()
+				.setService(S1.class, "(key=value)")
+				.setRequired(true);
+		
+		Component component1 = dm.createComponent()
+				.setImplementation(C0.class)
+				.add(serviceDependency1);
+
+		Properties component2Properties = new Properties();
+		component2Properties.put("key", "value");
+		Properties component4Properties = new Properties();
+		component4Properties.put("key", "otherValue");
+
+		Component component2 = dm.createComponent()
+				.setImplementation(S1Impl1.class)
+				.setInterface(S1.class.getName(), component2Properties);
+		Component component3 = dm.createComponent()
+				.setImplementation(S1Impl2.class)
+				.setInterface(S1.class.getName(), null);
+		Component component4 = dm.createComponent()
+				.setImplementation(S1Impl3.class)
+				.setInterface(S1.class.getName(), component4Properties);
+
+		m_dm.add(component1);
+		m_dm.add(component2);
+		m_dm.add(component3);
+		m_dm.add(component4);
+		
+		DependencyGraph graph = DependencyGraph.getGraph(ComponentState.ALL, DependencyState.ALL);
+		
+		List<ComponentDeclaration> providers = graph.getProviders(serviceDependency1);
+		assertEquals(1, providers.size());
+		assertTrue(providers.contains(component2));
+		assertFalse(providers.contains(component3));
+		assertFalse(providers.contains(component4));
+		
+	}
+
+	public void testCircularDependencies() throws Exception {
+		
+		DependencyManager dm = getDM();
+		
+		Component component0 = dm.createComponent()
+				.setImplementation(C0.class)
+				.add(dm.createServiceDependency()
+						.setService(S1.class)
+						.setRequired(true));
+
+		Component component1 = dm.createComponent()
+				.setImplementation(S1Impl1.class)
+				.setInterface(S1.class.getName(), null)
+				.add(dm.createServiceDependency()
+						.setService(S2.class)
+						.setRequired(true));
+		Component component2 = dm.createComponent()
+				.setImplementation(S2Impl1.class)
+				.setInterface(S2.class.getName(), null)
+				.add(dm.createServiceDependency()
+						.setService(S1.class)
+						.setRequired(true));
+		
+		m_dm.add(component0);
+		m_dm.add(component1);
+		m_dm.add(component2);
+		
+		DependencyGraph graph = DependencyGraph.getGraph(ComponentState.UNREGISTERED,DependencyState.REQUIRED_UNAVAILABLE);
+		List<CircularDependency> circularDependencies = graph.getCircularDependencies();
+		
+		assertEquals(1, circularDependencies.size());
+		
+		List<ComponentDeclaration> circularDependencyComponents = circularDependencies.get(0).getComponents(); 
+		assertTrue(circularDependencyComponents.contains(component1));
+		assertTrue(circularDependencyComponents.contains(component2));
+		assertFalse(circularDependencyComponents.contains(component0));
+		
+	}
+	
+	public void testWithTwoProvidersOneUnavailable() {
+		DependencyManager dm = getDM();
+		
+		Component component0 = dm.createComponent()
+				.setImplementation(C0.class)
+				.add(dm.createServiceDependency()
+						.setService(S1.class)
+						.setRequired(true));
+		Component component1 = dm.createComponent()
+				.setImplementation(S1Impl1.class)
+				.setInterface(S1.class.getName(), null);
+		Component component2 = dm.createComponent()
+				.setImplementation(S1Impl2.class)
+				.setInterface(S1.class.getName(), null)
+				.add(dm.createServiceDependency()
+						.setService(S2.class)
+						.setRequired(true));
+		
+		dm.add(component0);
+		dm.add(component1);
+		dm.add(component2);
+		
+		DependencyGraph graph = DependencyGraph.getGraph(ComponentState.UNREGISTERED, DependencyState.REQUIRED_UNAVAILABLE);
+		
+		assertEquals(1, graph.getAllComponents().size());
+		List<MissingDependency> missingDependencies = graph.getMissingDependencies("service");
+		assertEquals(1, missingDependencies.size());
+	
+		MissingDependency missingDependency = missingDependencies.get(0);
+		assertTrue(missingDependency.getName().equals(S2.class.getName()));
+		
+	}
+	
+	public void testGraphsWithSeveralComponentDependencyCombinations() throws Exception {
+		
+		DependencyManager dm = getDM();
+		
+		Component component0 = dm.createComponent()
+				.setImplementation(C0.class)
+				.add(dm.createServiceDependency()
+						.setService(S1.class)
+						.setRequired(true))
+				.add(dm.createServiceDependency()
+						.setService(S3.class)
+						.setRequired(true))
+				.add(dm.createServiceDependency()
+						.setService(S4.class)
+						.setRequired(true));
+		Component component1 = dm.createComponent()
+				.setImplementation(C1.class)
+				.add(dm.createServiceDependency()
+						.setService(S5.class)
+						.setRequired(true))
+				.add(dm.createServiceDependency()
+						.setService(S6.class)
+						.setRequired(true))
+				.add(dm.createServiceDependency()
+						.setService(S7.class)
+						.setRequired(true));
+		Component s1Impl1 = dm.createComponent()
+				.setImplementation(S1Impl1.class)
+				.setInterface(S1.class.getName(), null)
+				.add(dm.createServiceDependency()
+						.setService(S2.class)
+						.setRequired(true));
+		Component s1Impl2 = dm.createComponent()
+				.setImplementation(S1Impl2.class)
+				.setInterface(S1.class.getName(), null);
+
+		Component s3Impl1 = dm.createComponent()
+				.setImplementation(S3Impl1.class)
+				.setInterface(S3.class.getName(), null)
+				.add(dm.createConfigurationDependency()
+						.setPid("missing.config.pid"));
+		Component s3s4Impl = dm.createComponent()
+				.setImplementation(S3S4Impl.class)
+				.setInterface( new String[] {S3.class.getName(), S4.class.getName()}, null);
+		Component s4Impl1 = dm.createComponent()
+				.setImplementation(S4Impl1.class)
+				.setInterface(S4.class.getName(), null);
+		Component s5Impl1 = dm.createComponent()
+				.setImplementation(S5Impl1.class)
+				.setInterface(S5.class.getName(), null);
+		Component s6s7Impl = dm.createComponent()
+				.setImplementation(S6S7Impl.class)
+				.setInterface( new String[] {S6.class.getName(), S7.class.getName()}, null)
+				.add(dm.createServiceDependency()
+						.setService(S8.class)
+						.setRequired(true));
+		Component s8Impl1 = dm.createComponent()
+				.setImplementation(S8Impl1.class)
+				.setInterface(S8.class.getName(), null)
+				.add(dm.createServiceDependency()
+						.setService(S6.class)
+						.setRequired(true));
+		dm.add(component0);
+		dm.add(component1);
+		dm.add(s1Impl1); dm.add(s1Impl2);
+		dm.add(s3Impl1); dm.add(s3s4Impl);
+		dm.add(s4Impl1); dm.add(s5Impl1);
+		dm.add(s6s7Impl); dm.add(s8Impl1);
+		
+		
+		// graph containing all components and dependencies
+		DependencyGraph graph = DependencyGraph.getGraph(ComponentState.ALL, DependencyState.ALL);
+		
+		List<ComponentDeclaration> allComponents = graph.getAllComponents();
+		assertTrue(checkComponentCount(10, allComponents.size()));
+		
+		List<MissingDependency> missingDependencies = graph.getMissingDependencies("service");
+		assertEquals(1, missingDependencies.size());
+		
+		missingDependencies = graph.getMissingDependencies("configuration");
+		assertEquals(1, missingDependencies.size());
+		
+		List<CircularDependency> circularDependencies = graph.getCircularDependencies();
+		assertEquals(1, circularDependencies.size());
+		CircularDependency circularDependency = circularDependencies.get(0);
+
+		assertEquals(3, circularDependency.getComponents().size());
+		assertTrue(circularDependency.getComponents().contains(s6s7Impl));
+		assertTrue(circularDependency.getComponents().contains(s8Impl1));
+
+		// graph containing unregistered components and unavailable required dependencies
+		graph = null;
+		graph = DependencyGraph.getGraph(ComponentState.UNREGISTERED, DependencyState.REQUIRED_UNAVAILABLE);
+	
+		List<ComponentDeclaration> unregComponents = graph.getAllComponents();
+		assertEquals(5, unregComponents.size());
+		assertTrue(unregComponents.contains(s1Impl1));
+		assertTrue(unregComponents.contains(s3Impl1));
+		assertTrue(unregComponents.contains(component1));
+		assertTrue(unregComponents.contains(s6s7Impl));
+		assertTrue(unregComponents.contains(s8Impl1));
+		assertFalse(unregComponents.contains(component0));
+		
+		circularDependencies = graph.getCircularDependencies();
+		assertEquals(1, circularDependencies.size());
+		circularDependency = circularDependencies.get(0);
+
+		assertEquals(3, circularDependency.getComponents().size());
+		assertTrue(circularDependency.getComponents().contains(s6s7Impl));
+		assertTrue(circularDependency.getComponents().contains(s8Impl1));
+		
+		missingDependencies = graph.getMissingDependencies("service");
+		assertEquals(1, missingDependencies.size());	
+		
+		missingDependencies = graph.getMissingDependencies("configuration");
+		assertEquals(1, missingDependencies.size());
+
+		// call getCircularDependencies again on the same graph
+		circularDependencies = graph.getCircularDependencies();
+		assertEquals(1, circularDependencies.size());
+		circularDependency = circularDependencies.get(0);
+
+		assertEquals(3, circularDependency.getComponents().size());
+		assertTrue(circularDependency.getComponents().contains(s6s7Impl));
+		assertTrue(circularDependency.getComponents().contains(s8Impl1));
+		
+		List<MissingDependency> allMissingDependencies = graph.getMissingDependencies(null);
+		assertEquals(2, allMissingDependencies.size());
+
+	}
+	
+	static interface S1 {}
+	static interface S2 {}
+	static interface S3 {}
+	static interface S4 {}
+	static interface S5 {}
+	static interface S6 {}
+	static interface S7 {}
+	static interface S8 {}
+	static class C0 {
+		public C0() {}
+	}
+	static class C1 {
+		public C1() {}
+	}
+	static class S1Impl1 implements S1 {
+		public S1Impl1(){}
+	}
+	static class S1Impl2 implements S1 {
+		public S1Impl2() {}
+	}
+	static class S1Impl3 implements S1 {
+		public S1Impl3() {}
+	}
+	static class S2Impl1 implements S2 {
+		public S2Impl1() {}
+	}
+	static class S3Impl1 implements S3 {
+		public S3Impl1() {}
+	}
+	static class S3S4Impl implements S3, S4 {
+		public S3S4Impl() {}
+	}
+	static class S4Impl1 implements S4 {
+		public S4Impl1() {}
+	}
+	static class S5Impl1 implements S5 {
+		public S5Impl1() {}
+	}
+	static class S6S7Impl implements S6, S7 {
+		public S6S7Impl() {}
+	}
+	static class S8Impl1 implements S8 {
+		public S8Impl1() {}
+	}
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd
index 08e99e2..1a649f0 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd
+++ b/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd
@@ -24,7 +24,7 @@
 Private-Package: \
 	org.apache.felix.dm.shell
 Bundle-Activator:org.apache.felix.dm.shell.Activator
-Bundle-Version: 4.0.1
+Bundle-Version: 4.0.2
 Include-Resource: META-INF/=resources/LICENSE,\
 	META-INF/=resources/NOTICE,\
 	META-INF/=resources/DEPENDENCIES,\
diff --git a/dependencymanager/org.apache.felix.dependencymanager.shell/resources/changelog.txt b/dependencymanager/org.apache.felix.dependencymanager.shell/resources/changelog.txt
index 2e15e6d..51be153 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.shell/resources/changelog.txt
+++ b/dependencymanager/org.apache.felix.dependencymanager.shell/resources/changelog.txt
@@ -1,3 +1,9 @@
+Release org.apache.felix.dependencymanager.r3:
+---------------------------------------------
+
+** Improvement
+    * [FELIX-4889] - Refactor dm shell command to use the org.apache.dm.diagnostics api
+
 Release org.apache.felix.dependencymanager.r1:
 ---------------------------------------------
 
diff --git a/dependencymanager/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java b/dependencymanager/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java
index e4171cb..440566c 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.shell/src/org/apache/felix/dm/shell/DMCommand.java
@@ -23,19 +23,19 @@
 import java.util.Comparator;
 import java.util.Dictionary;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.Set;
 import java.util.StringTokenizer;
-import java.util.TreeSet;
 
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.ComponentDeclaration;
 import org.apache.felix.dm.ComponentDependencyDeclaration;
 import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.diagnostics.CircularDependency;
+import org.apache.felix.dm.diagnostics.DependencyGraph;
+import org.apache.felix.dm.diagnostics.DependencyGraph.ComponentState;
+import org.apache.felix.dm.diagnostics.DependencyGraph.DependencyState;
+import org.apache.felix.dm.diagnostics.MissingDependency;
 import org.apache.felix.service.command.CommandSession;
 import org.apache.felix.service.command.Descriptor;
 import org.apache.felix.service.command.Parameter;
@@ -57,11 +57,11 @@
      * Bundle context used to create OSGi filters.
      */
     private final BundleContext m_context;
-    
+        
     /**
-     * Sorter used to sort components.
+     * Comparator used to compare component declarations based on their bundle ids
      */
-    private static final DependencyManagerSorter SORTER = new DependencyManagerSorter();
+    private static final ComponentDeclarationComparator COMPONENT_DECLARATION_COMPARATOR = new ComponentDeclarationComparator();
 
     /**
      * Constant used by the wtf command, when listing missing services.
@@ -72,6 +72,16 @@
      * Constant used by the wtf command, when listing missing configurations.
      */
     private static final String CONFIGURATION = "configuration";
+    
+    /**
+     * Constant used by the wtf command, when listing missing resource dependencies
+     */
+    private static final String RESOURCE = "resource";
+    
+    /**
+     * Constant used by the wtf command, when listing missing bundle dependencies
+     */
+    private static final String BUNDLE = "bundle";
 
     /**
      * Name of a specific gogo shell variable, which may be used to configure "compact" mode.
@@ -212,100 +222,96 @@
             wtf();
             return;
         }
-
-        // lookup all dependency manager service components
-        List<DependencyManager> managers = DependencyManager.getDependencyManagers();
-        Collections.sort(managers, SORTER);
-        Iterator<DependencyManager> iterator = managers.iterator();
+        
+        DependencyGraph graph = null;
+        if(notavail) {
+        	graph = DependencyGraph.getGraph(ComponentState.UNREGISTERED, DependencyState.ALL_UNAVAILABLE);
+        } else {
+        	graph = DependencyGraph.getGraph(ComponentState.ALL, DependencyState.ALL);
+        }
+        
+        List<ComponentDeclaration> allComponents = graph.getAllComponents();
+        Collections.sort(allComponents, COMPONENT_DECLARATION_COMPARATOR);
         long numberOfComponents = 0;
         long numberOfDependencies = 0;
         long lastBundleId = -1;
-        while (iterator.hasNext()) {
-            DependencyManager manager = iterator.next();
-            List<Component> complist = manager.getComponents();
-            Iterator<Component> componentIterator = complist.iterator();
-            while (componentIterator.hasNext()) {
-                Component component = componentIterator.next();
-                ComponentDeclaration sc = component.getComponentDeclaration();
-                String name = sc.getName();
-                // check if this component is enabled or disabled.
-                if (!mayDisplay(component, servicesFilter, componentsRegex, cids)) {
-                    continue;
+        
+        for(ComponentDeclaration cd : allComponents) {
+        	Bundle bundle = cd.getBundleContext().getBundle();
+        	if(!matchBundle(bundle, bids)) {
+        		continue;
+        	}
+        	
+        	Component component = (Component)cd;
+        	String name = cd.getName();
+        	if (!mayDisplay(component, servicesFilter, componentsRegex, cids)) {
+                continue;
+            }
+        	
+        	numberOfComponents++;
+    		long bundleId = bundle.getBundleId();
+    		if(lastBundleId != bundleId) {
+    			lastBundleId = bundleId;
+    			if (comp) {
+                    System.out.println("[" + bundleId + "] " + compactName(bundle.getSymbolicName()));
+                } else {
+                    System.out.println("[" + bundleId + "] " + bundle.getSymbolicName());
                 }
-                int state = sc.getState();
-                Bundle bundle = sc.getBundleContext().getBundle();
-                if (matchBundle(bundle, bids)) {
-                    long bundleId = bundle.getBundleId();
-                    if (notavail) {
-                        if (sc.getState() != ComponentDeclaration.STATE_UNREGISTERED) {
-                            continue;
-                        }
+    		}
+    		if (comp) {
+                System.out.print(" [" + cd.getId() + "] " + compactName(name) + " "
+                        + compactState(ComponentDeclaration.STATE_NAMES[cd.getState()]));
+            } else {
+                System.out.println(" [" + cd.getId() + "] " + name + " "
+                        + ComponentDeclaration.STATE_NAMES[cd.getState()]);
+            }
+    		
+    		if(!nodeps) {
+    			List<ComponentDependencyDeclaration> dependencies = graph.getDependecies(cd);
+    			if(!dependencies.isEmpty()) {
+    				numberOfDependencies += dependencies.size();
+    				if (comp) {
+                        System.out.print('(');
                     }
+    				for(int j = 0; j < dependencies.size(); j ++) {
+        				ComponentDependencyDeclaration dep = dependencies.get(j);
+        				
+        				String depName = dep.getName();
+                        String depType = dep.getType();
+                        int depState = dep.getState();
 
-                    numberOfComponents++;
-                    if (lastBundleId != bundleId) {
-                        lastBundleId = bundleId;
                         if (comp) {
-                            System.out.println("[" + bundleId + "] " + compactName(bundle.getSymbolicName()));
+                            if (j > 0) {
+                                System.out.print(' ');
+                            }
+                            System.out.print(compactName(depName) + " " + compactState(depType) + " "
+                                    + compactState(ComponentDependencyDeclaration.STATE_NAMES[depState]));
                         } else {
-                            System.out.println("[" + bundleId + "] " + bundle.getSymbolicName());
+                            System.out.println("    " + depName + " " + depType + " "
+                                    + ComponentDependencyDeclaration.STATE_NAMES[depState]);
                         }
-                    }
-                    if (comp) {
-                        System.out.print(" [" + sc.getId() + "] " + compactName(name) + " "
-                                + compactState(ComponentDeclaration.STATE_NAMES[state]));
-                    } else {
-                        System.out.println(" [" + sc.getId() + "] " + name + " "
-                                + ComponentDeclaration.STATE_NAMES[state]);
-                    }
-                    if (!nodeps) {
-                        ComponentDependencyDeclaration[] dependencies = sc.getComponentDependencies();
-                        if (dependencies != null && dependencies.length > 0) {
-                            numberOfDependencies += dependencies.length;
-                            if (comp) {
-                                System.out.print('(');
-                            }
-                            for (int j = 0; j < dependencies.length; j++) {
-                                ComponentDependencyDeclaration dep = dependencies[j];
-                                if (notavail && !isUnavailable(dep)) {
-                                    continue;
-                                }
-                                String depName = dep.getName();
-                                String depType = dep.getType();
-                                int depState = dep.getState();
 
-                                if (comp) {
-                                    if (j > 0) {
-                                        System.out.print(' ');
-                                    }
-                                    System.out.print(compactName(depName) + " " + compactState(depType) + " "
-                                            + compactState(ComponentDependencyDeclaration.STATE_NAMES[depState]));
-                                } else {
-                                    System.out.println("    " + depName + " " + depType + " "
-                                            + ComponentDependencyDeclaration.STATE_NAMES[depState]);
-                                }
-                            }
-                            if (comp) {
-                                System.out.print(')');
-                            }
-                        }
-                    }
+        			}
                     if (comp) {
-                        System.out.println();
+                        System.out.print(')');
                     }
-                }
+    			}
+    		}
+    		if (comp) {
+                System.out.println();
             }
         }
-
-        if (stats) {
-            System.out.println("Statistics:");
-            System.out.println(" - Dependency managers: " + managers.size());
-            System.out.println(" - Components: " + numberOfComponents);
+        
+        if(stats) {
+        	System.out.println("Statistics:");
+        	System.out.println(" - Dependency managers: " + DependencyManager.getDependencyManagers().size());
+        	System.out.println(" - Components: " + numberOfComponents);
             if (!nodeps) {
                 System.out.println(" - Dependencies: " + numberOfDependencies);
             }
         }
-    }
+
+        }
 
     /**
      * Displays components callbacks (init/start/stop/destroy) elapsed time.
@@ -356,16 +362,6 @@
         }
     }
 
-    private boolean isUnavailable(ComponentDependencyDeclaration dep) {
-        switch (dep.getState()) {
-            case ComponentDependencyDeclaration.STATE_UNAVAILABLE_OPTIONAL:
-            case ComponentDependencyDeclaration.STATE_UNAVAILABLE_REQUIRED:
-                return true;
-            default:
-                return false;
-        }
-    }
-
     private boolean matchBundle(Bundle bundle, List<String> ids) {
         if (ids.size() == 0) {
             return true;
@@ -553,46 +549,68 @@
     }
 
     public void wtf() {
-        List<ComponentDeclaration> downComponents = getComponentsThatAreUnregistered();
-        if (downComponents.isEmpty()) {
-            System.out.println("No missing dependencies found.");
-        }
-        else {
-            String message = downComponents.size() + " missing dependencies found.";
+    	
+    	DependencyGraph graph = DependencyGraph.getGraph(ComponentState.UNREGISTERED, DependencyState.REQUIRED_UNAVAILABLE);
+    	List<ComponentDeclaration> unregisteredComponents = graph.getAllComponents();
+    	
+    	if(unregisteredComponents.isEmpty()) {
+    		System.out.println("No unregistered components found");
+    	} else {
+    		String message = unregisteredComponents.size() + " unregistered components found";
 			System.out.println(message);
             System.out.println("----------------------------------------------------".substring(0, message.length()));
-        }
-        listResolvedBundles();
-        listInstalledBundles();
-        Set<ComponentId> downComponentsRoot = getTheRootCouses(downComponents);
-        listAllMissingConfigurations(downComponentsRoot);
-        listAllMissingServices(downComponents, downComponentsRoot);
+    	}
+    	
+    	listResolvedBundles();
+    	listInstalledBundles();
+    	
+    	List<CircularDependency> circularDependencies = graph.getCircularDependencies();
+    	if(!circularDependencies.isEmpty()) {
+    		System.out.println("Circular dependencies:");
+    		printCircularDependencies(circularDependencies);
+    	}
+    	
+    	List<MissingDependency> missingConfigDependencies = graph.getMissingDependencies(CONFIGURATION);
+    	if(!missingConfigDependencies.isEmpty()) {
+    		System.out.println("The following configuration(s) are missing: ");
+    		printMissingDependencies(missingConfigDependencies);
+    	}
+    	
+    	List<MissingDependency> missingServiceDependencies = graph.getMissingDependencies(SERVICE);
+    	if(!missingServiceDependencies.isEmpty()) {
+    		System.out.println("The following service(s) are missing: ");
+    		printMissingDependencies(missingServiceDependencies);
+    	}
+
+    	
+    	List<MissingDependency> missingResourceDependencies = graph.getMissingDependencies(RESOURCE);
+    	if(!missingResourceDependencies.isEmpty()) {
+    		System.out.println("The following resource(s) are missing: ");
+    		printMissingDependencies(missingResourceDependencies);
+    	}
+    	
+    	List<MissingDependency> missingBundleDependencies = graph.getMissingDependencies(BUNDLE);
+    	if(!missingBundleDependencies.isEmpty()) {
+    		System.out.println("The following bundle(s) are missing: ");
+    		printMissingDependencies(missingBundleDependencies);
+    	}
     }
 
-    private Set<ComponentId> getTheRootCouses(List<ComponentDeclaration> downComponents) {
-        Set<ComponentId> downComponentsRoot = new TreeSet<ComponentId>();
-        for (ComponentDeclaration c : downComponents) {
-            List<ComponentId> root = getRoot(downComponents, c, new ArrayList<ComponentId>());
-            downComponentsRoot.addAll(root);
-        }
-        return downComponentsRoot;
-    }
+	private void printCircularDependencies(List<CircularDependency> circularDependencies) {
+		for(CircularDependency c : circularDependencies) {
+			System.out.print(" *");
+			for(ComponentDeclaration cd : c.getComponents()) {
+				System.out.print(" -> " + cd.getName());
+			}
+			System.out.println();
+		}
+	}
 
-    private List<ComponentDeclaration> getComponentsThatAreUnregistered() {
-        List<DependencyManager> dependencyManagers = DependencyManager.getDependencyManagers();
-        List<ComponentDeclaration> unregisteredComponents = new ArrayList<ComponentDeclaration>();
-        for (DependencyManager dm : dependencyManagers) {
-            List<Component> components = dm.getComponents();
-            // create a list of all components that are unregistered
-            for (Component c : components) {
-                ComponentDeclaration cd = c.getComponentDeclaration();
-                if (cd.getState() == ComponentDeclaration.STATE_UNREGISTERED) {
-                    unregisteredComponents.add(cd);
-                }
-            }
-        }
-        return unregisteredComponents;
-    }
+	private void printMissingDependencies(List<MissingDependency> missingConfigDependencies) {
+		for(MissingDependency m : missingConfigDependencies) {
+			System.out.println(" * " + m.getName() + " for bundle " + m.getBundleName());
+		}
+	}
 
     private void listResolvedBundles() {
         boolean areResolved = false;
@@ -635,150 +653,19 @@
         Dictionary<String, String> headers = b.getHeaders();
         return headers.get("Fragment-Host") != null;
     }
-
-    private void listAllMissingConfigurations(Set<ComponentId> unregisteredComponentsRoot) {
-        if (hasMissingType(unregisteredComponentsRoot, CONFIGURATION)) {
-            System.out.println("The following configuration(s) are missing: ");
-            for (ComponentId s : unregisteredComponentsRoot) {
-                if (CONFIGURATION.equals(s.getType())) {
-                    System.out.println(" * " + s.getName() + " for bundle " + s.getBundleName());
-                }
-            }
-        }
-    }
-
-    private void listAllMissingServices(List<ComponentDeclaration> downComponents, Set<ComponentId> unregisteredComponentsRoot) {
-        if (hasMissingType(unregisteredComponentsRoot, SERVICE)) {
-            System.out.println("The following service(s) are missing: ");
-            for (ComponentId s : unregisteredComponentsRoot) {
-                if (SERVICE.equals(s.getType())) {
-                    System.out.print(" * " + s.getName());
-                    ComponentDeclaration component = getComponentDeclaration(s.getName(), downComponents);
-                    if (component == null) {
-                        System.out.println(" is not found in the service registry");
-                    } else {
-                        ComponentDependencyDeclaration[] componentDependencies = component.getComponentDependencies();
-                        System.out.println(" and needs:");
-                        for (ComponentDependencyDeclaration cdd : componentDependencies) {
-                            if (cdd.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_REQUIRED) {
-                                System.out.println(cdd.getName());
-                            }
-                        }
-                        System.out.println(" to work");
-                    }
-                }
-            }
-        }
-    }
-
-    private boolean hasMissingType(Set<ComponentId> downComponentsRoot, String type) {
-        for (ComponentId s : downComponentsRoot) {
-            if (type.equals(s.getType())) {
-                return true;
-            }
-        }
-        return false;
-    }
     
-    private List<ComponentId> getRoot(List<ComponentDeclaration> downComponents, ComponentDeclaration c, List<ComponentId> backTrace) {
-        ComponentDependencyDeclaration[] componentDependencies = c.getComponentDependencies();
-        int unregisteredDeps = 0;
-        List<ComponentId> result = new ArrayList<ComponentId>();
-        for (ComponentDependencyDeclaration cdd : componentDependencies) {
-            if (cdd.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_REQUIRED) {
-                unregisteredDeps++;
-                // Detect missing configuration dependency
-                if (CONFIGURATION.equals(cdd.getType())) {
-                    String bsn = c.getBundleContext().getBundle().getSymbolicName();
-                    result.add(new ComponentId(cdd.getName(), cdd.getType(), bsn));
-                    continue;
-                }
-
-                // Detect if the missing dependency is a root cause failure
-                ComponentDeclaration component = getComponentDeclaration(cdd.getName(), downComponents);
-                if (component == null) {
-                    result.add(new ComponentId(cdd.getName(), cdd.getType(), null));
-                    continue;
-                }
-                // Detect circular dependency
-                ComponentId componentId = new ComponentId(cdd.getName(), cdd.getType(), null);
-                if (backTrace.contains(componentId)) {
-                    // We already got this one so it's a circular dependency
-                    System.out.print("Circular dependency found:\n *");
-                    for (ComponentId cid : backTrace) {
-                        System.out.print(" -> " + cid.getName() + " ");
-                    }
-                    System.out.println(" -> " + componentId.getName());
-                    result.add(new ComponentId(c.getName(), SERVICE, c.getBundleContext().getBundle().getSymbolicName()));
-                    continue;
-                }
-                backTrace.add(componentId);
-                return getRoot(downComponents, component, backTrace);
-            }
-        }
-        if (unregisteredDeps > 0 && result.isEmpty()) {
-            result.add(new ComponentId(c.getName(), SERVICE, c.getBundleContext().getBundle().getSymbolicName()));
-        }
-        return result;
-    }
-    
-    private ComponentDeclaration getComponentDeclaration(final String fullName, List<ComponentDeclaration> list) {
-        String simpleName = getSimpleName(fullName);
-        Properties props = parseProperties(fullName);
-        for (ComponentDeclaration c : list) {
-            String serviceNames = c.getName();
-            int cuttOff = serviceNames.indexOf("(");
-            if (cuttOff != -1) {
-                serviceNames = serviceNames.substring(0, cuttOff).trim();
-            }
-            for (String serviceName : serviceNames.split(",")) {
-                if (simpleName.equals(serviceName.trim()) && doPropertiesMatch(props, parseProperties(c.getName()))) {
-                    return c;
-                }
-            }
-        }
-        return null;
-    }
-    
-    private boolean doPropertiesMatch(Properties need, Properties provide) {
-        for (Entry<Object, Object> entry : need.entrySet()) {
-            Object prop = provide.get(entry.getKey());
-            if (prop == null || !prop.equals(entry.getValue())) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private String getSimpleName(String name) {
-        int cuttOff = name.indexOf("(");
-        if (cuttOff != -1) {
-            return name.substring(0, cuttOff).trim();
-        }
-        return name.trim();
-    }
-    
-    private Properties parseProperties(String name) {
-        Properties result = new Properties();
-        int cuttOff = name.indexOf("(");
-        if (cuttOff != -1) {
-            String propsText = name.substring(cuttOff + 1, name.indexOf(")"));
-            String[] split = propsText.split(",");
-            for (String prop : split) {
-                String[] kv = prop.split("=");
-                if (kv.length == 2) {
-                    result.put(kv[0], kv[1]);
-                }
-            }
-        }
-        return result;
-    }
-    
-    public static class DependencyManagerSorter implements Comparator<DependencyManager> {
-        public int compare(DependencyManager dm1, DependencyManager dm2) {
-            long id1 = dm1.getBundleContext().getBundle().getBundleId();
-            long id2 = dm2.getBundleContext().getBundle().getBundleId();
-            return id1 > id2 ? 1 : -1;
-        }
+    public static class ComponentDeclarationComparator implements Comparator<ComponentDeclaration> {
+		@Override
+		public int compare(ComponentDeclaration cd1, ComponentDeclaration cd2) {
+			long id1 = cd1.getBundleContext().getBundle().getBundleId();
+			long id2 = cd2.getBundleContext().getBundle().getBundleId();
+			if(id1 == id2) {
+				// sort by component id
+				long cid1 = cd1.getId();
+				long cid2 = cd2.getId();
+				return cid1 > cid2 ? 1 : -1;
+			} 
+			return id1 > id2 ? 1 : -1;
+		}
     }
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.shell/test/test/DMCommandTest.java b/dependencymanager/org.apache.felix.dependencymanager.shell/test/test/DMCommandTest.java
index 18d0f0e..24ea66d 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.shell/test/test/DMCommandTest.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.shell/test/test/DMCommandTest.java
@@ -70,14 +70,12 @@
         System.setErr(new PrintStream(errContent));
         dm = new DependencyManager(m_bundleContext);
         dme = new DMCommand(m_bundleContext);
-        DependencyManager.getDependencyManagers().add(dm);
     }
 
     @After
     public void cleanUp() {
         System.setOut(null);
         System.setErr(null);
-        DependencyManager.getDependencyManagers().remove(dm);
     }
 
     @Test
@@ -86,7 +84,7 @@
         setupEmptyBundles();
         
         dme.wtf();
-        assertEquals("No missing dependencies found.\n", outContent.toString());
+        assertEquals("No unregistered components found\n", outContent.toString());
     }
 
     @Test
@@ -99,7 +97,7 @@
             .setInterface(Object.class.getName(), null)
             );
         dme.wtf();
-        assertEquals("No missing dependencies found.\n", outContent.toString());
+        assertEquals("No unregistered components found\n", outContent.toString());
     }
     
     @Test
@@ -117,7 +115,7 @@
         
         dme.wtf();
         String output = outContent.toString();
-        assertTrue(output.contains("1 missing"));
+        assertTrue(output.contains("1 unregistered"));
         assertTrue(output.contains("java.lang.Math"));
         
         // remove the mess
@@ -145,8 +143,8 @@
         
         dme.wtf();
         String output = outContent.toString();
-        assertTrue(output.contains("Circular dependency found:"));
-        assertTrue(output.contains("-> java.lang.Math  -> javax.crypto.Cipher  -> java.lang.Math"));
+        assertTrue(output.contains("-> java.lang.Math -> javax.crypto.Cipher -> java.lang.Math") ||
+        		output.contains("-> javax.crypto.Cipher -> java.lang.Math -> javax.crypto.Cipher"));
         
         // remove the mess
         dm.remove(component1);
@@ -172,7 +170,7 @@
         
         dme.wtf();
         String output = outContent.toString();
-        assertTrue(output.contains("2 missing"));
+        assertTrue(output.contains("2 unregistered"));
         assertTrue(output.contains("java.lang.String"));
         
         // remove the mess
@@ -205,7 +203,7 @@
         
         dme.wtf();
         String output = outContent.toString();
-        assertTrue(output.contains("3 missing"));
+        assertTrue(output.contains("3 unregistered"));
         assertTrue(output.contains("java.lang.String"));
         assertFalse(output.contains("java.lang.Float"));
         
@@ -230,7 +228,7 @@
         
         dme.wtf();
         String output = outContent.toString();
-        assertTrue(output.contains("1 missing"));
+        assertTrue(output.contains("1 unregistered"));
         assertTrue(output.contains("java.lang.Math"));
         assertTrue(output.contains("java.lang.Long"));
         
diff --git a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd
index b42cd3c..c461405 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd
+++ b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd
@@ -24,10 +24,11 @@
 	org.apache.felix.dm.impl.index,\
 	org.apache.felix.dm.impl.index.multiproperty,\
 	org.apache.felix.dm.impl.metatype
-Export-Package: \
+Export-Package:  \
 	org.apache.felix.dm,\
 	org.apache.felix.dm.tracker,\
-	org.apache.felix.dm.context
+	org.apache.felix.dm.context,\
+	org.apache.felix.dm.diagnostics
 Include-Resource: META-INF/=resources/LICENSE,\
 	META-INF/=resources/NOTICE,\
 	META-INF/=resources/DEPENDENCIES,\
diff --git a/dependencymanager/org.apache.felix.dependencymanager/resources/changelog.txt b/dependencymanager/org.apache.felix.dependencymanager/resources/changelog.txt
index b96214a..98e76f2 100644
--- a/dependencymanager/org.apache.felix.dependencymanager/resources/changelog.txt
+++ b/dependencymanager/org.apache.felix.dependencymanager/resources/changelog.txt
@@ -10,7 +10,8 @@
     * [FELIX-4878] - Support more signatures for Dependency callbacks
     * [FELIX-4879] - ConfigurationDependency should always "need instance".
     * [FELIX-4880] - Missing callback instance support for some adapters
-
+    * [FELIX-4873] - Enhance DM API to get missing and circular dependencies
+    
 ** Wish
     * [FELIX-4875] - Update DM integration test with latest ConfigAdmin
 
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/CircularDependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/CircularDependency.java
new file mode 100644
index 0000000..8d4de08
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/CircularDependency.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.diagnostics;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.felix.dm.ComponentDeclaration;
+
+public class CircularDependency {
+	
+	private List<ComponentDeclaration> m_components = new ArrayList<>();
+	
+	void addComponent(ComponentDeclaration component) {
+		m_components.add(component);
+	}
+	
+	public List<ComponentDeclaration> getComponents() {
+		return Collections.unmodifiableList(m_components);
+	}
+	
+	@Override
+	public String toString() {
+		String result = "";
+		for(ComponentDeclaration c : m_components) {
+			result += " -> " + c.getName();
+		}
+		return result;
+	}
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/ComponentNode.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/ComponentNode.java
new file mode 100644
index 0000000..8d8fcdb
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/ComponentNode.java
@@ -0,0 +1,40 @@
+/*
+ * 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.diagnostics;
+
+import org.apache.felix.dm.ComponentDeclaration;
+
+class ComponentNode extends DependencyGraphNode {
+	
+	private ComponentDeclaration m_componentDeclaration;
+	
+	public ComponentNode(ComponentDeclaration componentDeclaration) {
+		m_componentDeclaration = componentDeclaration;
+	}
+	
+	public ComponentDeclaration getComponentDeclaration() {
+		return m_componentDeclaration;
+	}
+	
+	@Override
+	public String toString() {
+		return m_componentDeclaration.getName();
+	}
+	
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyGraph.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyGraph.java
new file mode 100644
index 0000000..5822242
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyGraph.java
@@ -0,0 +1,392 @@
+/*
+ * 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.diagnostics;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Stack;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentDeclaration;
+import org.apache.felix.dm.ComponentDependencyDeclaration;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.Bundle;
+
+/**
+ * The dependency graph is a view of all components managed by the dependency manager 
+ * and of their dependencies. Using this API you can get the dependencies of a given component,
+ * the components providing a given service, the circular dependencies that might exist. 
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class DependencyGraph {
+
+	/**
+	 * Use this to specify which components the dependency graph should contain 
+	 */
+	public enum ComponentState {
+		ALL, 
+		UNREGISTERED
+	};
+
+	/**
+	 * Use this to specify which dependencies the graph should contain
+	 */
+	public enum DependencyState {
+		ALL,
+		ALL_UNAVAILABLE,
+		REQUIRED_UNAVAILABLE
+	};
+	
+	private static final String SERVICE = "service";
+
+	private Map<ComponentDeclaration, DependencyGraphNode> m_componentToNode = new HashMap<>();
+	private Map<ComponentDependencyDeclaration, DependencyGraphNode> m_dependencyToNode = new HashMap<>();
+	private List<List<DependencyGraphNode>> m_circularDependencies = new ArrayList<>();
+	private Map<DependencyGraphNode, DependencyGraphNode> m_parent = new HashMap<>();
+	
+	private ComponentState m_componentState = ComponentState.ALL;
+	private DependencyState m_dependencyState = DependencyState.ALL; 
+	
+	private DependencyGraph(ComponentState componentState, DependencyState dependencyState) {
+		
+		m_componentState = componentState;
+		m_dependencyState = dependencyState;
+		
+		buildComponentNodes();
+		buildDependecyNodesAndEdges();
+		
+	}
+	
+	private void buildComponentNodes() {
+		List<DependencyManager> dependencyManagers = DependencyManager.getDependencyManagers();
+		for(DependencyManager dm : dependencyManagers) {
+			List<Component> components = dm.getComponents();
+			for(Component c : components) {
+				ComponentDeclaration cd = c.getComponentDeclaration();
+				if(componentMustBeAddedToGraph(cd)) {
+					m_componentToNode.put(cd, new ComponentNode(cd));
+				}
+			}
+		}
+	}
+	
+	private boolean componentMustBeAddedToGraph(ComponentDeclaration cd) {
+		if(m_componentState == ComponentState.ALL) {
+			return true;
+		} else if(m_componentState == ComponentState.UNREGISTERED) {
+			return cd.getState() == ComponentDeclaration.STATE_UNREGISTERED;
+		}
+		return false;
+	}
+
+	private void buildDependecyNodesAndEdges() {
+		
+		for(DependencyGraphNode node : m_componentToNode.values()) {
+			ComponentNode componentNode = (ComponentNode)node;
+			ComponentDependencyDeclaration[] dependencyDeclarations = componentNode.getComponentDeclaration().getComponentDependencies();
+			
+			for(ComponentDependencyDeclaration cdd : dependencyDeclarations) {
+				if(dependencyMustBeAddedToGraph(cdd)) {
+					DependencyNode dependencyNode = new DependencyNode(cdd);
+					m_dependencyToNode.put(cdd, dependencyNode);
+					
+					// add edges from the component node to newly created dependency node
+					componentNode.addSuccessor(dependencyNode);
+					
+					// add edges from the newly created dependency node to the components 
+					// providing those dependencies (only applicable to service dependencies)
+					List<ComponentNode> providerComponents = getProviderComponents(dependencyNode);
+					for(ComponentNode p : providerComponents) {
+						dependencyNode.addSuccessor(p);
+					}
+				}
+			}
+		}
+	}
+
+	private List<ComponentNode> getProviderComponents(DependencyNode dependencyNode) {
+		List<ComponentNode> result = new ArrayList<>();
+
+		ComponentDependencyDeclaration cdd = dependencyNode.getDependencyDeclaration();
+		if(!SERVICE.equals(cdd.getType())) {
+			return result;
+		}
+		
+		for(DependencyGraphNode n : m_componentToNode.values()) {
+			ComponentNode componentNode = (ComponentNode)n;
+			if(componentProvidesDependency(componentNode, dependencyNode)) {
+				result.add(componentNode);
+			}
+		}
+		
+		return result;
+	}
+
+	private boolean componentProvidesDependency(ComponentNode componentNode, DependencyNode dependencyNode) {
+		ComponentDeclaration cd = componentNode.getComponentDeclaration();
+		
+		String dependencyName = dependencyNode.getDependencyDeclaration().getName();
+		String simpleName = getSimpleName(dependencyName);
+		Properties properties = parseProperties(dependencyName);
+
+        String componentName = cd.getName();
+        int cuttOff = componentName.indexOf("(");
+        if (cuttOff != -1) {
+            componentName = componentName.substring(0, cuttOff).trim();
+        }
+        for (String serviceName : componentName.split(",")) {
+            if (simpleName.equals(serviceName.trim()) && doPropertiesMatch(properties, parseProperties(cd.getName()))) {
+                return true;
+            }
+        }
+		return false;
+	}
+
+	private boolean dependencyMustBeAddedToGraph(ComponentDependencyDeclaration cdd) {
+		if(m_dependencyState == DependencyState.ALL) {
+			return true;
+		} else if(m_dependencyState == DependencyState.ALL_UNAVAILABLE) {
+			return 
+					(cdd.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_REQUIRED) ||
+					(cdd.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_OPTIONAL);
+		} else if(m_dependencyState == DependencyState.REQUIRED_UNAVAILABLE) {
+			return cdd.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_REQUIRED;
+			
+		}
+		return false;
+	}	
+
+	/**
+	 * Build the dependency graph. It will contain all the components managed by the dependency manager, provided
+	 * that those components are in the given state, and all dependencies of their dependencies, provided that the
+	 * dependencies are in the given state.
+	 * 
+	 * <p>This implementation currently only builds a graph of unregistered components and 
+	 * required unavailable dependencies.
+	 * 
+	 * @param componentState Include only the components in this state
+	 * @param dependencyState Include only the dependencies in this state
+	 * @return
+	 */
+	public static DependencyGraph getGraph(ComponentState componentState, DependencyState dependencyState) {
+		return new DependencyGraph(componentState, dependencyState);
+	}
+	
+	/**
+	 * Returns the list of components in the graph
+	 * @return the list of components in the graph
+	 */
+	public List<ComponentDeclaration> getAllComponents() {
+		return new ArrayList<ComponentDeclaration>(m_componentToNode.keySet());
+	}
+	
+	/**
+	 * Returns a list all dependencies in the graph
+	 * @return the list of all dependencies in the graph 
+	 */
+	public List<ComponentDependencyDeclaration> getAllDependencies() {
+		return new ArrayList<ComponentDependencyDeclaration>(m_dependencyToNode.keySet());
+
+	}
+	
+	/**
+	 * For a given component declaration, it returns a list of its dependencies in the state
+	 * specified when the graph was built.
+	 * @param componentDeclaration
+	 * @return the list of dependencies or null if the component declaration is not in the graph
+	 */
+	public List<ComponentDependencyDeclaration> getDependecies(ComponentDeclaration componentDeclaration) {
+		List<ComponentDependencyDeclaration> result = new ArrayList<>();
+		
+		DependencyGraphNode node = m_componentToNode.get(componentDeclaration);
+		if(node == null) {
+			return null;
+		}
+
+		for(DependencyGraphNode s : node.getSuccessors()) {
+			result.add( ((DependencyNode)s).getDependencyDeclaration() );
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * Returns the list of components that provide the given dependency. This only returns the components
+	 * managed by the dependency manager that are in the state specified when the graph was built. The 
+	 * dependency can only be a service dependency.
+	 * 
+	 * @param dependency 
+	 * @return the list of components providing this dependency or null if the dependency declaration is 
+	 * 		   not in the graph
+	 */
+	public List<ComponentDeclaration> getProviders(ComponentDependencyDeclaration dependency) {
+		List<ComponentDeclaration> result = new ArrayList<>();
+		
+		DependencyGraphNode node = m_dependencyToNode.get(dependency);
+		if(node == null) {
+			return null;
+		}
+		
+		for(DependencyGraphNode s : node.getSuccessors()) {
+			result.add(((ComponentNode)s).getComponentDeclaration());
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * Returns the list of circular dependencies in the graph
+	 * @return the list of circular dependencies
+	 */
+	public List<CircularDependency> getCircularDependencies() {
+    	List<CircularDependency> result = new ArrayList<CircularDependency>();
+		
+		for(DependencyGraphNode n : m_componentToNode.values()) {
+			if(n.isUndiscovered()) {
+				depthFirstSearch(n);
+			}
+		}		
+		
+		for(List<DependencyGraphNode> cycle : m_circularDependencies) {
+			CircularDependency circularDependency = new CircularDependency();
+			for(DependencyGraphNode n : cycle) {
+				if(n instanceof ComponentNode) {
+					circularDependency.addComponent(((ComponentNode) n).getComponentDeclaration());
+				}
+			}
+			
+			result.add(circularDependency);
+		}
+		
+		return result;
+	}
+	
+	private void depthFirstSearch(DependencyGraphNode n) {
+
+		n.setState(DependencyGraphNode.DependencyGraphNodeState.DISCOVERED);
+		for(DependencyGraphNode s : n.getSuccessors()) {
+			if(s.isUndiscovered()) {
+				m_parent.put(s, n);
+				depthFirstSearch(s);
+			} else if(s.isDiscovered()) {
+				addCycle(n, s);
+			}
+		}
+		n.setState(DependencyGraphNode.DependencyGraphNodeState.PROCESSED);
+	}
+	
+    private void addCycle(DependencyGraphNode n, DependencyGraphNode s) {
+		List<DependencyGraphNode> cycle = new ArrayList<>();
+		Stack<DependencyGraphNode> stack = new Stack<>();
+		
+		stack.push(s);
+		for(DependencyGraphNode p = n; p != s; p = m_parent.get(p)) {
+			stack.push(p);
+		}
+		stack.push(s);
+		
+		while(!stack.isEmpty()) {
+			cycle.add(stack.pop());
+		}
+		m_circularDependencies.add(cycle);
+	}
+
+	/**
+     * Returns all the missing dependencies of a given type.
+     * @param type The type of the dependencies to be returned. This can be either one of the types 
+     * 			   known by the DependencyManager (service, bundle, configuration, resource), 
+     * 			   a user defined type or null, in which case all missing dependencies must be returned.
+     * 			   
+     * @return The missing dependencies of the given type or all the missing dependencies.
+     */
+	public List<MissingDependency> getMissingDependencies(String type) {
+		
+		List<MissingDependency> result = new ArrayList<>();
+
+		// get all dependency nodes that have no out-going edges
+		List<DependencyNode> missingDependencies = new ArrayList<>();
+		for(DependencyGraphNode node : m_dependencyToNode.values()) {
+			DependencyNode dependencyNode = (DependencyNode)node;
+			if(!dependencyNode.isUnavailable()) {
+				continue;
+			}
+			
+			if( (type != null) && (!dependencyNode.getDependencyDeclaration().getType().equals(type)) ) {
+				continue;
+			}
+			if (dependencyNode.getSuccessors().isEmpty()) {
+				missingDependencies.add(dependencyNode);
+			}
+		}
+		
+		for(DependencyNode node : missingDependencies) {
+			for(DependencyGraphNode p : node.getPredecessors()) {
+				ComponentNode componentNode = (ComponentNode)p;
+				Bundle bundle = componentNode.getComponentDeclaration().getBundleContext().getBundle();
+				MissingDependency missingDependency = new MissingDependency(
+						node.getDependencyDeclaration().getName(), 
+						node.getDependencyDeclaration().getType(), 
+						bundle.getSymbolicName());
+				result.add(missingDependency);
+			}
+		}
+		return result;
+	}
+    
+    private String getSimpleName(String name) {
+        int cuttOff = name.indexOf("(");
+        if (cuttOff != -1) {
+            return name.substring(0, cuttOff).trim();
+        }
+        return name.trim();
+    }
+    
+    private Properties parseProperties(String name) {
+        Properties result = new Properties();
+        int cuttOff = name.indexOf("(");
+        if (cuttOff != -1) {
+            String propsText = name.substring(cuttOff + 1, name.indexOf(")"));
+            String[] split = propsText.split(",");
+            for (String prop : split) {
+                String[] kv = prop.split("=");
+                if (kv.length == 2) {
+                    result.put(kv[0], kv[1]);
+                }
+            }
+        }
+        return result;
+    }
+    
+    private boolean doPropertiesMatch(Properties need, Properties provide) {
+        for (Entry<Object, Object> entry : need.entrySet()) {
+            Object prop = provide.get(entry.getKey());
+            if (prop == null || !prop.equals(entry.getValue())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyGraphNode.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyGraphNode.java
new file mode 100644
index 0000000..775cd28
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyGraphNode.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.diagnostics;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+class DependencyGraphNode {
+	
+	public enum DependencyGraphNodeState {
+		UNDISCOVERED,
+		DISCOVERED,
+		PROCESSED
+	};
+	
+	private List<DependencyGraphNode> m_successors = new ArrayList<>();
+	private List<DependencyGraphNode> m_predecessors = new ArrayList<>();
+	private DependencyGraphNodeState m_state = DependencyGraphNodeState.UNDISCOVERED;
+	
+	public void addSuccessor(DependencyGraphNode successor) {
+		m_successors.add(successor);	
+		successor.addPredecessor(this);
+	}
+	
+	private void addPredecessor(DependencyGraphNode predecessor) {
+		m_predecessors.add(predecessor);
+	}
+	
+	public List<DependencyGraphNode> getSuccessors() {
+		return Collections.unmodifiableList(m_successors);
+	}
+	
+	public List<DependencyGraphNode> getPredecessors() {
+		return Collections.unmodifiableList(m_predecessors);
+	}
+	
+	void setState(DependencyGraphNodeState state) {
+		m_state = state;
+	}
+	
+	boolean isDiscovered() {
+		return m_state == DependencyGraphNodeState.DISCOVERED;
+	}
+	
+	boolean isUndiscovered() {
+		return m_state == DependencyGraphNodeState.UNDISCOVERED;
+	}
+	
+	boolean isProcessed() {
+		return m_state == DependencyGraphNodeState.PROCESSED;
+	}
+	
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyNode.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyNode.java
new file mode 100644
index 0000000..5eab1d2
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/DependencyNode.java
@@ -0,0 +1,53 @@
+/*
+ * 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.diagnostics;
+
+import org.apache.felix.dm.ComponentDependencyDeclaration;
+
+class DependencyNode extends DependencyGraphNode {
+	
+	private ComponentDependencyDeclaration m_dependencyDeclaration;
+	
+	public DependencyNode(ComponentDependencyDeclaration dependencyDeclaration) {
+		m_dependencyDeclaration = dependencyDeclaration;
+	}
+	
+	public ComponentDependencyDeclaration getDependencyDeclaration() {
+		return m_dependencyDeclaration;
+	}
+	
+	public boolean isUnavailableRequired() {
+		return m_dependencyDeclaration.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_REQUIRED;
+	}
+	
+	public boolean isUnavailableOptional() {
+		return m_dependencyDeclaration.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_OPTIONAL;
+	}
+	
+	public boolean isUnavailable() {
+		return m_dependencyDeclaration.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_OPTIONAL
+				|| m_dependencyDeclaration.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_REQUIRED;
+	}
+	
+	@Override
+	public String toString() {
+		return m_dependencyDeclaration.getName();
+	}
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/MissingDependency.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/MissingDependency.java
new file mode 100644
index 0000000..3d872e4
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/MissingDependency.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.diagnostics;
+
+/**
+ * This represents a missing dependency. It can have any of the four types known to the Dependency Manager (service,
+ * configuration, bundle and resource) or it can be a type defined by the programmer.
+ * A missing dependency is defined by its name, its type and the bundle name of the bundle for which
+ * this dependency is unavailable.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ *
+ */
+public class MissingDependency {
+	
+	private final String name;
+	private final String type;
+	private final String bundleName;
+	
+	public MissingDependency(String name, String type, String bundleName) {
+		this.name = name;
+		this.type = type;
+		this.bundleName = bundleName;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public String getBundleName() {
+		return bundleName;
+	}
+	
+	@Override
+	public String toString() {
+		return "Missing dependency: " 
+				+ "name = " + name + " "
+				+ "type = " + type + " "
+				+ "bundleName = " + bundleName;
+	}
+
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/packageinfo b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/packageinfo
new file mode 100644
index 0000000..e252556
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/diagnostics/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
\ No newline at end of file
