diff --git a/src/main/java/kieker/analysis/stage/graphoutput/DotGraphWriter.java b/src/main/java/kieker/analysis/stage/graphoutput/DotGraphWriter.java
index a12c98342c5ce63e9a5df2fe57baca219fc15994..118c137fa0cf589382257cc54541cb813abebbb9 100644
--- a/src/main/java/kieker/analysis/stage/graphoutput/DotGraphWriter.java
+++ b/src/main/java/kieker/analysis/stage/graphoutput/DotGraphWriter.java
@@ -12,11 +12,12 @@ import com.tinkerpop.blueprints.Edge;
 import com.tinkerpop.blueprints.Graph;
 import com.tinkerpop.blueprints.Vertex;
 
+import kieker.analysis.trace.traversal.NamedGraph;
 import kieker.tools.traceAnalysis.filter.visualization.util.dot.DotFactory;
 
 import teetime.framework.AbstractConsumerStage;
 
-public class DotGraphWriter extends AbstractConsumerStage<Graph> {
+public class DotGraphWriter extends AbstractConsumerStage<NamedGraph> {
 
 	private final String outputDir;
 
@@ -25,8 +26,8 @@ public class DotGraphWriter extends AbstractConsumerStage<Graph> {
 	}
 
 	@Override
-	protected void execute(final Graph graph) {
-		String dotGraph = createDotGraph(graph);
+	protected void execute(final NamedGraph graph) {
+		String dotGraph = createDotGraph(graph.getGraph());
 
 		try {
 			writeDotGraphFile(dotGraph);
diff --git a/src/main/java/kieker/analysis/stage/graphoutput/GraphBuilder.java b/src/main/java/kieker/analysis/stage/graphoutput/GraphBuilder.java
index dac7685dc5bca8f1b84846197d1ed3dd61ecf084..ebe75b99b374177169c54fbb63385f9f822dbf74 100644
--- a/src/main/java/kieker/analysis/stage/graphoutput/GraphBuilder.java
+++ b/src/main/java/kieker/analysis/stage/graphoutput/GraphBuilder.java
@@ -4,22 +4,24 @@ import com.tinkerpop.blueprints.Graph;
 import com.tinkerpop.blueprints.Vertex;
 import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
 
+import kieker.analysis.trace.traversal.NamedGraph;
 import kieker.analysis.traceanalysisdomain.AbstractOperationCall;
 import kieker.analysis.traceanalysisdomain.AbstractTrace;
 
 import teetime.stage.basic.AbstractTransformation;
 
 //TODO: really necessary to have 2 type parameters?
-public class GraphBuilder<T extends AbstractTrace<C>, C extends AbstractOperationCall<C>> extends AbstractTransformation<T, Graph> {
+public class GraphBuilder<T extends AbstractTrace<C>, C extends AbstractOperationCall<C>> extends AbstractTransformation<T, NamedGraph> {
 
 	@Override
 	protected void execute(final T trace) {
 
 		Graph graph = new TinkerGraph();
+		String graphName = String.valueOf(trace.getRootOperationCall().hashCode());
 
 		transformOperationCallsRecurive(graph, trace.getRootOperationCall(), null);
 
-		this.getOutputPort().send(graph);
+		this.getOutputPort().send(new NamedGraph(graphName, graphName, graph));
 	}
 
 	private void transformOperationCallsRecurive(final Graph graph, final C operationCall, final Vertex parentVertex) {
diff --git a/src/main/java/kieker/analysis/stage/graphoutput/GraphMLWriter.java b/src/main/java/kieker/analysis/stage/graphoutput/GraphMLWriter.java
index cf286f7ffe1e2a48eeac7d2293424d71cf449197..09f1cfb52ae72b025ae3ff1a16ae7f668de1d7fd 100644
--- a/src/main/java/kieker/analysis/stage/graphoutput/GraphMLWriter.java
+++ b/src/main/java/kieker/analysis/stage/graphoutput/GraphMLWriter.java
@@ -2,11 +2,11 @@ package kieker.analysis.stage.graphoutput;
 
 import java.io.IOException;
 
-import com.tinkerpop.blueprints.Graph;
+import kieker.analysis.trace.traversal.NamedGraph;
 
 import teetime.framework.AbstractConsumerStage;
 
-public class GraphMLWriter extends AbstractConsumerStage<Graph> {
+public class GraphMLWriter extends AbstractConsumerStage<NamedGraph> {
 
 	private final String outputDir;
 
@@ -15,18 +15,17 @@ public class GraphMLWriter extends AbstractConsumerStage<Graph> {
 	}
 
 	@Override
-	protected void execute(final Graph graph) {
+	protected void execute(final NamedGraph graph) {
 
 		String outputFile = outputDir + "/traces.xml";
 
-		com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter writer = new com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter(graph);
+		com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter writer = new com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter(graph.getGraph());
 		writer.setNormalize(true);
 
 		try {
 			writer.outputGraph(outputFile);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			throw new IllegalStateException(e);
 		}
 
 	}
diff --git a/src/main/java/kieker/analysis/stage/tracediagnosis/TraceAggregationComposite.java b/src/main/java/kieker/analysis/stage/tracediagnosis/TraceAggregationComposite.java
index c8f354799d20b942ebefc5af92336bdf1b7892e3..df478bec689e540671497a8fc80934fd5596b6b5 100644
--- a/src/main/java/kieker/analysis/stage/tracediagnosis/TraceAggregationComposite.java
+++ b/src/main/java/kieker/analysis/stage/tracediagnosis/TraceAggregationComposite.java
@@ -18,12 +18,10 @@ package kieker.analysis.stage.tracediagnosis;
 
 import java.util.List;
 
-import com.tinkerpop.blueprints.Graph;
-
 import kieker.analysis.stage.graphoutput.DotGraphWriter;
-import kieker.analysis.stage.graphoutput.GraphBuilder;
 import kieker.analysis.stage.graphoutput.GraphMLWriter;
-import kieker.analysis.traceanalysisdomain.AggregatedOperationCall;
+import kieker.analysis.trace.traversal.AggrTraceTraverserStage;
+import kieker.analysis.trace.traversal.NamedGraph;
 import kieker.analysis.traceanalysisdomain.AggregatedTrace;
 import kieker.analysis.traceanalysisdomain.Trace;
 
@@ -57,17 +55,15 @@ public final class TraceAggregationComposite extends AbstractCompositeStage {
 		String graphFilesOutputDir = "example/event monitoring log/output"; // TODO Temp hard coded
 
 		final Distributor<AggregatedTrace> distributor = new Distributor<>(new CopyByReferenceStrategy());
-		// DotGraphWriterOld<AggregatedTrace, AggregatedOperationCall> callDotGraphWriter = new DotGraphWriterOld<>(); TODO Remove
-		GraphBuilder<AggregatedTrace, AggregatedOperationCall> aggregatedTraceGraphBuilder = new GraphBuilder<>();
-		final Distributor<Graph> graphDistributor = new Distributor<>(new CopyByReferenceStrategy());
+		AggrTraceTraverserStage aggrTraceTraverser = new AggrTraceTraverserStage();
+		final Distributor<NamedGraph> graphDistributor = new Distributor<>(new CopyByReferenceStrategy());
 		GraphMLWriter graphMLWriter = new GraphMLWriter(graphFilesOutputDir);
 		DotGraphWriter dotGraphWriter = new DotGraphWriter(graphFilesOutputDir);
 
 		super.connectPorts(this.statisticsDecorator.getOutputPort(), distributor.getInputPort());
 		super.connectPorts(distributor.getNewOutputPort(), this.tracesCollector.getInputPort());
-		// super.connectPorts(distributor.getNewOutputPort(), callDotGraphWriter.getInputPort()); TODO Remove
-		super.connectPorts(distributor.getNewOutputPort(), aggregatedTraceGraphBuilder.getInputPort());
-		super.connectPorts(aggregatedTraceGraphBuilder.getOutputPort(), graphDistributor.getInputPort());
+		super.connectPorts(distributor.getNewOutputPort(), aggrTraceTraverser.getInputPort());
+		super.connectPorts(aggrTraceTraverser.getOutputPort(), graphDistributor.getInputPort());
 		super.connectPorts(graphDistributor.getNewOutputPort(), graphMLWriter.getInputPort());
 		super.connectPorts(graphDistributor.getNewOutputPort(), dotGraphWriter.getInputPort());
 
diff --git a/src/main/java/kieker/analysis/trace/traversal/AggrTrace2Blueprint.java b/src/main/java/kieker/analysis/trace/traversal/AggrTrace2Blueprint.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7a4306a14133be868a7ce535e02487ffa167c92
--- /dev/null
+++ b/src/main/java/kieker/analysis/trace/traversal/AggrTrace2Blueprint.java
@@ -0,0 +1,41 @@
+package kieker.analysis.trace.traversal;
+
+import com.tinkerpop.blueprints.Graph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
+
+import kieker.analysis.traceanalysisdomain.AggregatedOperationCall;
+
+public class AggrTrace2Blueprint extends OperationCallVisitor<AggregatedOperationCall> {
+
+	private final Graph graph;
+
+	public AggrTrace2Blueprint() {
+		super();
+		this.graph = new TinkerGraph();
+	}
+
+	@Override
+	public void visit(final AggregatedOperationCall operationCall) {
+
+		Vertex vertex = graph.addVertex(operationCall.hashCode());
+
+		vertex.setProperty("label", operationCall.getOperation());
+		// TODO maybe more properties?
+
+		AggregatedOperationCall parentCall = operationCall.getParent();
+
+		if (parentCall != null) {
+			Vertex parentVertex = graph.getVertex(operationCall.getParent().hashCode());
+			if (parentVertex != null) {
+				graph.addEdge(null, parentVertex, vertex, "");
+			}
+		}
+
+	}
+
+	public Graph getGraph() {
+		return graph;
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java b/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..61247db17cdd7ddd2e931eb723fa4f15ed43f93b
--- /dev/null
+++ b/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java
@@ -0,0 +1,26 @@
+package kieker.analysis.trace.traversal;
+
+import kieker.analysis.traceanalysisdomain.AggregatedOperationCall;
+import kieker.analysis.traceanalysisdomain.AggregatedTrace;
+
+import teetime.stage.basic.AbstractTransformation;
+
+public class AggrTraceTraverserStage extends AbstractTransformation<AggregatedTrace, NamedGraph> {
+
+	@Override
+	protected void execute(final AggregatedTrace trace) {
+
+		AggrTrace2Blueprint aggrTrace2Blueprint = new AggrTrace2Blueprint();
+
+		TraceTraverser<AggregatedTrace, AggregatedOperationCall> traverser = new TraceTraverser<>(aggrTrace2Blueprint);
+
+		traverser.traverse(trace);
+
+		String name = String.valueOf(trace.hashCode());
+
+		NamedGraph graph = new NamedGraph(name, name, aggrTrace2Blueprint.getGraph());
+
+		this.getOutputPort().send(graph);
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/trace/traversal/NamedGraph.java b/src/main/java/kieker/analysis/trace/traversal/NamedGraph.java
new file mode 100644
index 0000000000000000000000000000000000000000..8337e119e4f1dfa937e019ee7daed5dd16d53e95
--- /dev/null
+++ b/src/main/java/kieker/analysis/trace/traversal/NamedGraph.java
@@ -0,0 +1,43 @@
+package kieker.analysis.trace.traversal;
+
+import com.tinkerpop.blueprints.Graph;
+
+public class NamedGraph {
+
+	private String name;
+
+	private String fileName;
+
+	private Graph graph;
+
+	public NamedGraph(final String name, final String fileName, final Graph graph) {
+		this.name = name;
+		this.fileName = fileName;
+		this.graph = graph;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	public String getFileName() {
+		return fileName;
+	}
+
+	public void setFileName(final String fileName) {
+		this.fileName = fileName;
+	}
+
+	public Graph getGraph() {
+		return graph;
+	}
+
+	public void setGraph(final Graph graph) {
+		this.graph = graph;
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/trace/traversal/OperationCallVisitor.java b/src/main/java/kieker/analysis/trace/traversal/OperationCallVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..50864506dbef67885bf4a2d20e14a4fff36f1f6c
--- /dev/null
+++ b/src/main/java/kieker/analysis/trace/traversal/OperationCallVisitor.java
@@ -0,0 +1,9 @@
+package kieker.analysis.trace.traversal;
+
+import kieker.analysis.traceanalysisdomain.AbstractOperationCall;
+
+public abstract class OperationCallVisitor<C extends AbstractOperationCall<C>> {
+
+	public abstract void visit(C operationCall);
+
+}
diff --git a/src/main/java/kieker/analysis/trace/traversal/TraceToBlueprint.java b/src/main/java/kieker/analysis/trace/traversal/TraceToBlueprint.java
new file mode 100644
index 0000000000000000000000000000000000000000..526e3b7e90c03fc3c983bf017fba8eb5d8d07dc8
--- /dev/null
+++ b/src/main/java/kieker/analysis/trace/traversal/TraceToBlueprint.java
@@ -0,0 +1,41 @@
+package kieker.analysis.trace.traversal;
+
+import com.tinkerpop.blueprints.Graph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
+
+import kieker.analysis.traceanalysisdomain.OperationCall;
+
+public class TraceToBlueprint extends OperationCallVisitor<OperationCall> {
+
+	private final Graph graph;
+
+	public TraceToBlueprint() {
+		super();
+		this.graph = new TinkerGraph();
+	}
+
+	@Override
+	public void visit(final OperationCall operationCall) {
+
+		Vertex vertex = graph.addVertex(operationCall.hashCode());
+
+		vertex.setProperty("label", operationCall.getOperation());
+		// TODO maybe more properties?
+
+		OperationCall parentCall = operationCall.getParent();
+
+		if (parentCall != null) {
+			Vertex parentVertex = graph.getVertex(operationCall.getParent().hashCode());
+			if (parentVertex != null) {
+				graph.addEdge(null, parentVertex, vertex, "");
+			}
+		}
+
+	}
+
+	public Graph getGraph() {
+		return graph;
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/trace/traversal/TraceTraverser.java b/src/main/java/kieker/analysis/trace/traversal/TraceTraverser.java
new file mode 100644
index 0000000000000000000000000000000000000000..989f5a744a2255418dbe93740b31c55012a161e0
--- /dev/null
+++ b/src/main/java/kieker/analysis/trace/traversal/TraceTraverser.java
@@ -0,0 +1,57 @@
+package kieker.analysis.trace.traversal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import kieker.analysis.traceanalysisdomain.AbstractOperationCall;
+import kieker.analysis.traceanalysisdomain.AbstractTrace;
+
+public class TraceTraverser<T extends AbstractTrace<C>, C extends AbstractOperationCall<C>> {
+
+	private List<OperationCallVisitor<C>> visitors;
+
+	public TraceTraverser() {
+		super();
+		this.visitors = new ArrayList<>();
+	}
+
+	public TraceTraverser(final OperationCallVisitor<C> visitor) {
+		this();
+		visitors.add(visitor);
+	}
+
+	public TraceTraverser(final List<OperationCallVisitor<C>> visitors) {
+		super();
+		this.visitors = visitors;
+	}
+
+	public void traverse(final T trace) {
+		handleOperationCallsRecursively(trace.getRootOperationCall());
+	}
+
+	private void handleOperationCallsRecursively(final C operationCall) {
+		handleOperationCall(operationCall);
+		for (C childOperationCall : operationCall.getChildren()) {
+			handleOperationCallsRecursively(childOperationCall);
+		}
+	}
+
+	private void handleOperationCall(final C operationCall) {
+		for (OperationCallVisitor<C> visitor : visitors) {
+			visitor.visit(operationCall);
+		}
+	}
+
+	public List<OperationCallVisitor<C>> getVisitors() {
+		return visitors;
+	}
+
+	public void setVisitors(final List<OperationCallVisitor<C>> visitors) {
+		this.visitors = visitors;
+	}
+
+	public void addVisitor(final OperationCallVisitor<C> visitor) {
+		visitors.add(visitor);
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java b/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..950a9a04782bfbaa05c2ea78df324909c266b96b
--- /dev/null
+++ b/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java
@@ -0,0 +1,26 @@
+package kieker.analysis.trace.traversal;
+
+import kieker.analysis.traceanalysisdomain.OperationCall;
+import kieker.analysis.traceanalysisdomain.Trace;
+
+import teetime.stage.basic.AbstractTransformation;
+
+public class TraceTraverserStage extends AbstractTransformation<Trace, NamedGraph> {
+
+	@Override
+	protected void execute(final Trace trace) {
+
+		TraceToBlueprint traceToBlueprint = new TraceToBlueprint();
+
+		TraceTraverser<Trace, OperationCall> traverser = new TraceTraverser<>(traceToBlueprint);
+
+		traverser.traverse(trace);
+
+		String name = String.valueOf(trace.hashCode());
+
+		NamedGraph graph = new NamedGraph(name, name, traceToBlueprint.getGraph());
+
+		this.getOutputPort().send(graph);
+	}
+
+}