diff --git a/org.fortiss.tooling.ext.quality/META-INF/MANIFEST.MF b/org.fortiss.tooling.ext.quality/META-INF/MANIFEST.MF
index 4db8cb70af2dc664684e1c99e81c1954373993e1..8bf5ae2e6ab0d35404a355f09cf71d956992efaa 100644
--- a/org.fortiss.tooling.ext.quality/META-INF/MANIFEST.MF
+++ b/org.fortiss.tooling.ext.quality/META-INF/MANIFEST.MF
@@ -15,4 +15,5 @@ Export-Package: org.fortiss.tooling.ext.quality.service
 Import-Package: org.fortiss.af3.component.model,
  org.fortiss.af3.component.utils,
  org.fortiss.af3.project.model,
- org.fortiss.af3.project.utils
+ org.fortiss.af3.project.utils,
+ org.fortiss.af3.rcp.application
diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricCommentProvider.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricCommentProvider.java
index e7e3890936cf724c39a9125bdc28c79efab83dd7..1361afa6c7b02fb4392a090ffb351bebc6955153 100644
--- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricCommentProvider.java
+++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricCommentProvider.java
@@ -16,14 +16,23 @@
 package org.fortiss.tooling.ext.quality.service;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.emf.ecore.EObject;
+import org.fortiss.af3.component.model.InputPort;
+import org.fortiss.af3.component.model.PortSpecification;
+import org.fortiss.tooling.base.model.base.HierarchicElementBase;
+import org.fortiss.tooling.base.model.element.IConnector;
 import org.fortiss.tooling.base.model.element.IHierarchicElement;
 import org.fortiss.tooling.kernel.model.INamedCommentedElement;
 
 /**
- * {@link IMetricProvider} to count the ratio of filled out comments of INamedCommentedElements.
+ * {@link IMetricProvider} to count the ratio of filled out comments of
+ * INamedCommentedElements.
  * 
  * @author blaschke
  */
@@ -36,15 +45,287 @@ public class MetricCommentProvider implements IMetricProvider<IHierarchicElement
 	@Override
 	public List<String> apply(IHierarchicElement topComponent) {
 		extractComment(topComponent);
-		for(IHierarchicElement child : topComponent.getContainedElements()) {
+		for (IHierarchicElement child : topComponent.getContainedElements()) {
 			apply(child);
 		}
 		return strings;
 	}
 
+	public void startRecursion(IHierarchicElement topElement) {
+
+		Set<IElementConsumer> consumers = new HashSet<MetricCommentProvider.IElementConsumer>();
+		consumers.add(new PortCounter());
+		consumers.add(new ConnectionCounter());
+		consumers.add(new ElementCounter());
+		consumers.add(new CommentCompleteness());
+		consumers.add(new CloneDetection());
+
+		traverse(topElement, consumers);
+
+		consumers.forEach(c -> c.printResult());
+
+		new PortCounter().printShare((HierarchicElementBase) topElement.getContainedElements().get(0));
+	}
+
+	public void traverse(IHierarchicElement currentElement, Set<IElementConsumer> consumers) {
+
+		consumers.forEach(c -> c.apply(currentElement));
+
+		for (IHierarchicElement child : currentElement.getContainedElements()) {
+			traverse(child, consumers);
+		}
+
+	}
+
+	public interface IElementConsumer {
+
+		public void apply(IHierarchicElement element);
+
+		public void printResult();
+	}
+
+	public abstract class MultiMethodDemo implements IElementConsumer {
+
+		@Override
+		public void apply(IHierarchicElement element) {
+			if (element instanceof INamedCommentedElement) {
+				consume((INamedCommentedElement) element);
+			} else {
+				consume(element);
+			}
+		}
+
+		public abstract void consume(IHierarchicElement element);
+
+		public abstract void consume(INamedCommentedElement element);
+
+	}
+
+	public class CloneDetection implements IElementConsumer {
+
+		private Map<Integer, List<IHierarchicElement>> map = new HashMap<>();
+
+		@Override
+		public void printResult() {
+			System.out.println("Stuff");
+		}
+
+		@Override
+		public void apply(IHierarchicElement element) {
+			if (!((INamedCommentedElement) element).getName().equals("DtB")) {
+				// return;
+			}
+
+			int hash = 1;
+			for (IConnector connector : element.getConnectors()) {
+				PortSpecification port = (PortSpecification) connector.getSpecifications().get(0);
+				hash = 31 * hash
+						+ (connector instanceof InputPort ? 1 : 2) * port.getType().getClass().hashCode();
+			}
+			map.putIfAbsent(hash, new ArrayList<>());
+
+			List<IHierarchicElement> elements = map.get(hash);
+
+			for (IHierarchicElement element_b : elements) {
+
+				List<String> element_a_input = new ArrayList<String>();
+				List<String> element_b_input = new ArrayList<String>();
+				List<String> element_a_output = new ArrayList<String>();
+				List<String> element_b_output = new ArrayList<String>();
+
+				for (IConnector connector : element.getConnectors()) {
+					PortSpecification port = (PortSpecification) connector.getSpecifications().get(0);
+					String type = port.getType().getClass().getSimpleName();
+					if (connector instanceof InputPort) {
+						element_a_input.add(type);
+					} else {
+						element_a_output.add(type);
+					}
+				}
+
+				for (IConnector connector : element_b.getConnectors()) {
+					PortSpecification port = (PortSpecification) connector.getSpecifications().get(0);
+					String type = port.getType().getClass().getSimpleName();
+					if (connector instanceof InputPort) {
+						element_b_input.add(type);
+					} else {
+						element_b_output.add(type);
+					}
+				}
+
+				boolean equals = true;
+
+				for (String type_a_input : element_a_input) {
+					if (!element_b_input.remove(type_a_input)) {
+						equals = false;
+						break;
+					}
+
+				}
+
+				for (String type_a_output : element_a_output) {
+					if (!element_b_output.remove(type_a_output)) {
+						equals = false;
+						break;
+					}
+
+				}
+
+				if (equals) {
+					System.out.println("Found duplicate: "+((INamedCommentedElement)element).getName() + ", " + ((INamedCommentedElement)element_b).getName());
+					break;
+				} else {
+					System.out.println("Same but not duplicate");
+				}
+			}
+			elements.add(element);
+		}
+
+	}
+
+	public class CommentCompleteness extends MultiMethodDemo {
+
+		private int total_amount;
+		private int with_comments;
+
+		public CommentCompleteness() {
+			total_amount = 0;
+			with_comments = 0;
+		}
+
+		@Override
+		public void printResult() {
+			System.out.println("[CommentCompleteness] Total:" + total_amount + " With:" + with_comments + " Ratio:"
+					+ (with_comments / (double) total_amount));
+		}
+
+		@Override
+		public void consume(IHierarchicElement element) {
+			total_amount++;
+		}
+
+		@Override
+		public void consume(INamedCommentedElement element) {
+			if (element.getComment() != "") {
+				with_comments++;
+			}
+			total_amount++;
+		}
+
+	}
+
+	public class Tuple<T1, T2> {
+		private T1 element1;
+		private T2 element2;
+
+		public Tuple(T1 element1, T2 element2) {
+			this.element1 = element1;
+			this.element2 = element2;
+		}
+
+		public T1 getElement1() {
+			return element1;
+		}
+
+		public T2 getElement2() {
+			return element2;
+		}
+	}
+
+	public abstract class CounterConsumer implements IElementConsumer {
+
+		protected int count;
+
+		public CounterConsumer() {
+			count = 0;
+		}
+
+		@Override
+		public void printResult() {
+			System.out.println("[" + this.getClass().getSimpleName() + "] Found " + count + " total");
+		}
+
+		public int getCount() {
+			return count;
+		}
+
+		public void printShare(HierarchicElementBase element) {
+
+			Set<Tuple<String, Integer>> counts = new HashSet<>();
+			this.apply(element);
+			counts.add(new Tuple<>("[Self]" + element.getName(), count));
+			count = 0;
+
+			for (IHierarchicElement child : element.getContainedElements()) {
+
+				HierarchicElementBase real_child = (HierarchicElementBase) child;
+
+				recursiveDescent(real_child, this);
+
+				counts.add(new Tuple<>(real_child.getName(), count));
+				count = 0;
+			}
+
+			double total = counts.stream().mapToInt(t -> t.getElement2()).sum();
+
+			System.out.println("[" + this.getClass().getSimpleName() + "] shares:");
+			for (Tuple<String, Integer> tuple : counts) {
+				System.out.println("\t " + String.format("%05.2f%%", tuple.element2 / total * 100) + ", "
+						+ tuple.element2 + ": " + tuple.element1);
+			}
+		}
+
+		protected void recursiveDescent(HierarchicElementBase element, CounterConsumer consumer) {
+			consumer.apply(element);
+
+			for (IHierarchicElement child : element.getContainedElements()) {
+				HierarchicElementBase real_child = (HierarchicElementBase) child;
+
+				recursiveDescent(real_child, consumer);
+			}
+		}
+	}
+
+	public class PortCounter extends CounterConsumer {
+
+		@Override
+		public void apply(IHierarchicElement element) {
+			count += element.getConnectors().size();
+		}
+	}
+
+	public class ConnectionCounter extends CounterConsumer {
+
+		@Override
+		public void apply(IHierarchicElement element) {
+			count += element.getConnections().size();
+		}
+	}
+
+	public class ElementCounter extends CounterConsumer {
+		@Override
+		public void apply(IHierarchicElement element) {
+			count++;
+		}
+	}
+
+	public Map<String, Integer> sizeMetrics(IHierarchicElement ele) {
+		return null;
+		// anzahl elemente im baum ab hierarchiebene ele
+		// anzahl ports ab ......
+		// anzahl channels.......
+		// completness von comments #eleMitComment/#ele
+		// kamelCase names
+
+		// State Automoton
+		// Annotations
+
+		// tooling.kernel -> tooling.body -> ext packages -> af3 -> rcp
+	}
+
 	/** */
 	private void extractComment(IHierarchicElement c) {
-		strings.add(((INamedCommentedElement)c).getComment());
+		strings.add(((INamedCommentedElement) c).getComment());
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.ext.quality/test-src/test/org/fortiss/tooling/ext/quality/metric/MetricTest.java b/org.fortiss.tooling.ext.quality/test-src/test/org/fortiss/tooling/ext/quality/metric/MetricTest.java
index 174d0c3d10da6d0135e605cafb97fff10f013291..9199b9fef720cd6501c6ee2d534fd3da99f10d06 100644
--- a/org.fortiss.tooling.ext.quality/test-src/test/org/fortiss/tooling/ext/quality/metric/MetricTest.java
+++ b/org.fortiss.tooling.ext.quality/test-src/test/org/fortiss/tooling/ext/quality/metric/MetricTest.java
@@ -18,11 +18,9 @@ package test.org.fortiss.tooling.ext.quality.metric;
 import static org.fortiss.af3.component.utils.ComponentArchitectureUtils.findFirstComponentArchitecture;
 import static org.fortiss.af3.project.utils.TestCaseProjectUtils.loadTestProject;
 
-import java.util.List;
-
-import org.fortiss.af3.component.model.Component;
 import org.fortiss.af3.project.model.FileProject;
-import org.fortiss.tooling.ext.quality.AF3QualityActivator;
+import org.fortiss.af3.rcp.application.AF3ApplicationActivator;
+import org.fortiss.tooling.base.model.element.IHierarchicElement;
 import org.fortiss.tooling.ext.quality.service.MetricCommentProvider;
 import org.junit.Before;
 import org.junit.Test;
@@ -36,13 +34,17 @@ import org.junit.Test;
 public class MetricTest {
 
 	/** Top component. */
-	private Component topComponent;
+	private IHierarchicElement topComponent;
 
+	
 	/** Setup the test. */
 	@Before
 	public void setup() {
-		FileProject project = loadTestProject(AF3QualityActivator.PLUGIN_ID,
-				"test-data/StateAutomataConstraintsCheckerTestData.af3_23");
+		FileProject project = loadTestProject(AF3ApplicationActivator.PLUGIN_ID,
+				// "test-data/ACC.af3_23");
+				"test-data/carla_ff1_rover.af3_23");
+
+		// topComponent = (IHierarchicElement) project.getRootElements().get(2);
 		topComponent = findFirstComponentArchitecture(project).getTopComponent();
 	}
 
@@ -50,7 +52,7 @@ public class MetricTest {
 	@Test
 	public void actionsConstraintCheck() {
 		MetricCommentProvider mcp = new MetricCommentProvider();
-		List<String> result = mcp.apply(topComponent);
-		System.out.println(result);
+		mcp.startRecursion(topComponent);
+
 	}
 }