diff --git a/analysis/src/main/java/org/oceandsl/analysis/RewriteBeforeAndAfterEventsStage.java b/analysis/src/main/java/org/oceandsl/analysis/RewriteBeforeAndAfterEventsStage.java
index e1875973552581aaabcde747d30f8192cbb36118..4fbc5b0165a74e7892282cb1f3339f4bb3a2b3ba 100644
--- a/analysis/src/main/java/org/oceandsl/analysis/RewriteBeforeAndAfterEventsStage.java
+++ b/analysis/src/main/java/org/oceandsl/analysis/RewriteBeforeAndAfterEventsStage.java
@@ -1,5 +1,5 @@
 /**
- * 
+ *
  */
 package org.oceandsl.analysis;
 
@@ -24,94 +24,97 @@ import teetime.framework.OutputPort;
  *
  */
 public class RewriteBeforeAndAfterEventsStage extends AbstractConsumerStage<IMonitoringRecord> {
-	
-	private OutputPort<IMonitoringRecord> outputPort = this.createOutputPort(IMonitoringRecord.class);
-	
-	private File addrlineExecutable;
-	private Map<String,AddrOutput> addressMap = new HashMap<String,AddrOutput>();
-	private File modelExecutable;
-	
-	public RewriteBeforeAndAfterEventsStage(File addrLineExecutable, File modelExecutable) {
-		this.addrlineExecutable = addrLineExecutable;
-		this.modelExecutable = modelExecutable;
-	}
-	
-	@Override
-	protected void execute(IMonitoringRecord element) throws Exception {
-		if (element instanceof BeforeOperationEvent) {
-			BeforeOperationEvent before = (BeforeOperationEvent)element;
-			AddrOutput rewriteInfo = findRewriteInfo(before.getOperationSignature());
-			this.outputPort.send(new BeforeOperationEvent(before.getTimestamp(), before.getTraceId(), before.getOrderIndex(),
-					rewriteInfo.name,"COMPONENT"));
-		} else if (element instanceof AfterOperationEvent) {
-			AfterOperationEvent before = (AfterOperationEvent)element;
-			AddrOutput rewriteInfo = findRewriteInfo(before.getOperationSignature());
-			this.outputPort.send(new AfterOperationEvent(before.getTimestamp(), before.getTraceId(), before.getOrderIndex(),
-					rewriteInfo.name,"COMPONENT"));
-		} else
-			this.outputPort.send(element);
-	}
-	
-	private AddrOutput findRewriteInfo(String address) throws IOException, InterruptedException {
-		AddrOutput addrOutput = addressMap.get(address);
-		if (addrOutput == null) {
-			Process process = Runtime.getRuntime().exec(String.format("%s -e %s -p -C -f %s",
-					this.addrlineExecutable.getCanonicalPath(),
-					this.modelExecutable, address));
-			process.waitFor();
-			new BufferedReader(new InputStreamReader(process.getErrorStream())).lines().forEach(new Consumer<String>() {
-				@Override
-				public void accept(String arg0) {
-					System.err.println(arg0);		
-				}
-			});
-			
-			new BufferedReader(new InputStreamReader(process.getInputStream())).lines().forEach(new Consumer<String>() {
-
-				final Pattern pattern = Pattern.compile("^(\\w+) at ([\\w\\?/\\.\\-]+):([\\d\\?]*)$");
-				
-				@Override
-				public void accept(String string) {
-					Matcher matcher = this.pattern.matcher(string);
-					if (matcher.find()) {
-						Integer linenumber = matcher.group(3).equals("?")?null:Integer.parseInt(matcher.group(3));
-						addressMap.put(address,new AddrOutput(matcher.group(1), matcher.group(2), linenumber));
-					}
-				}
-				
-			});
-			return addressMap.get(address);
-		} else
-			return addrOutput;
-	}
-
-	class AddrOutput {
-
-		private final String name;
-		private final String filename;
-		private final Integer linenumber;
-		
-		public AddrOutput(String name, String filename, Integer linenumber) {
-			this.name = name;
-			this.filename = filename;
-			this.linenumber = linenumber;
-		}
-
-		public String getName() {
-			return name;
-		}
-		
-		public String getFilename() {
-			return filename;
-		}
-		
-		public Integer getLinenumber() {
-			return linenumber;
-		}
-	}
-
-	public OutputPort<IMonitoringRecord> getOutputPort() {
-		return this.outputPort;
-	}
+
+    private final OutputPort<IMonitoringRecord> outputPort = this.createOutputPort(IMonitoringRecord.class);
+
+    private final File addrlineExecutable;
+    private final Map<String, AddrOutput> addressMap = new HashMap<>();
+    private final File modelExecutable;
+
+    public RewriteBeforeAndAfterEventsStage(final File addrLineExecutable, final File modelExecutable) {
+        this.addrlineExecutable = addrLineExecutable;
+        this.modelExecutable = modelExecutable;
+    }
+
+    @Override
+    protected void execute(final IMonitoringRecord element) throws Exception {
+        if (element instanceof BeforeOperationEvent) {
+            final BeforeOperationEvent before = (BeforeOperationEvent) element;
+            final AddrOutput rewriteInfo = this.findRewriteInfo(before.getOperationSignature());
+            this.outputPort.send(new BeforeOperationEvent(before.getTimestamp(), before.getTraceId(),
+                    before.getOrderIndex(), rewriteInfo.name, rewriteInfo.getFilename()));
+        } else if (element instanceof AfterOperationEvent) {
+            final AfterOperationEvent before = (AfterOperationEvent) element;
+            final AddrOutput rewriteInfo = this.findRewriteInfo(before.getOperationSignature());
+            this.outputPort.send(new AfterOperationEvent(before.getTimestamp(), before.getTraceId(),
+                    before.getOrderIndex(), rewriteInfo.name, rewriteInfo.getFilename()));
+        } else {
+            this.outputPort.send(element);
+        }
+    }
+
+    private AddrOutput findRewriteInfo(final String address) throws IOException, InterruptedException {
+        final AddrOutput addrOutput = this.addressMap.get(address);
+        if (addrOutput == null) {
+            final Process process = Runtime.getRuntime().exec(String.format("%s -e %s -p -C -f %s",
+                    this.addrlineExecutable.getCanonicalPath(), this.modelExecutable, address));
+            process.waitFor();
+            new BufferedReader(new InputStreamReader(process.getErrorStream())).lines().forEach(new Consumer<String>() {
+                @Override
+                public void accept(final String arg0) {
+                    System.err.println(arg0);
+                }
+            });
+
+            new BufferedReader(new InputStreamReader(process.getInputStream())).lines().forEach(new Consumer<String>() {
+
+                final Pattern pattern = Pattern.compile("^(\\w+) at ([\\w\\?/\\.\\-]+):([\\d\\?]*)$");
+
+                @Override
+                public void accept(final String string) {
+                    final Matcher matcher = this.pattern.matcher(string);
+                    if (matcher.find()) {
+                        final Integer linenumber = matcher.group(3).equals("?") ? null
+                                : Integer.parseInt(matcher.group(3));
+                        RewriteBeforeAndAfterEventsStage.this.addressMap.put(address,
+                                new AddrOutput(matcher.group(1), matcher.group(2), linenumber));
+                    }
+                }
+
+            });
+            return this.addressMap.get(address);
+        } else {
+            return addrOutput;
+        }
+    }
+
+    class AddrOutput {
+
+        private final String name;
+        private final String filename;
+        private final Integer linenumber;
+
+        public AddrOutput(final String name, final String filename, final Integer linenumber) {
+            this.name = name;
+            this.filename = filename;
+            this.linenumber = linenumber;
+        }
+
+        public String getName() {
+            return this.name;
+        }
+
+        public String getFilename() {
+            return this.filename;
+        }
+
+        public Integer getLinenumber() {
+            return this.linenumber;
+        }
+    }
+
+    public OutputPort<IMonitoringRecord> getOutputPort() {
+        return this.outputPort;
+    }
 
 }
diff --git a/common/build.gradle b/common/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..e6f782cc4285e6dbfaeb8d89fa71fff883a0a708
--- /dev/null
+++ b/common/build.gradle
@@ -0,0 +1,25 @@
+/*
+ * This file was generated by the Gradle 'init' task.
+ *
+ * This generated file contains a sample Java project to get you started.
+ * For more details take a look at the Java Quickstart chapter in the Gradle
+ * User Manual available at https://docs.gradle.org/6.5/userguide/tutorial_java_projects.html
+ */
+
+plugins {
+    id 'java'
+    id 'java-library'
+}
+
+dependencies {
+    implementation 'net.kieker-monitoring:kieker:1.15-SNAPSHOT:jar' 
+}
+
+sourceSets {
+  main {
+    java { }
+  }
+  gen {
+    java { }
+  }
+}
\ No newline at end of file
diff --git a/common/src/gen/java/org/oceandsl/common/OperationCallEvent.java b/common/src/gen/java/org/oceandsl/common/OperationCallEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..96113650a5e1130a5dc67186fce8dc414bdbea94
--- /dev/null
+++ b/common/src/gen/java/org/oceandsl/common/OperationCallEvent.java
@@ -0,0 +1,209 @@
+package org.oceandsl.common;
+
+import java.nio.BufferOverflowException;
+
+import kieker.common.exception.RecordInstantiationException;
+import kieker.common.record.AbstractMonitoringRecord;
+import kieker.common.record.io.IValueDeserializer;
+import kieker.common.record.io.IValueSerializer;
+
+
+/**
+ * @author Reiner Jung
+ * API compatibility: Kieker 1.15.0
+ * 
+ * @since 1.0
+ */
+public class OperationCallEvent extends AbstractMonitoringRecord  {			
+	/** Descriptive definition of the serialization size of the record. */
+	public static final int SIZE = TYPE_SIZE_STRING // OperationCallEvent.sourceComponent
+			 + TYPE_SIZE_STRING // OperationCallEvent.sourceOperation
+			 + TYPE_SIZE_STRING // OperationCallEvent.targetComponent
+			 + TYPE_SIZE_STRING; // OperationCallEvent.targetOperation
+	
+	public static final Class<?>[] TYPES = {
+		String.class, // OperationCallEvent.sourceComponent
+		String.class, // OperationCallEvent.sourceOperation
+		String.class, // OperationCallEvent.targetComponent
+		String.class, // OperationCallEvent.targetOperation
+	};
+	
+	/** property name array. */
+	public static final String[] VALUE_NAMES = {
+		"sourceComponent",
+		"sourceOperation",
+		"targetComponent",
+		"targetOperation",
+	};
+	
+	/** default constants. */
+	public static final String SOURCE_COMPONENT = "";
+	public static final String SOURCE_OPERATION = "";
+	public static final String TARGET_COMPONENT = "";
+	public static final String TARGET_OPERATION = "";
+	private static final long serialVersionUID = -5250152168812250464L;
+	
+	/** property declarations. */
+	private final String sourceComponent;
+	private final String sourceOperation;
+	private final String targetComponent;
+	private final String targetOperation;
+	
+	/**
+	 * Creates a new instance of this class using the given parameters.
+	 * 
+	 * @param sourceComponent
+	 *            sourceComponent
+	 * @param sourceOperation
+	 *            sourceOperation
+	 * @param targetComponent
+	 *            targetComponent
+	 * @param targetOperation
+	 *            targetOperation
+	 */
+	public OperationCallEvent(final String sourceComponent, final String sourceOperation, final String targetComponent, final String targetOperation) {
+		this.sourceComponent = sourceComponent == null?"":sourceComponent;
+		this.sourceOperation = sourceOperation == null?"":sourceOperation;
+		this.targetComponent = targetComponent == null?"":targetComponent;
+		this.targetOperation = targetOperation == null?"":targetOperation;
+	}
+
+
+	/**
+	 * @param deserializer
+	 *            The deserializer to use
+	 * @throws RecordInstantiationException 
+	 *            when the record could not be deserialized
+	 */
+	public OperationCallEvent(final IValueDeserializer deserializer) throws RecordInstantiationException {
+		this.sourceComponent = deserializer.getString();
+		this.sourceOperation = deserializer.getString();
+		this.targetComponent = deserializer.getString();
+		this.targetOperation = deserializer.getString();
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void serialize(final IValueSerializer serializer) throws BufferOverflowException {
+		serializer.putString(this.getSourceComponent());
+		serializer.putString(this.getSourceOperation());
+		serializer.putString(this.getTargetComponent());
+		serializer.putString(this.getTargetOperation());
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public Class<?>[] getValueTypes() {
+		return TYPES; // NOPMD
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String[] getValueNames() {
+		return VALUE_NAMES; // NOPMD
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int getSize() {
+		return SIZE;
+	}
+
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean equals(final Object obj) {
+		if (obj == null) {
+			return false;
+		}
+		if (obj == this) {
+			return true;
+		}
+		if (obj.getClass() != this.getClass()) {
+			return false;
+		}
+		
+		final OperationCallEvent castedRecord = (OperationCallEvent) obj;
+		if (this.getLoggingTimestamp() != castedRecord.getLoggingTimestamp()) {
+			return false;
+		}
+		if (!this.getSourceComponent().equals(castedRecord.getSourceComponent())) {
+			return false;
+		}
+		if (!this.getSourceOperation().equals(castedRecord.getSourceOperation())) {
+			return false;
+		}
+		if (!this.getTargetComponent().equals(castedRecord.getTargetComponent())) {
+			return false;
+		}
+		if (!this.getTargetOperation().equals(castedRecord.getTargetOperation())) {
+			return false;
+		}
+		
+		return true;
+	}
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int hashCode() {
+		int code = 0;
+		code += this.getSourceComponent().hashCode();
+		code += this.getSourceOperation().hashCode();
+		code += this.getTargetComponent().hashCode();
+		code += this.getTargetOperation().hashCode();
+		
+		return code;
+	}
+	
+	public final String getSourceComponent() {
+		return this.sourceComponent;
+	}
+	
+	
+	public final String getSourceOperation() {
+		return this.sourceOperation;
+	}
+	
+	
+	public final String getTargetComponent() {
+		return this.targetComponent;
+	}
+	
+	
+	public final String getTargetOperation() {
+		return this.targetOperation;
+	}
+	
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		String result = "OperationCallEvent: ";
+		result += "sourceComponent = ";
+		result += this.getSourceComponent() + ", ";
+		
+		result += "sourceOperation = ";
+		result += this.getSourceOperation() + ", ";
+		
+		result += "targetComponent = ";
+		result += this.getTargetComponent() + ", ";
+		
+		result += "targetOperation = ";
+		result += this.getTargetOperation() + ", ";
+		
+		return result;
+	}
+}
diff --git a/common/src/gen/java/org/oceandsl/common/OperationCallEventFactory.java b/common/src/gen/java/org/oceandsl/common/OperationCallEventFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..276ad80e301cb66922ed6fcee657de602a674acb
--- /dev/null
+++ b/common/src/gen/java/org/oceandsl/common/OperationCallEventFactory.java
@@ -0,0 +1,35 @@
+package org.oceandsl.common;
+
+
+import kieker.common.exception.RecordInstantiationException;
+import kieker.common.record.factory.IRecordFactory;
+import kieker.common.record.io.IValueDeserializer;
+
+/**
+ * @author Reiner Jung
+ * 
+ * @since 1.0
+ */
+public final class OperationCallEventFactory implements IRecordFactory<OperationCallEvent> {
+	
+
+	@Override
+	public OperationCallEvent create(final IValueDeserializer deserializer) throws RecordInstantiationException {
+		return new OperationCallEvent(deserializer);
+	}
+
+
+	@Override
+	public String[] getValueNames() {
+		return OperationCallEvent.VALUE_NAMES; // NOPMD
+	}
+
+	@Override
+	public Class<?>[] getValueTypes() {
+		return OperationCallEvent.TYPES; // NOPMD
+	}
+
+	public int getRecordSizeInBytes() {
+		return OperationCallEvent.SIZE;
+	}
+}
diff --git a/common/src/main/java/org/oceandsl/common/common.irl b/common/src/main/java/org/oceandsl/common/common.irl
new file mode 100644
index 0000000000000000000000000000000000000000..d7d0f72f55d262db22d4e751df468be8d8a41e9e
--- /dev/null
+++ b/common/src/main/java/org/oceandsl/common/common.irl
@@ -0,0 +1,9 @@
+package org.oceandsl.common
+
+@author "Reiner Jung" @since "1.0"
+entity OperationCallEvent {
+	string sourceComponent
+	string sourceOperation
+	string targetComponent
+	string targetOperation
+}
\ No newline at end of file
diff --git a/common/src/main/java/org/oceandsl/common/package-info.java b/common/src/main/java/org/oceandsl/common/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f28e9374665cbef02a9ae6805141c5661806be4
--- /dev/null
+++ b/common/src/main/java/org/oceandsl/common/package-info.java
@@ -0,0 +1,20 @@
+/***************************************************************************
+ * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de)
+ *
+ * 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.
+ ***************************************************************************/
+/**
+ * @author reiner
+ *
+ */
+package org.oceandsl.common;
\ No newline at end of file
diff --git a/logback.groovy b/logback.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..5bf5a90c7ce6c214f71efea03fb7851130220865
--- /dev/null
+++ b/logback.groovy
@@ -0,0 +1,32 @@
+import ch.qos.logback.classic.filter.ThresholdFilter
+import ch.qos.logback.core.filter.EvaluatorFilter
+import ch.qos.logback.classic.boolex.GEventEvaluator
+
+import static ch.qos.logback.core.spi.FilterReply.DENY
+import static ch.qos.logback.core.spi.FilterReply.NEUTRAL
+
+appender("FILE", FileAppender) {
+  filter(ThresholdFilter) {
+    level=INFO
+  }
+  file = "kieker.log"
+  append = true
+  encoder(PatternLayoutEncoder) {
+    pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
+  }
+}
+
+appender("STDOUT", ConsoleAppender) {
+  filter(ThresholdFilter) {
+    level=INFO
+  }
+  encoder(PatternLayoutEncoder) {
+    pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
+  }
+  target="System.out"
+}
+
+root(DEBUG, ["STDOUT", "FILE"])
+
+
+
diff --git a/logback.xml b/logback.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e3ed73c7b561a51ae1da7deccdd8018879e138b4
--- /dev/null
+++ b/logback.xml
@@ -0,0 +1,14 @@
+<configuration>
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <!-- encoders are assigned the type
+         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+    <encoder>
+      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+    </encoder>
+  </appender>
+
+  <root level="debug">
+    <appender-ref ref="STDOUT" />
+  </root>
+</configuration>
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 39b81b8115d9365caaf28bb2e637760a793eb03b..70990e7ea9c2e14d1dfed330211fe07bf8213b9f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -9,6 +9,7 @@
 
 rootProject.name = 'oceandsl-java-tools'
 
+include 'common'
 include 'analysis'
 include 'tools:rewrite-log-entries'
 include 'tools:create-architecture-model'
diff --git a/tools/create-architecture-model/build.gradle b/tools/create-architecture-model/build.gradle
index 52ff287e06886e796e730ab941f74ef958ff28ba..f39b956b120ed072af54f4f8aa105a767a8fc8c8 100644
--- a/tools/create-architecture-model/build.gradle
+++ b/tools/create-architecture-model/build.gradle
@@ -12,9 +12,14 @@ plugins {
 }
 
 dependencies {
+    implementation project(':common')
     implementation project(':analysis')
     // https://mvnrepository.com/artifact/org.eclipse.emf/org.eclipse.emf.ecore
     implementation 'org.eclipse.emf:org.eclipse.emf.ecore:2.23.0'
+    runtime 'org.eclipse.emf:org.eclipse.emf.ecore:2.23.0'
+    
+    runtime 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3'
+    runtime 'com.sun.xml.bind:jaxb-impl:2.3.3'    
 }
 
 application {
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ArchitectureModelMain.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ArchitectureModelMain.java
index 55d5ec728b65aba2e1c76570bc33a98d07dee503..b356bb76b0f1816daf5f9119273dd5a76d208154 100644
--- a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ArchitectureModelMain.java
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ArchitectureModelMain.java
@@ -8,61 +8,80 @@ import java.io.IOException;
 
 import com.beust.jcommander.JCommander;
 
+import kieker.analysis.statistics.StatisticsModel;
+import kieker.analysisteetime.model.analysismodel.assembly.AssemblyFactory;
+import kieker.analysisteetime.model.analysismodel.assembly.AssemblyModel;
+import kieker.analysisteetime.model.analysismodel.deployment.DeploymentFactory;
+import kieker.analysisteetime.model.analysismodel.deployment.DeploymentModel;
+import kieker.analysisteetime.model.analysismodel.execution.ExecutionFactory;
+import kieker.analysisteetime.model.analysismodel.execution.ExecutionModel;
+import kieker.analysisteetime.model.analysismodel.type.TypeFactory;
+import kieker.analysisteetime.model.analysismodel.type.TypeModel;
 import kieker.common.configuration.Configuration;
 import kieker.common.exception.ConfigurationException;
 import kieker.tools.common.AbstractService;
 
-public class ArchitectureModelMain extends AbstractService<TeetimeConfiguration,ArchitectureModelSettings>{
-   
-    public static void main(String[] args) {
-    	 java.lang.System.exit(new ArchitectureModelMain().run("Kieker Log ELF Rewriter",
-    		        "log-rewriter", args, new ArchitectureModelSettings()));
+public class ArchitectureModelMain extends AbstractService<TeetimeConfiguration, ArchitectureModelSettings> {
+
+    private final TypeModel typeModel = TypeFactory.eINSTANCE.createTypeModel();
+    private final AssemblyModel assemblyModel = AssemblyFactory.eINSTANCE.createAssemblyModel();
+    private final DeploymentModel deploymentModel = DeploymentFactory.eINSTANCE.createDeploymentModel();
+    private final ExecutionModel executionModel = ExecutionFactory.eINSTANCE.createExecutionModel();
+    private final StatisticsModel statisticsModel = new StatisticsModel();
+
+    public static void main(final String[] args) {
+        final ArchitectureModelMain main = new ArchitectureModelMain();
+        final int exitCode = main.run("Kieker Log ELF Rewriter", "log-rewriter", args, new ArchitectureModelSettings());
+
+        java.lang.System.exit(exitCode);
     }
 
-	@Override
-	protected TeetimeConfiguration createTeetimeConfiguration() throws ConfigurationException {
-		try {
-			return new TeetimeConfiguration(this.parameterConfiguration);
-		} catch (IOException e) {
-			throw new ConfigurationException(e);
-		}
-	}
+    @Override
+    protected TeetimeConfiguration createTeetimeConfiguration() throws ConfigurationException {
+        try {
+            return new TeetimeConfiguration(this.parameterConfiguration, this.typeModel, this.assemblyModel,
+                    this.deploymentModel, this.executionModel, this.statisticsModel);
+        } catch (final IOException e) {
+            throw new ConfigurationException(e);
+        }
+    }
 
-	@Override
-	protected File getConfigurationFile() {
-		// we do not use a configuration file
-		return null;
-	}
+    @Override
+    protected File getConfigurationFile() {
+        // we do not use a configuration file
+        return null;
+    }
 
-	@Override
-	protected boolean checkConfiguration(Configuration configuration, JCommander commander) {
-		return true;
-	}
+    @Override
+    protected boolean checkConfiguration(final Configuration configuration, final JCommander commander) {
+        return true;
+    }
+
+    @Override
+    protected boolean checkParameters(final JCommander commander) throws ConfigurationException {
+        if (!this.parameterConfiguration.getAddrlineExecutable().canExecute()) {
+            this.logger.error("Addr2line file {} is not executable",
+                    this.parameterConfiguration.getAddrlineExecutable());
+            return false;
+        }
+        if (!this.parameterConfiguration.getModelExecutable().canExecute()) {
+            this.logger.error("Model file {} is not executable", this.parameterConfiguration.getModelExecutable());
+            return false;
+        }
+        if (!this.parameterConfiguration.getInputFile().isDirectory()) {
+            this.logger.error("Input directory {} is not directory", this.parameterConfiguration.getInputFile());
+            return false;
+        }
+        if (!this.parameterConfiguration.getOutputFile().isDirectory()) {
+            this.logger.error("Output directory {} is not directory", this.parameterConfiguration.getOutputFile());
+            return false;
+        }
+        return true;
+    }
 
-	@Override
-	protected boolean checkParameters(JCommander commander) throws ConfigurationException {
-		if (!this.parameterConfiguration.getAddrlineExecutable().canExecute()) {
-			this.logger.error("Addr2line file {} is not executable", this.parameterConfiguration.getAddrlineExecutable());
-			return false;
-		}
-		if (!this.parameterConfiguration.getModelExecutable().canExecute()) {
-			this.logger.error("Model file {} is not executable", this.parameterConfiguration.getModelExecutable());
-			return false;
-		}
-		if (!this.parameterConfiguration.getInputFile().isDirectory()) {
-			this.logger.error("Input directory {} is not directory", this.parameterConfiguration.getInputFile());
-			return false;
-		}
-		if (!this.parameterConfiguration.getOutputFile().isDirectory()) {
-			this.logger.error("Output directory {} is not directory", this.parameterConfiguration.getOutputFile());
-			return false;
-		}
-		return true;
-	}
+    @Override
+    protected void shutdownService() {
+        // TODO Auto-generated method stub
 
-	@Override
-	protected void shutdownService() {
-		// TODO Auto-generated method stub
-		
-	}
+    }
 }
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ArchitectureModelSettings.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ArchitectureModelSettings.java
index c353bc0a88d55f7a95120b1782c52bc1fedc88af..60320e058a9bdf2bce0e718e9477523c0532d30c 100644
--- a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ArchitectureModelSettings.java
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ArchitectureModelSettings.java
@@ -1,5 +1,5 @@
 /**
- * 
+ *
  */
 package org.oceandsl.architecture.model;
 
@@ -14,31 +14,43 @@ import com.beust.jcommander.converters.FileConverter;
  */
 public class ArchitectureModelSettings {
 
-	@Parameter(names = { "-i", "--input" }, required = true, converter = FileConverter.class, description = "Input Kieker log directory")
-	private File inputFile;
-
-	@Parameter(names = { "-o", "--output" }, required = true, converter = FileConverter.class, description = "Output directory where to put the graphics")
-	private File outputFile;
-	
-	@Parameter(names = { "-a", "--addrline" }, required = true, converter = FileConverter.class, description = "Location of the addrline tool")
-	private File addrlineExecutable;
-
-	@Parameter(names = { "-e", "--executable" }, required = true, converter = FileConverter.class, description = "Location of the executable")
-	private File modelExecutable;
-	
-	public File getInputFile() {
-		return this.inputFile;
-	}
-
-	public File getOutputFile() {
-		return this.outputFile;
-	}
-	
-	public File getAddrlineExecutable() {
-		return this.addrlineExecutable;
-	}
-
-	public File getModelExecutable() {
-		return this.modelExecutable;
-	}
+    @Parameter(names = { "-i",
+            "--input" }, required = true, converter = FileConverter.class, description = "Input Kieker log directory")
+    private File inputFile;
+
+    @Parameter(names = { "-o",
+            "--output" }, required = true, converter = FileConverter.class, description = "Output directory where to put the graphics")
+    private File outputFile;
+
+    @Parameter(names = { "-a",
+            "--addrline" }, required = true, converter = FileConverter.class, description = "Location of the addrline tool")
+    private File addrlineExecutable;
+
+    @Parameter(names = { "-e",
+            "--executable" }, required = true, converter = FileConverter.class, description = "Location of the executable")
+    private File modelExecutable;
+
+    @Parameter(names = { "-p",
+            "--prefix" }, required = false, description = "Path prefix to be removed from filenames in the visualization")
+    private String prefix;
+
+    public File getInputFile() {
+        return this.inputFile;
+    }
+
+    public File getOutputFile() {
+        return this.outputFile;
+    }
+
+    public File getAddrlineExecutable() {
+        return this.addrlineExecutable;
+    }
+
+    public File getModelExecutable() {
+        return this.modelExecutable;
+    }
+
+    public String getPrefix() {
+        return this.prefix;
+    }
 }
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/Call.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/Call.java
deleted file mode 100644
index 6ec8ead93fb02355e45d4f82da19e313f5c770fb..0000000000000000000000000000000000000000
--- a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/Call.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * 
- */
-package org.oceandsl.architecture.model;
-
-/**
- * @author reiner
- *
- */
-public class Call {
-
-	private final String fromClassSignature;
-	private final String fromOperationSignature;
-	private final String toClassSignature;
-	private final String toOperationSignature;
-
-	public Call(ECallType before, String fromClassSignature, String fromOperationSignature, String toClassSignature,
-			String toOperationSignature) {
-		this.fromClassSignature = fromClassSignature;
-		this.fromOperationSignature = fromOperationSignature;
-		this.toClassSignature = toClassSignature;
-		this.toOperationSignature = toOperationSignature;
-	}
-
-	public final String getFromClassSignature() {
-		return fromClassSignature;
-	}
-
-	public final String getFromOperationSignature() {
-		return fromOperationSignature;
-	}
-
-	public final String getToClassSignature() {
-		return toClassSignature;
-	}
-
-	public final String getToOperationSignature() {
-		return toOperationSignature;
-	}
-	
-	@Override
-	public boolean equals(Object object) {
-		if (object instanceof Call) {
-			Call otherCall = (Call)object;
-			return compareValues(this.fromClassSignature, otherCall.getFromClassSignature()) &&
-					compareValues(this.fromOperationSignature, otherCall.getFromOperationSignature()) &&
-					compareValues(this.toClassSignature, otherCall.getToClassSignature()) &&
-					compareValues(this.toOperationSignature, otherCall.getToOperationSignature());
-		} else
-			return false;
-	}
-	
-	private boolean compareValues(String from, String to) {
-		if (from == null && to == null)
-			return true;
-		return from != null && to != null && from.equals(to);
-	}
-
-}
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/CountUniqueCalls.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/CountUniqueCalls.java
index f819fd675d0841538acb325a82fdb90886027d08..d52c189e2fb7099e0575ae2fabac2c4bc103e382 100644
--- a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/CountUniqueCalls.java
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/CountUniqueCalls.java
@@ -3,72 +3,34 @@
  */
 package org.oceandsl.architecture.model;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.function.Function;
 
-import teetime.framework.AbstractConsumerStage;
-import teetime.framework.OutputPort;
+import kieker.analysis.statistics.StatisticsDecoratorStage;
+import kieker.analysis.statistics.StatisticsModel;
+import kieker.analysis.statistics.Units;
+import kieker.analysis.statistics.calculating.CountCalculator;
+import kieker.analysis.util.ComposedKey;
+import kieker.analysisteetime.model.analysismodel.deployment.DeployedOperation;
+import kieker.analysisteetime.model.analysismodel.execution.ExecutionModel;
 
 /**
  * @author reiner
  *
  */
-public class CountUniqueCalls extends AbstractConsumerStage<Call> {
+public class CountUniqueCalls extends StatisticsDecoratorStage<OperationCall> {
 
-    private final List<StoredCall> storedCalls = new ArrayList<>();
-    private final OutputPort<List<StoredCall>> outputPort = this.createOutputPort();
-
-    @Override
-    protected void execute(final Call element) throws Exception {
-        for (final StoredCall storedCall : this.storedCalls) {
-            if (storedCall.getCall().equals(element)) {
-                storedCall.increment();
-                return;
-            }
-        }
-        this.storedCalls.add(new StoredCall(1, element));
-    }
-
-    private void printStore() {
-        for (final StoredCall storedCall : this.storedCalls) {
-            final Call call = storedCall.getCall();
-            this.logger.info(
-                    String.format("%s:%s -> %s:%s (%d)", call.getFromClassSignature(), call.getFromOperationSignature(),
-                            call.getToClassSignature(), call.getToOperationSignature(), storedCall.getCount()));
-        }
-    }
-
-    @Override
-    protected void onTerminating() {
-        this.printStore();
-        this.outputPort.send(this.storedCalls);
-        super.onTerminating();
-    }
-
-    private class StoredCall {
-        private long count;
-        private final Call call;
-
-        public StoredCall(final long count, final Call call) {
-            this.count = count;
-            this.call = call;
-        }
-
-        public Call getCall() {
-            return this.call;
-        }
-
-        public void increment() {
-            this.count++;
-        }
-
-        public long getCount() {
-            return this.count;
-        }
+    public CountUniqueCalls(final StatisticsModel statisticsModel, final ExecutionModel executionModel) {
+        super(statisticsModel, Units.RESPONSE_TIME, new CountCalculator<>(),
+                CountUniqueCalls.createForAggregatedInvocation(executionModel));
     }
 
-    public OutputPort<List<StoredCall>> getOutputPort() {
-        return this.outputPort;
+    public static final Function<OperationCall, Object> createForAggregatedInvocation(
+            final ExecutionModel executionModel) {
+        return operationCall -> {
+            final ComposedKey<DeployedOperation, DeployedOperation> key = ComposedKey
+                    .of(operationCall.getSourceOperation(), operationCall.getTargetOperation());
+            return executionModel.getAggregatedInvocations().get(key);
+        };
     }
 
 }
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/CreateCallsStage.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/CreateCallsStage.java
index e4ee16b07e80ee27b845cc2b6b750bd7108232ef..c642fb713fb8c63b2e0743fb2109a5d44f89d8db 100644
--- a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/CreateCallsStage.java
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/CreateCallsStage.java
@@ -1,12 +1,21 @@
 /**
- * 
+ *
  */
 package org.oceandsl.architecture.model;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Stack;
 
+import kieker.analysisteetime.model.analysismodel.deployment.DeployedComponent;
+import kieker.analysisteetime.model.analysismodel.deployment.DeployedOperation;
+import kieker.analysisteetime.model.analysismodel.deployment.DeploymentContext;
+import kieker.analysisteetime.model.analysismodel.deployment.DeploymentModel;
 import kieker.common.record.flow.IFlowRecord;
+import kieker.common.record.flow.trace.TraceMetadata;
+import kieker.common.record.flow.trace.operation.AfterOperationEvent;
 import kieker.common.record.flow.trace.operation.BeforeOperationEvent;
 import teetime.framework.AbstractConsumerStage;
 import teetime.framework.OutputPort;
@@ -16,30 +25,66 @@ import teetime.framework.OutputPort;
  *
  */
 public class CreateCallsStage extends AbstractConsumerStage<IFlowRecord> {
-	
-	private final Map<Long,BeforeOperationEvent> cachedTraces = new HashMap<>();
-	private OutputPort<Call> outputPort = this.createOutputPort(Call.class);
-
-	@Override
-	protected void execute(IFlowRecord element) throws Exception {
-		if (element instanceof BeforeOperationEvent) {
-			BeforeOperationEvent currentEvent = (BeforeOperationEvent)element;
-			BeforeOperationEvent previousEvent = cachedTraces.get(currentEvent.getTraceId());
-			if (previousEvent != null) {
-				this.outputPort.send(new Call(ECallType.BEFORE, 
-						previousEvent.getClassSignature(),
-						previousEvent.getOperationSignature(),
-						currentEvent.getClassSignature(),
-						currentEvent.getOperationSignature()));
-				
-			}
-			cachedTraces.put(currentEvent.getTraceId(), currentEvent);
-		}
-	}
-	
-
-	public OutputPort<Call> getOutputPort() {
-		return outputPort;
-	}
+
+    private final Map<Long, Stack<BeforeOperationEvent>> cachedTraces = new HashMap<>();
+    private final List<TraceMetadata> traces = new ArrayList<>();
+    private final OutputPort<OperationCall> outputPort = this.createOutputPort(OperationCall.class);
+    private final DeploymentModel deploymentModel;
+
+    public CreateCallsStage(final DeploymentModel deploymentModel) {
+        this.deploymentModel = deploymentModel;
+    }
+
+    @Override
+    protected void execute(final IFlowRecord element) throws Exception {
+        if (element instanceof TraceMetadata) {
+            final TraceMetadata metadata = (TraceMetadata) element;
+            this.traces.add(metadata);
+            this.cachedTraces.put(metadata.getTraceId(), new Stack<BeforeOperationEvent>());
+        } else if (element instanceof BeforeOperationEvent) {
+            final BeforeOperationEvent currentEvent = (BeforeOperationEvent) element;
+            final Stack<BeforeOperationEvent> eventStack = this.cachedTraces.get(currentEvent.getTraceId());
+            if (eventStack.size() > 0) {
+                final BeforeOperationEvent previousEvent = eventStack.peek();
+                final DeploymentContext deploymentContext = this.deploymentModel.getDeploymentContexts()
+                        .get(this.findDeploymentContext(currentEvent));
+                final DeployedComponent sourceComponent = deploymentContext.getComponents()
+                        .get(previousEvent.getClassSignature());
+                final DeployedComponent targetComponent = deploymentContext.getComponents()
+                        .get(currentEvent.getClassSignature());
+
+                final DeployedOperation sourceOperation = sourceComponent.getContainedOperations()
+                        .get(previousEvent.getOperationSignature());
+                final DeployedOperation targetOperation = targetComponent.getContainedOperations()
+                        .get(currentEvent.getOperationSignature());
+
+                this.outputPort.send(new OperationCall(sourceOperation, targetOperation));
+            }
+            eventStack.push(currentEvent);
+        } else if (element instanceof AfterOperationEvent) {
+            final AfterOperationEvent currentEvent = (AfterOperationEvent) element;
+            final Stack<BeforeOperationEvent> eventStack = this.cachedTraces.get(currentEvent.getTraceId());
+            final BeforeOperationEvent beforeOperationEvent = eventStack.pop();
+            if (!beforeOperationEvent.getOperationSignature().equals(currentEvent.getOperationSignature())) {
+                // broken trace
+                this.logger.error("Trace is broken. Found {}, expected {}", currentEvent.getOperationSignature(),
+                        beforeOperationEvent.getOperationSignature());
+                eventStack.push(beforeOperationEvent);
+            }
+        }
+    }
+
+    private String findDeploymentContext(final BeforeOperationEvent currentEvent) {
+        for (final TraceMetadata trace : this.traces) {
+            if (trace.getTraceId() == currentEvent.getTraceId()) {
+                return trace.getHostname();
+            }
+        }
+        return "";
+    }
+
+    public OutputPort<OperationCall> getOutputPort() {
+        return this.outputPort;
+    }
 
 }
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/DedicatedFileNameMapper.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/DedicatedFileNameMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e925bda1aefdf1ac0f52816057be3891e42b8d7
--- /dev/null
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/DedicatedFileNameMapper.java
@@ -0,0 +1,35 @@
+package org.oceandsl.architecture.model;
+
+import java.util.function.Function;
+
+import kieker.analysis.graph.IGraph;
+import kieker.analysis.graph.util.FileExtension;
+
+public class DedicatedFileNameMapper implements Function<IGraph, String> {
+
+    private final String outputDirectory;
+    private final FileExtension fileExtension;
+    private final String outputFilename;
+
+    /**
+     * Create a simple file mapper.
+     *
+     * @param outputDirectory
+     *            output directory path
+     * @param outputFilename
+     *            filename
+     * @param fileExtension
+     *            file extension for the graph
+     */
+    public DedicatedFileNameMapper(final String outputDirectory, final String outputFilename,
+            final FileExtension fileExtension) {
+        this.outputDirectory = outputDirectory;
+        this.outputFilename = outputFilename;
+        this.fileExtension = fileExtension;
+    }
+
+    @Override
+    public String apply(final IGraph graph) {
+        return this.outputDirectory + '/' + this.outputFilename + "-" + graph.getName() + '.' + this.fileExtension;
+    }
+}
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/DotExportConfigurationFactory.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/DotExportConfigurationFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d0803a9bc115f34f36dbece24f618aa077b547f
--- /dev/null
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/DotExportConfigurationFactory.java
@@ -0,0 +1,296 @@
+/***************************************************************************
+ * Copyright 2020 Kieker Project (http://kieker-monitoring.net)
+ *
+ * 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.
+ ***************************************************************************/
+package org.oceandsl.architecture.model;
+
+import java.util.Collection;
+
+import kieker.analysis.graph.IElement;
+import kieker.analysis.graph.IVertex;
+import kieker.analysis.graph.dependency.PropertyConstants;
+import kieker.analysis.graph.dependency.vertextypes.IVertexTypeMapper;
+import kieker.analysis.graph.dependency.vertextypes.VertexType;
+import kieker.analysis.graph.export.dot.DotExportConfiguration;
+import kieker.analysis.graph.util.dot.attributes.DotClusterAttribute;
+import kieker.analysis.graph.util.dot.attributes.DotEdgeAttribute;
+import kieker.analysis.graph.util.dot.attributes.DotGraphAttribute;
+import kieker.analysis.graph.util.dot.attributes.DotNodeAttribute;
+import kieker.analysis.signature.NameBuilder;
+
+/**
+ * @author Sören Henning
+ *
+ * @since 1.14
+ */
+public class DotExportConfigurationFactory {
+
+    private static final String ENTRY_LABEL = "'Entry'";
+
+    private final NameBuilder nameBuilder;
+    private final IVertexTypeMapper vertexTypeMapper;
+
+    /**
+     * Uses TO_STRING of {@link kieker.analysis.graph.dependency.vertextypes.IVertexTypeMapper} as
+     * second default argument.
+     *
+     * @param nameBuilder
+     *            label for the builder
+     */
+    public DotExportConfigurationFactory(final NameBuilder nameBuilder) {
+        this(nameBuilder, IVertexTypeMapper.TO_STRING);
+    }
+
+    public DotExportConfigurationFactory(final NameBuilder nameBuilder, final IVertexTypeMapper vertexTypeMapper) {
+        this.nameBuilder = nameBuilder;
+        this.vertexTypeMapper = vertexTypeMapper;
+    }
+
+    private DotExportConfiguration.Builder createBaseBuilder() {
+        final DotExportConfiguration.Builder builder = new DotExportConfiguration.Builder();
+
+        builder.addGraphAttribute(DotGraphAttribute.RANKDIR, g -> "LR");
+        builder.addDefaultEdgeAttribute(DotEdgeAttribute.STYLE, g -> "solid");
+        builder.addDefaultEdgeAttribute(DotEdgeAttribute.ARROWHEAD, g -> "open");
+        builder.addDefaultEdgeAttribute(DotEdgeAttribute.COLOR, g -> "#000000");
+
+        builder.addDefaultNodeAttribute(DotNodeAttribute.STYLE, g -> "filled");
+        builder.addDefaultNodeAttribute(DotNodeAttribute.COLOR, g -> "#000000");
+        builder.addDefaultNodeAttribute(DotNodeAttribute.FILLCOLOR, g -> "white");
+
+        builder.addEdgeAttribute(DotEdgeAttribute.LABEL, e -> this.getProperty(e, PropertyConstants.CALLS).toString());
+
+        builder.addClusterAttribute(DotClusterAttribute.STYLE, v -> "filled");
+        builder.addClusterAttribute(DotClusterAttribute.FILLCOLOR, v -> "white");
+
+        return builder;
+    }
+
+    public DotExportConfiguration createForTypeLevelOperationDependencyGraph() {
+        final DotExportConfiguration.Builder builder = this.createBaseBuilder();
+
+        builder.addDefaultNodeAttribute(DotNodeAttribute.SHAPE, v -> "oval");
+
+        builder.addNodeAttribute(DotNodeAttribute.LABEL, v -> {
+            final VertexType type = this.getProperty(v, PropertyConstants.TYPE, VertexType.class);
+            if (type == VertexType.ENTRY) {
+                return DotExportConfigurationFactory.ENTRY_LABEL;
+            } else {
+                return new StringBuilder().append(this.createOperationLabelFromVertex(v)).append("\\n")
+                        .append(this.createStatisticsFromVertex(v)).toString();
+            }
+        });
+
+        builder.addClusterAttribute(DotClusterAttribute.LABEL, v -> this.createComponentLabelFromVertex(v).toString());
+
+        return builder.build();
+    }
+
+    public DotExportConfiguration createForTypeLevelComponentDependencyGraph() {
+        final DotExportConfiguration.Builder builder = this.createBaseBuilder();
+
+        builder.addDefaultNodeAttribute(DotNodeAttribute.SHAPE, v -> "box");
+
+        builder.addNodeAttribute(DotNodeAttribute.LABEL, v -> {
+            final VertexType type = this.getProperty(v, PropertyConstants.TYPE, VertexType.class);
+            if (type == VertexType.ENTRY) {
+                return DotExportConfigurationFactory.ENTRY_LABEL;
+            } else {
+                return new StringBuilder().append(this.createComponentLabelFromVertex(v)).append("\\n")
+                        .append(this.createStatisticsFromVertex(v)).toString();
+            }
+        });
+
+        return builder.build();
+    }
+
+    public DotExportConfiguration createForAssemblyLevelOperationDependencyGraph(final boolean vertexStatistics) {
+        final DotExportConfiguration.Builder builder = this.createBaseBuilder();
+
+        builder.addDefaultNodeAttribute(DotNodeAttribute.SHAPE, v -> "oval");
+
+        builder.addNodeAttribute(DotNodeAttribute.LABEL, v -> {
+            final VertexType type = this.getProperty(v, PropertyConstants.TYPE, VertexType.class);
+            if (type == VertexType.ENTRY) {
+                return DotExportConfigurationFactory.ENTRY_LABEL;
+            } else {
+                return new StringBuilder().append(this.createOperationLabelFromVertex(v)).append("\\n")
+                        .append(vertexStatistics ? this.createStatisticsFromVertex(v) : "").toString();
+            }
+        });
+
+        builder.addClusterAttribute(DotClusterAttribute.LABEL, v -> this.createComponentLabelFromVertex(v).toString());
+
+        return builder.build();
+    }
+
+    public DotExportConfiguration createForAssemblyLevelComponentDependencyGraph(final boolean vertexStatistics) {
+        final DotExportConfiguration.Builder builder = this.createBaseBuilder();
+
+        builder.addDefaultNodeAttribute(DotNodeAttribute.SHAPE, v -> "box");
+
+        builder.addNodeAttribute(DotNodeAttribute.LABEL, v -> {
+            final VertexType type = this.getProperty(v, PropertyConstants.TYPE, VertexType.class);
+            if (type == VertexType.ENTRY) {
+                return DotExportConfigurationFactory.ENTRY_LABEL;
+            } else {
+                return new StringBuilder().append(this.createComponentLabelFromVertex(v)).append("\\n")
+                        .append(vertexStatistics ? this.createStatisticsFromVertex(v) : "").toString();
+            }
+        });
+
+        return builder.build();
+    }
+
+    public DotExportConfiguration createForDeploymentLevelOperationDependencyGraph() {
+        final DotExportConfiguration.Builder builder = this.createBaseBuilder();
+
+        builder.addDefaultNodeAttribute(DotNodeAttribute.SHAPE, v -> "oval");
+
+        builder.addNodeAttribute(DotNodeAttribute.LABEL, v -> {
+            final VertexType type = this.getProperty(v, PropertyConstants.TYPE, VertexType.class);
+            if (type == VertexType.ENTRY) {
+                return DotExportConfigurationFactory.ENTRY_LABEL;
+            } else {
+                return new StringBuilder().append(this.createOperationLabelFromVertex(v)).append("\\n")
+                        .append(this.createStatisticsFromVertex(v)).toString();
+            }
+        });
+
+        builder.addClusterAttribute(DotClusterAttribute.LABEL, v -> {
+            final VertexType type = this.getProperty(v, PropertyConstants.TYPE, VertexType.class);
+            switch (type) {
+            case DEPLOYMENT_CONTEXT:
+                return this.createContextLabelFromVertex(v).toString();
+            case DEPLOYED_COMPONENT:
+                return this.createComponentLabelFromVertex(v).toString();
+            default:
+                throw new IllegalArgumentException(
+                        "Type '" + type.toString() + "' is not supported for this dependency graph.");
+            }
+        });
+
+        return builder.build();
+    }
+
+    public DotExportConfiguration createForDeploymentLevelComponentDependencyGraph() {
+        final DotExportConfiguration.Builder builder = this.createBaseBuilder();
+
+        builder.addDefaultNodeAttribute(DotNodeAttribute.SHAPE, v -> "box");
+
+        builder.addNodeAttribute(DotNodeAttribute.LABEL, v -> {
+            final VertexType type = this.getProperty(v, PropertyConstants.TYPE, VertexType.class);
+            if (type == VertexType.ENTRY) {
+                return DotExportConfigurationFactory.ENTRY_LABEL;
+            } else {
+                return new StringBuilder().append(this.createComponentLabelFromVertex(v)).append("\\n")
+                        .append(this.createStatisticsFromVertex(v)).toString();
+            }
+        });
+
+        builder.addClusterAttribute(DotClusterAttribute.LABEL, v -> this.createContextLabelFromVertex(v).toString());
+
+        return builder.build();
+    }
+
+    public DotExportConfiguration createForDeploymentLevelContextDependencyGraph() {
+        final DotExportConfiguration.Builder builder = this.createBaseBuilder();
+
+        builder.addDefaultNodeAttribute(DotNodeAttribute.SHAPE, v -> "box3d");
+
+        builder.addNodeAttribute(DotNodeAttribute.LABEL, v -> {
+            final VertexType type = this.getProperty(v, PropertyConstants.TYPE, VertexType.class);
+            if (type == VertexType.ENTRY) {
+                return DotExportConfigurationFactory.ENTRY_LABEL;
+            } else {
+                return this.createContextLabelFromVertex(v).toString();
+            }
+        });
+
+        return builder.build();
+    }
+
+    private StringBuilder createType(final VertexType type) {
+        return new StringBuilder().append("<<").append(this.vertexTypeMapper.apply(type)).append(">>");
+    }
+
+    private StringBuilder createOperationLabelFromVertex(final IVertex vertex) {
+        @SuppressWarnings("unchecked")
+        final Collection<String> modifiers = this.getProperty(vertex, PropertyConstants.MODIFIERS, Collection.class);
+        final String returnType = this.getProperty(vertex, PropertyConstants.RETURN_TYPE, String.class);
+        final String name = this.getProperty(vertex, PropertyConstants.NAME, String.class);
+        @SuppressWarnings("unchecked")
+        final Collection<String> parameterTypes = this.getProperty(vertex, PropertyConstants.PARAMETER_TYPES,
+                Collection.class);
+
+        return new StringBuilder(
+                this.nameBuilder.getOperationNameBuilder().build(modifiers, returnType, name, parameterTypes));
+    }
+
+    private StringBuilder createComponentLabelFromVertex(final IVertex vertex) {
+        final VertexType type = this.getProperty(vertex, PropertyConstants.TYPE, VertexType.class);
+        final String name = this.getProperty(vertex, PropertyConstants.NAME, String.class);
+        final String packageName = this.getProperty(vertex, PropertyConstants.PACKAGE_NAME, String.class);
+
+        return new StringBuilder().append(this.createType(type)).append("\\n")
+                .append(this.nameBuilder.getComponentNameBuilder().build(packageName, name));
+    }
+
+    private StringBuilder createContextLabelFromVertex(final IVertex vertex) {
+        final VertexType type = this.getProperty(vertex, PropertyConstants.TYPE, VertexType.class);
+        final String name = this.getProperty(vertex, PropertyConstants.NAME, String.class);
+
+        return new StringBuilder().append(this.createType(type)).append("\\n").append(name);
+    }
+
+    private StringBuilder createStatisticsFromVertex(final IVertex vertex) {
+        final String timeUnit = this.getProperty(vertex, PropertyConstants.TIME_UNIT).toString();
+        final String minResponseTime = this.getProperty(vertex, PropertyConstants.MIN_REPSONSE_TIME).toString();
+        final String maxResponseTime = this.getProperty(vertex, PropertyConstants.MAX_REPSONSE_TIME).toString();
+        final String totalResponseTime = this.getProperty(vertex, PropertyConstants.TOTAL_RESPONSE_TIME).toString();
+        final String meanResponseTime = this.getProperty(vertex, PropertyConstants.MEAN_REPSONSE_TIME).toString();
+        final String medianResponseTime = this.getProperty(vertex, PropertyConstants.MEDIAN_REPSONSE_TIME).toString();
+        return this.createStatistics(timeUnit, minResponseTime, maxResponseTime, totalResponseTime, meanResponseTime,
+                medianResponseTime);
+    }
+
+    private StringBuilder createStatistics(final String timeUnit, final String minResponseTime,
+            final String maxResponseTime, final String totalResponseTime, final String meanResponseTime,
+            final String medianResponseTime) {
+        return new StringBuilder().append("min: ").append(minResponseTime).append(' ').append(timeUnit).append(", ")
+                .append("max: ").append(maxResponseTime).append(' ').append(timeUnit).append(", ").append("total: ")
+                .append(totalResponseTime).append(' ').append(timeUnit).append(",\\n").append("avg: ")
+                .append(meanResponseTime).append(' ').append(timeUnit).append(", ").append("median: ")
+                .append(medianResponseTime).append(' ').append(timeUnit);
+    }
+
+    // BETTER This could be moved to the graph library
+    private Object getProperty(final IElement element, final String key) {
+        final Object object = element.getProperty(key);
+        if (object == null) {
+            throw new IllegalArgumentException("There is no key '" + key + "' for element '" + element + "'");
+        }
+        return object;
+    }
+
+    // BETTER This could be moved to the graph library
+    private <T> T getProperty(final IElement element, final String key, final Class<T> clazz) {
+        final Object object = this.getProperty(element, key);
+        if (!clazz.isInstance(object)) {
+            throw new IllegalArgumentException("Object with key '" + key + "' is not of type '" + clazz + "'");
+        }
+        return clazz.cast(object);
+    }
+
+}
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ExecutionModelGenerationStage.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ExecutionModelGenerationStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbcdb8aea70edbd7134c1a69086395cf02234f7f
--- /dev/null
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ExecutionModelGenerationStage.java
@@ -0,0 +1,44 @@
+package org.oceandsl.architecture.model;
+
+import kieker.analysis.util.ComposedKey;
+import kieker.analysisteetime.model.analysismodel.deployment.DeployedOperation;
+import kieker.analysisteetime.model.analysismodel.execution.AggregatedInvocation;
+import kieker.analysisteetime.model.analysismodel.execution.ExecutionFactory;
+import kieker.analysisteetime.model.analysismodel.execution.ExecutionModel;
+import teetime.framework.AbstractConsumerStage;
+import teetime.framework.OutputPort;
+
+public class ExecutionModelGenerationStage extends AbstractConsumerStage<OperationCall> {
+
+    private final ExecutionFactory factory = ExecutionFactory.eINSTANCE;
+
+    private final ExecutionModel executionModel;
+
+    private final OutputPort<OperationCall> outputPort = this.createOutputPort(OperationCall.class);
+
+    public ExecutionModelGenerationStage(final ExecutionModel executionModel) {
+        this.executionModel = executionModel;
+    }
+
+    @Override
+    protected void execute(final OperationCall call) throws Exception {
+        this.addExecution(call.getSourceOperation(), call.getTargetOperation());
+        this.outputPort.send(call);
+    }
+
+    protected void addExecution(final DeployedOperation source, final DeployedOperation target) {
+        final ComposedKey<DeployedOperation, DeployedOperation> key = ComposedKey.of(source, target);
+        if (!this.executionModel.getAggregatedInvocations().containsKey(key)) {
+            final AggregatedInvocation invocation = this.factory.createAggregatedInvocation();
+            invocation.setSource(source);
+            invocation.setTarget(target);
+
+            this.executionModel.getAggregatedInvocations().put(key, invocation);
+        }
+    }
+
+    public OutputPort<OperationCall> getOutputPort() {
+        return this.outputPort;
+    }
+
+}
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/OperationCall.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/OperationCall.java
new file mode 100644
index 0000000000000000000000000000000000000000..bcac547b6e94c4cfdf95afba6c024242f07365fa
--- /dev/null
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/OperationCall.java
@@ -0,0 +1,41 @@
+/**
+ *
+ */
+package org.oceandsl.architecture.model;
+
+import kieker.analysisteetime.model.analysismodel.deployment.DeployedOperation;
+
+/**
+ * @author reiner
+ *
+ */
+public class OperationCall {
+
+    private final DeployedOperation sourceOperation;
+    private final DeployedOperation targetOperation;
+
+    public OperationCall(final DeployedOperation sourceOperation, final DeployedOperation targetOperation) {
+        this.sourceOperation = sourceOperation;
+        this.targetOperation = targetOperation;
+    }
+
+    public DeployedOperation getSourceOperation() {
+        return this.sourceOperation;
+    }
+
+    public DeployedOperation getTargetOperation() {
+        return this.targetOperation;
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        if (object instanceof OperationCall) {
+            final OperationCall otherCall = (OperationCall) object;
+            return (otherCall.getSourceOperation().equals(this.getSourceOperation())
+                    && otherCall.getTargetOperation().equals(this.getTargetOperation()));
+        } else {
+            return false;
+        }
+    }
+
+}
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ProduceBeforeAndAfterEventsFromOperationCalls.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ProduceBeforeAndAfterEventsFromOperationCalls.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e8f55d2567654cfd4d3cb64febe3837607cb2ed
--- /dev/null
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/ProduceBeforeAndAfterEventsFromOperationCalls.java
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de)
+ *
+ * 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.
+ ***************************************************************************/
+package org.oceandsl.architecture.model;
+
+import org.oceandsl.common.OperationCallEvent;
+
+import kieker.common.record.IMonitoringRecord;
+import kieker.common.record.flow.IFlowRecord;
+import kieker.common.record.flow.trace.TraceMetadata;
+import kieker.common.record.flow.trace.operation.AfterOperationEvent;
+import kieker.common.record.flow.trace.operation.BeforeOperationEvent;
+import teetime.stage.basic.AbstractTransformation;
+
+/**
+ * @author reiner
+ *
+ */
+public class ProduceBeforeAndAfterEventsFromOperationCalls
+        extends AbstractTransformation<IMonitoringRecord, IFlowRecord> {
+
+    private long traceId = 1;
+    private long now = 0;
+    private final String hostname;
+
+    public ProduceBeforeAndAfterEventsFromOperationCalls(final String hostname) {
+        this.hostname = hostname;
+    }
+
+    @Override
+    protected void execute(final IMonitoringRecord element) throws Exception {
+        if (element instanceof OperationCallEvent) {
+            final OperationCallEvent operation = (OperationCallEvent) element;
+            this.outputPort.send(new TraceMetadata(this.traceId++, 0, "", this.hostname, 0, 0));
+            this.outputPort.send(new BeforeOperationEvent(this.now++, this.traceId, 0, operation.getSourceOperation(),
+                    operation.getSourceComponent()));
+            this.outputPort.send(new BeforeOperationEvent(this.now++, this.traceId, 1, operation.getTargetOperation(),
+                    operation.getTargetComponent()));
+            this.outputPort.send(new AfterOperationEvent(this.now++, this.traceId, 2, operation.getTargetOperation(),
+                    operation.getTargetComponent()));
+            this.outputPort.send(new AfterOperationEvent(this.now++, this.traceId, 3, operation.getSourceOperation(),
+                    operation.getSourceComponent()));
+        } else if (element instanceof IFlowRecord) {
+            this.outputPort.send((IFlowRecord) element);
+        }
+    }
+
+}
diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/TeetimeConfiguration.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/TeetimeConfiguration.java
index 8493fda5a9d220ad54391eedfed9c358788fc9e8..f2d59cfb20954bb11b9fe6152d17576b0de9e014 100644
--- a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/TeetimeConfiguration.java
+++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/TeetimeConfiguration.java
@@ -4,19 +4,40 @@
 package org.oceandsl.architecture.model;
 
 import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 
 import org.oceandsl.analysis.RewriteBeforeAndAfterEventsStage;
 
+import kieker.analysis.graph.IGraph;
+import kieker.analysis.graph.dependency.AssemblyLevelComponentDependencyGraphBuilderFactory;
+import kieker.analysis.graph.dependency.AssemblyLevelOperationDependencyGraphBuilderFactory;
+import kieker.analysis.graph.dependency.DependencyGraphCreatorStage;
+import kieker.analysis.graph.export.dot.DotFileWriterStage;
+import kieker.analysis.graph.export.graphml.GraphMLFileWriterStage;
+import kieker.analysis.graph.util.FileExtension;
+import kieker.analysis.model.AssemblyModelAssemblerStage;
 import kieker.analysis.model.DeploymentModelAssemblerStage;
-import kieker.analysisteetime.model.analysismodel.assembly.AssemblyFactory;
+import kieker.analysis.model.TypeModelAssemblerStage;
+import kieker.analysis.signature.IComponentSignatureExtractor;
+import kieker.analysis.signature.IOperationSignatureExtractor;
+import kieker.analysis.signature.NameBuilder;
+import kieker.analysis.statistics.StatisticsModel;
+import kieker.analysis.util.stage.trigger.Trigger;
+import kieker.analysis.util.stage.trigger.TriggerOnTerminationStage;
 import kieker.analysisteetime.model.analysismodel.assembly.AssemblyModel;
-import kieker.analysisteetime.model.analysismodel.deployment.DeploymentFactory;
 import kieker.analysisteetime.model.analysismodel.deployment.DeploymentModel;
+import kieker.analysisteetime.model.analysismodel.execution.ExecutionModel;
+import kieker.analysisteetime.model.analysismodel.type.ComponentType;
+import kieker.analysisteetime.model.analysismodel.type.OperationType;
+import kieker.analysisteetime.model.analysismodel.type.TypeModel;
 import kieker.common.record.IMonitoringRecord;
 import kieker.common.record.flow.IFlowRecord;
 import kieker.tools.source.LogsReaderCompositeStage;
 import teetime.framework.Configuration;
 import teetime.stage.InstanceOfFilter;
+import teetime.stage.basic.distributor.Distributor;
+import teetime.stage.basic.distributor.strategy.CopyByReferenceStrategy;
 
 /**
  * @author reiner
@@ -24,7 +45,9 @@ import teetime.stage.InstanceOfFilter;
  */
 public class TeetimeConfiguration extends Configuration {
 
-    public TeetimeConfiguration(final ArchitectureModelSettings parameterConfiguration) throws IOException {
+    public TeetimeConfiguration(final ArchitectureModelSettings parameterConfiguration, final TypeModel typeModel,
+            final AssemblyModel assemblyModel, final DeploymentModel deploymentModel,
+            final ExecutionModel executionModel, final StatisticsModel statisticsModel) throws IOException {
 
         final kieker.common.configuration.Configuration configuration = new kieker.common.configuration.Configuration();
         configuration.setProperty(LogsReaderCompositeStage.LOG_DIRECTORIES,
@@ -34,20 +57,102 @@ public class TeetimeConfiguration extends Configuration {
 
         final RewriteBeforeAndAfterEventsStage processor = new RewriteBeforeAndAfterEventsStage(
                 parameterConfiguration.getAddrlineExecutable(), parameterConfiguration.getModelExecutable());
+
+        final ProduceBeforeAndAfterEventsFromOperationCalls produceEvents = new ProduceBeforeAndAfterEventsFromOperationCalls(
+                "localhost");
+
         final InstanceOfFilter<IMonitoringRecord, IFlowRecord> instanceOfFilter = new InstanceOfFilter<>(
                 IFlowRecord.class);
-        // final CreateCallsStage callsStage = new CreateCallsStage();
-        // final CountUniqueCalls countStage = new CountUniqueCalls();
+
         final CountEvents<IFlowRecord> counter = new CountEvents<>(1000000);
-        final AssemblyModel assemblyModel = AssemblyFactory.eINSTANCE.createAssemblyModel();
-        final DeploymentModel deploymentModel = DeploymentFactory.eINSTANCE.createDeploymentModel();
+
+        final IComponentSignatureExtractor componentSignatureExtractor = new IComponentSignatureExtractor() {
+
+            @Override
+            public void extract(final ComponentType componentType) {
+                String signature = componentType.getSignature();
+                final String prefix = parameterConfiguration.getPrefix();
+                if (signature == null) {
+                    signature = "-- none --";
+                } else if (signature.startsWith(prefix)) {
+                    signature = signature.substring(prefix.length());
+                }
+                final Path path = Paths.get(signature);
+                final String name = path.getName(path.getNameCount() - 1).toString();
+                final String rest = (path.getParent() != null) ? path.getParent().toString() : "<<unknown>>";
+                componentType.setName(name);
+                componentType.setPackage(rest);
+            }
+        };
+        final IOperationSignatureExtractor operationSignatureExtractor = new IOperationSignatureExtractor() {
+
+            @Override
+            public void extract(final OperationType operationType) {
+                final String name = operationType.getSignature();
+                operationType.setName(name);
+                operationType.setReturnType("unknown");
+            }
+
+        };
+        final TypeModelAssemblerStage typeModelAssemblerStage = new TypeModelAssemblerStage(typeModel,
+                componentSignatureExtractor, operationSignatureExtractor);
+        final AssemblyModelAssemblerStage assemblyModelAssemblerStage = new AssemblyModelAssemblerStage(typeModel,
+                assemblyModel);
         final DeploymentModelAssemblerStage deploymentModelAssemblerStage = new DeploymentModelAssemblerStage(
                 assemblyModel, deploymentModel);
 
+        final CreateCallsStage callsStage = new CreateCallsStage(deploymentModel);
+        final ExecutionModelGenerationStage executionModelGenerationStage = new ExecutionModelGenerationStage(
+                executionModel);
+        final CountUniqueCalls countUniqueCalls = new CountUniqueCalls(statisticsModel, executionModel);
+
+        final TriggerOnTerminationStage triggerOnTerminationStage = new TriggerOnTerminationStage();
+
+        final Distributor<Trigger> distributor = new Distributor<>(new CopyByReferenceStrategy());
+
+        final DependencyGraphCreatorStage operationDependencyGraphCreatorStage = new DependencyGraphCreatorStage(
+                executionModel, statisticsModel, new AssemblyLevelOperationDependencyGraphBuilderFactory());
+        final DotFileWriterStage dotFileOperationDependencyWriterStage = new DotFileWriterStage(
+                new DedicatedFileNameMapper(parameterConfiguration.getOutputFile().getPath(), "operation",
+                        FileExtension.DOT),
+                new DotExportConfigurationFactory(NameBuilder.forJavaShortOperations())
+                        .createForAssemblyLevelOperationDependencyGraph(false));
+
+        final Distributor<IGraph> distributorGraphs = new Distributor<>(new CopyByReferenceStrategy());
+
+        final DependencyGraphCreatorStage componentDependencyGraphCreatorStage = new DependencyGraphCreatorStage(
+                executionModel, statisticsModel, new AssemblyLevelComponentDependencyGraphBuilderFactory());
+        final DotFileWriterStage dotFileComponentDependencyWriterStage = new DotFileWriterStage(
+                new DedicatedFileNameMapper(parameterConfiguration.getOutputFile().getPath(), "component",
+                        FileExtension.DOT),
+                new DotExportConfigurationFactory(NameBuilder.forJavaShortOperations())
+                        .createForAssemblyLevelComponentDependencyGraph(false));
+
+        final GraphMLFileWriterStage graphMLFileWriterStage = new GraphMLFileWriterStage(
+                parameterConfiguration.getOutputFile().getPath());
+
         this.connectPorts(reader.getOutputPort(), processor.getInputPort());
-        this.connectPorts(processor.getOutputPort(), instanceOfFilter.getInputPort());
+        this.connectPorts(processor.getOutputPort(), produceEvents.getInputPort());
+        this.connectPorts(produceEvents.getOutputPort(), instanceOfFilter.getInputPort());
         this.connectPorts(instanceOfFilter.getMatchedOutputPort(), counter.getInputPort());
-        this.connectPorts(counter.getOutputPort(), deploymentModelAssemblerStage.getInputPort());
+        this.connectPorts(counter.getOutputPort(), typeModelAssemblerStage.getInputPort());
+        this.connectPorts(typeModelAssemblerStage.getOutputPort(), assemblyModelAssemblerStage.getInputPort());
+        this.connectPorts(assemblyModelAssemblerStage.getOutputPort(), deploymentModelAssemblerStage.getInputPort());
+        this.connectPorts(deploymentModelAssemblerStage.getOutputPort(), callsStage.getInputPort());
+        this.connectPorts(callsStage.getOutputPort(), executionModelGenerationStage.getInputPort());
+        this.connectPorts(executionModelGenerationStage.getOutputPort(), countUniqueCalls.getInputPort());
+        this.connectPorts(countUniqueCalls.getOutputPort(), triggerOnTerminationStage.getInputPort());
+        this.connectPorts(triggerOnTerminationStage.getOutputPort(), distributor.getInputPort());
+
+        this.connectPorts(distributor.getNewOutputPort(), operationDependencyGraphCreatorStage.getInputPort());
+        this.connectPorts(distributor.getNewOutputPort(), componentDependencyGraphCreatorStage.getInputPort());
+
+        this.connectPorts(operationDependencyGraphCreatorStage.getOutputPort(), distributorGraphs.getInputPort());
+        this.connectPorts(distributorGraphs.getNewOutputPort(), dotFileOperationDependencyWriterStage.getInputPort());
+        this.connectPorts(distributorGraphs.getNewOutputPort(), graphMLFileWriterStage.getInputPort());
+
+        this.connectPorts(componentDependencyGraphCreatorStage.getOutputPort(),
+                dotFileComponentDependencyWriterStage.getInputPort());
 
     }
 }