diff --git a/src/main/java/kieker/analysis/TraceAnalysisConfiguration.java b/src/main/java/kieker/analysis/TraceAnalysisConfiguration.java
index e78b6a3561d27758714121ac2a4052b332ef6d1d..2624806999abdd538f8f05ceceb6ef65254fa2d0 100644
--- a/src/main/java/kieker/analysis/TraceAnalysisConfiguration.java
+++ b/src/main/java/kieker/analysis/TraceAnalysisConfiguration.java
@@ -7,25 +7,21 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
-import com.tinkerpop.blueprints.Graph;
-
-import kieker.analysis.dev.DependencyCreatorStage;
-import kieker.analysis.dev.DependencyStatisticsDecoratorStage;
 import kieker.analysis.domain.AggregatedOperationCall;
 import kieker.analysis.domain.AggregatedTrace;
 import kieker.analysis.domain.OperationCall;
 import kieker.analysis.domain.Trace;
+import kieker.analysis.graph.Graph;
+import kieker.analysis.graph.export.dot.DotFileWriterStage;
+import kieker.analysis.graph.export.graphml.GraphMLFileWriterComposite;
 import kieker.analysis.stage.tracediagnosis.AllowedRecordsFilter;
 import kieker.analysis.stage.tracediagnosis.BeginEndOfMonitoringDetector;
 import kieker.analysis.stage.tracediagnosis.OperationCallHandlerComposite;
 import kieker.analysis.stage.tracediagnosis.ReadingComposite;
 import kieker.analysis.stage.tracediagnosis.TraceAggregationComposite;
 import kieker.analysis.stage.tracediagnosis.TraceReconstructionComposite;
-import kieker.analysis.trace.graphoutput.DotGraphWriter;
-import kieker.analysis.trace.graphoutput.GraphMLWriter;
 import kieker.analysis.trace.traversal.AggrTraceTraverserStage;
 import kieker.analysis.trace.traversal.TraceTraverserStage;
-import kieker.analysis.util.graph.NamedGraph;
 import kieker.common.record.IMonitoringRecord;
 import kieker.common.record.misc.KiekerMetadataRecord;
 
@@ -78,32 +74,32 @@ public class TraceAnalysisConfiguration extends Configuration {
 		String graphFilesOutputDir = "example/event monitoring log/output"; // TODO Temp hard coded
 
 		TraceTraverserStage traceTraverserStage = new TraceTraverserStage();
-		final Distributor<NamedGraph<Graph>> graphDistributor = new Distributor<>(new CopyByReferenceStrategy());
-		GraphMLWriter graphMLWriter = new GraphMLWriter(graphFilesOutputDir);
-		DotGraphWriter dotGraphWriter = new DotGraphWriter(graphFilesOutputDir);
+		final Distributor<Graph> graphDistributor = new Distributor<>(new CopyByReferenceStrategy());
+		GraphMLFileWriterComposite graphMLFileWriterComposite = new GraphMLFileWriterComposite(graphFilesOutputDir);
+		DotFileWriterStage dotFileWriterStage = new DotFileWriterStage(graphFilesOutputDir);
 
 		super.connectPorts(distributor.getNewOutputPort(), traceTraverserStage.getInputPort());
 		super.connectPorts(traceTraverserStage.getOutputPort(), graphDistributor.getInputPort());
-		super.connectPorts(graphDistributor.getNewOutputPort(), graphMLWriter.getInputPort());
-		super.connectPorts(graphDistributor.getNewOutputPort(), dotGraphWriter.getInputPort());
+		super.connectPorts(graphDistributor.getNewOutputPort(), graphMLFileWriterComposite.getInputPort());
+		super.connectPorts(graphDistributor.getNewOutputPort(), dotFileWriterStage.getInputPort());
 
 		final Distributor<AggregatedTrace> aggregatedTraceDistributor = new Distributor<>(new CopyByReferenceStrategy());
 		AggrTraceTraverserStage aggrTraceTraverser = new AggrTraceTraverserStage();
-		final Distributor<NamedGraph<Graph>> graphDistributor2 = new Distributor<>(new CopyByReferenceStrategy());
-		GraphMLWriter graphMLWriter2 = new GraphMLWriter(graphFilesOutputDir);
-		DotGraphWriter dotGraphWriter2 = new DotGraphWriter(graphFilesOutputDir);
+		final Distributor<Graph> graphDistributor2 = new Distributor<>(new CopyByReferenceStrategy());
+		GraphMLFileWriterComposite graphMLFileWriterComposite2 = new GraphMLFileWriterComposite(graphFilesOutputDir);
+		DotFileWriterStage dotFileWriterStage2 = new DotFileWriterStage(graphFilesOutputDir);
 
 		super.connectPorts(aggregation.getOutputPort(), aggregatedTraceDistributor.getInputPort());
 
 		super.connectPorts(aggregatedTraceDistributor.getNewOutputPort(), aggrTraceTraverser.getInputPort());
 		super.connectPorts(aggrTraceTraverser.getOutputPort(), graphDistributor2.getInputPort());
-		super.connectPorts(graphDistributor2.getNewOutputPort(), graphMLWriter2.getInputPort());
-		super.connectPorts(graphDistributor2.getNewOutputPort(), dotGraphWriter2.getInputPort());
+		super.connectPorts(graphDistributor2.getNewOutputPort(), graphMLFileWriterComposite2.getInputPort());
+		super.connectPorts(graphDistributor2.getNewOutputPort(), dotFileWriterStage2.getInputPort());
 
-		DependencyCreatorStage dependencyCreatorStage = new DependencyCreatorStage();
-		DependencyStatisticsDecoratorStage dependencyStatisticsDecoratorStage = new DependencyStatisticsDecoratorStage();
-		super.connectPorts(aggregatedTraceDistributor.getNewOutputPort(), dependencyCreatorStage.getInputPort());
-		super.connectPorts(dependencyCreatorStage.getOutputPort(), dependencyStatisticsDecoratorStage.getInputPort());
+		// DependencyCreatorStage dependencyCreatorStage = new DependencyCreatorStage();
+		// DependencyStatisticsDecoratorStage dependencyStatisticsDecoratorStage = new DependencyStatisticsDecoratorStage();
+		// super.connectPorts(aggregatedTraceDistributor.getNewOutputPort(), dependencyCreatorStage.getInputPort());
+		// super.connectPorts(dependencyCreatorStage.getOutputPort(), dependencyStatisticsDecoratorStage.getInputPort());
 
 		/*
 		 *
diff --git a/src/main/java/kieker/analysis/graph/GraphTester.java b/src/main/java/kieker/analysis/graph/GraphTester.java
index 04871d1a860eda5bdb3396e256bbfc6f93b4d7cd..27b2d9e9167c8251bca210af4b7e5b8388ca8430 100644
--- a/src/main/java/kieker/analysis/graph/GraphTester.java
+++ b/src/main/java/kieker/analysis/graph/GraphTester.java
@@ -56,7 +56,20 @@ public class GraphTester {
 		Vertex node1sub1 = node1.getChildGraph().addVertex("n1::s1");
 		Vertex node1sub2 = node1.getChildGraph().addVertex("n1::s2");
 		Vertex node1sub3 = node1.getChildGraph().addVertex("n1::s3");
-		node1sub3.addEdge("wormhole", node4);
+		node1sub3.addEdge("wormhole1", node4);
+		node4.addEdge("wormhole2", node1sub3);
+
+		node1sub3.addChildGraph();
+		Vertex node1sub3sub1 = node1sub3.getChildGraph().addVertex("n1::s3::s1");
+		Vertex node1sub3sub2 = node1sub3.getChildGraph().addVertex("n1::s3::s2");
+		Vertex node1sub3sub3 = node1sub3.getChildGraph().addVertex("n1::s3::s3");
+		node1sub3sub1.addEdge("wormhole3", node4);
+		node4.addEdge("wormhole4", node1sub3sub1);
+		node1sub3sub2.addEdge(node1sub3sub3);
+
+		node1sub2.addChildGraph();
+		Vertex node1sub2sub1 = node1sub2.getChildGraph().addVertex("n1::s2::s1");
+		node1sub2sub1.addEdge("hyperwormhole", node1sub3sub1);
 
 		if (node1.hasChildGraph()) {
 			System.out.println("Node 1 has Child graph");
diff --git a/src/main/java/kieker/analysis/graph/export/dot/AbstractDotFileWriterStage.java b/src/main/java/kieker/analysis/graph/export/dot/AbstractDotFileWriterStage.java
deleted file mode 100644
index 2368b3c8e659bb06ba011365cf88ad94c029c2e6..0000000000000000000000000000000000000000
--- a/src/main/java/kieker/analysis/graph/export/dot/AbstractDotFileWriterStage.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package kieker.analysis.graph.export.dot;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-
-import kieker.analysis.graph.Graph;
-
-public abstract class AbstractDotFileWriterStage extends AbstractDotWriterStage {
-
-	public AbstractDotFileWriterStage() {
-		super();
-	}
-
-	@Override
-	protected Writer getWriter(final Graph graph) {
-		try {
-			return new FileWriter(getFileName(graph));
-		} catch (IOException e) {
-			throw new IllegalStateException(e);
-		}
-	}
-
-	protected abstract String getFileName(final Graph graph);
-
-}
diff --git a/src/main/java/kieker/analysis/graph/export/dot/AbstractDotWriterStage.java b/src/main/java/kieker/analysis/graph/export/dot/AbstractDotWriterStage.java
deleted file mode 100644
index 37a206bda28713843209036f9eb2850d6449680b..0000000000000000000000000000000000000000
--- a/src/main/java/kieker/analysis/graph/export/dot/AbstractDotWriterStage.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package kieker.analysis.graph.export.dot;
-
-import java.io.Writer;
-
-import kieker.analysis.graph.Graph;
-
-import teetime.framework.AbstractConsumerStage;
-
-public abstract class AbstractDotWriterStage extends AbstractConsumerStage<Graph> {
-
-	public AbstractDotWriterStage() {
-		super();
-	}
-
-	@Override
-	protected final void execute(final Graph graph) {
-		DotExporter dotExporter = new DotExporter(graph, getWriter(graph));
-		dotExporter.transform();
-	}
-
-	protected abstract Writer getWriter(final Graph graph);
-
-}
diff --git a/src/main/java/kieker/analysis/graph/export/dot/DotFileWriterStage.java b/src/main/java/kieker/analysis/graph/export/dot/DotFileWriterStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..e82d1432d0913f1d5892bd622e7788bd2f6fad00
--- /dev/null
+++ b/src/main/java/kieker/analysis/graph/export/dot/DotFileWriterStage.java
@@ -0,0 +1,30 @@
+package kieker.analysis.graph.export.dot;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+import kieker.analysis.graph.Graph;
+import kieker.analysis.graph.mapping.GraphMapper;
+import kieker.analysis.graph.mapping.SimpleFileNameMapper;
+
+public class DotFileWriterStage extends DotWriterStage {
+
+	public DotFileWriterStage(final GraphMapper<String> fileNameMapper) {
+		super(new GraphMapper<Writer>() {
+			@Override
+			public Writer map(final Graph graph) {
+				try {
+					return new FileWriter(fileNameMapper.map(graph));
+				} catch (IOException e) {
+					throw new IllegalArgumentException(e);
+				}
+			}
+		});
+	}
+
+	public DotFileWriterStage(final String outputDirectory) {
+		this(new SimpleFileNameMapper(outputDirectory, "dot"));
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/graph/export/dot/DotWriterStage.java b/src/main/java/kieker/analysis/graph/export/dot/DotWriterStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9e8f4470b01ca79434f59a6466818f923d27576
--- /dev/null
+++ b/src/main/java/kieker/analysis/graph/export/dot/DotWriterStage.java
@@ -0,0 +1,25 @@
+package kieker.analysis.graph.export.dot;
+
+import java.io.Writer;
+
+import kieker.analysis.graph.Graph;
+import kieker.analysis.graph.mapping.GraphMapper;
+
+import teetime.framework.AbstractConsumerStage;
+
+public class DotWriterStage extends AbstractConsumerStage<Graph> {
+
+	private final GraphMapper<Writer> writerMapper;
+
+	public DotWriterStage(final GraphMapper<Writer> writerMapper) {
+		super();
+		this.writerMapper = writerMapper;
+	}
+
+	@Override
+	protected final void execute(final Graph graph) {
+		DotExporter dotExporter = new DotExporter(graph, writerMapper.map(graph));
+		dotExporter.transform();
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/graph/export/graphml/GraphMLFileWriterComposite.java b/src/main/java/kieker/analysis/graph/export/graphml/GraphMLFileWriterComposite.java
index e91e7e73c75c795c48cac39f19f38896f85ba3b2..3c52f3199d8f1a4ac4e30e4096c0f1b69ed86070 100644
--- a/src/main/java/kieker/analysis/graph/export/graphml/GraphMLFileWriterComposite.java
+++ b/src/main/java/kieker/analysis/graph/export/graphml/GraphMLFileWriterComposite.java
@@ -6,6 +6,7 @@ import java.io.OutputStream;
 
 import kieker.analysis.graph.Graph;
 import kieker.analysis.graph.mapping.GraphMapper;
+import kieker.analysis.graph.mapping.SimpleFileNameMapper;
 
 public class GraphMLFileWriterComposite extends GraphMLWriterComposite {
 
@@ -22,4 +23,8 @@ public class GraphMLFileWriterComposite extends GraphMLWriterComposite {
 		});
 	}
 
+	public GraphMLFileWriterComposite(final String outputDirectory) {
+		this(new SimpleFileNameMapper(outputDirectory, "graphml"));
+	}
+
 }
diff --git a/src/main/java/kieker/analysis/graph/mapping/SimpleFileNameMapper.java b/src/main/java/kieker/analysis/graph/mapping/SimpleFileNameMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..066edda6435427cd24017d693c49a2b8b8d7132d
--- /dev/null
+++ b/src/main/java/kieker/analysis/graph/mapping/SimpleFileNameMapper.java
@@ -0,0 +1,27 @@
+package kieker.analysis.graph.mapping;
+
+import kieker.analysis.graph.Graph;
+
+/**
+ * This mapper maps a graph to a file name with the pattern:
+ * output directory + graph name + file extension
+ *
+ * @author Sören Henning
+ *
+ */
+public class SimpleFileNameMapper implements GraphMapper<String> {
+
+	private final String outputDirectory;
+	private final String fileExtension;
+
+	public SimpleFileNameMapper(final String outputDirectory, final String fileExtension) {
+		this.outputDirectory = outputDirectory;
+		this.fileExtension = fileExtension;
+	}
+
+	@Override
+	public String map(final Graph graph) {
+		return outputDirectory + '/' + graph.getName() + '.' + fileExtension;
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/trace/traversal/AbstractTraceToGraphTransformer.java b/src/main/java/kieker/analysis/trace/traversal/AbstractTraceToGraphTransformer.java
index 77fb05acf09022826909142f70e5857de7bfb834..4307507d205ef05537199276e50693fe95a1990a 100644
--- a/src/main/java/kieker/analysis/trace/traversal/AbstractTraceToGraphTransformer.java
+++ b/src/main/java/kieker/analysis/trace/traversal/AbstractTraceToGraphTransformer.java
@@ -1,11 +1,10 @@
 package kieker.analysis.trace.traversal;
 
-import com.tinkerpop.blueprints.Edge;
-import com.tinkerpop.blueprints.Graph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
-
 import kieker.analysis.domain.AbstractOperationCall;
+import kieker.analysis.graph.Edge;
+import kieker.analysis.graph.Graph;
+import kieker.analysis.graph.Vertex;
+import kieker.analysis.graph.impl.GraphImpl;
 
 public abstract class AbstractTraceToGraphTransformer<C extends AbstractOperationCall<C>> extends OperationCallVisitor<C> {
 
@@ -18,7 +17,7 @@ public abstract class AbstractTraceToGraphTransformer<C extends AbstractOperatio
 
 	public AbstractTraceToGraphTransformer(final C rootOperartionCall) {
 		super();
-		this.graph = new TinkerGraph();
+		this.graph = new GraphImpl();
 		this.rootOperationCall = rootOperartionCall;
 	}
 
@@ -54,7 +53,8 @@ public abstract class AbstractTraceToGraphTransformer<C extends AbstractOperatio
 
 		final Vertex rootVertex = graph.addVertex("Entry");
 		rootVertex.setProperty("label", "'Entry'");
-		graph.addEdge(null, rootVertex, realRootVertex, "1.");
+		Edge edge = graph.addEdge(null, rootVertex, realRootVertex);
+		edge.setProperty("label", "1.");
 
 	}
 
diff --git a/src/main/java/kieker/analysis/trace/traversal/AggrTraceToGraphTransformer.java b/src/main/java/kieker/analysis/trace/traversal/AggrTraceToGraphTransformer.java
index d8cae5ea43e9202f8e33404442881b22bde07164..4203ed75596eecba4221ff15181abd4abdd07d87 100644
--- a/src/main/java/kieker/analysis/trace/traversal/AggrTraceToGraphTransformer.java
+++ b/src/main/java/kieker/analysis/trace/traversal/AggrTraceToGraphTransformer.java
@@ -1,9 +1,8 @@
 package kieker.analysis.trace.traversal;
 
-import com.tinkerpop.blueprints.Edge;
-import com.tinkerpop.blueprints.Vertex;
-
 import kieker.analysis.domain.AggregatedOperationCall;
+import kieker.analysis.graph.Edge;
+import kieker.analysis.graph.Vertex;
 import kieker.analysis.util.NameConverter;
 
 public class AggrTraceToGraphTransformer extends AbstractTraceToGraphTransformer<AggregatedOperationCall> {
@@ -49,7 +48,9 @@ public class AggrTraceToGraphTransformer extends AbstractTraceToGraphTransformer
 			return null;
 		}
 
-		return graph.addEdge(null, parentVertex, thisVertex, String.valueOf(operationCall.getOrderIndex() + 1) + '.');
+		final Edge edge = graph.addEdge(null, parentVertex, thisVertex);
+		edge.setProperty("label", String.valueOf(operationCall.getOrderIndex() + 1) + '.');
+		return edge;
 	}
 
 }
diff --git a/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java b/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java
index 7d24977a6cdfaf7f1ac7e2d1fb9089bc59f10a61..52eba1aa8d7068934f657b14ef10c77ecc9fce22 100644
--- a/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java
+++ b/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java
@@ -1,14 +1,12 @@
 package kieker.analysis.trace.traversal;
 
-import com.tinkerpop.blueprints.Graph;
-
 import kieker.analysis.domain.AggregatedOperationCall;
 import kieker.analysis.domain.AggregatedTrace;
-import kieker.analysis.util.graph.NamedGraph;
+import kieker.analysis.graph.Graph;
 
 import teetime.stage.basic.AbstractTransformation;
 
-public class AggrTraceTraverserStage extends AbstractTransformation<AggregatedTrace, NamedGraph<Graph>> {
+public class AggrTraceTraverserStage extends AbstractTransformation<AggregatedTrace, Graph> {
 
 	@Override
 	protected void execute(final AggregatedTrace trace) {
@@ -21,7 +19,8 @@ public class AggrTraceTraverserStage extends AbstractTransformation<AggregatedTr
 
 		final String name = "aggr-trace-" + trace.hashCode();
 
-		final NamedGraph<Graph> graph = new NamedGraph<>(name, name, aggrTrace2Blueprint.getGraph());
+		final Graph graph = aggrTrace2Blueprint.getGraph();
+		graph.setName(name);
 
 		this.getOutputPort().send(graph);
 	}
diff --git a/src/main/java/kieker/analysis/trace/traversal/TraceToGraphTransformer.java b/src/main/java/kieker/analysis/trace/traversal/TraceToGraphTransformer.java
index e1f54798edebc5843c9cefe00ae493dae57d85dd..b139dcd48facc9a2e25bf292bbb622b6cd2ce09c 100644
--- a/src/main/java/kieker/analysis/trace/traversal/TraceToGraphTransformer.java
+++ b/src/main/java/kieker/analysis/trace/traversal/TraceToGraphTransformer.java
@@ -1,9 +1,8 @@
 package kieker.analysis.trace.traversal;
 
-import com.tinkerpop.blueprints.Edge;
-import com.tinkerpop.blueprints.Vertex;
-
 import kieker.analysis.domain.OperationCall;
+import kieker.analysis.graph.Edge;
+import kieker.analysis.graph.Vertex;
 import kieker.analysis.util.NameConverter;
 
 public class TraceToGraphTransformer extends AbstractTraceToGraphTransformer<OperationCall> {
@@ -48,7 +47,9 @@ public class TraceToGraphTransformer extends AbstractTraceToGraphTransformer<Ope
 			return null;
 		}
 
-		return graph.addEdge(null, parentVertex, thisVertex, String.valueOf(operationCall.getOrderIndex() + 1) + '.');
+		final Edge edge = graph.addEdge(null, parentVertex, thisVertex);
+		edge.setProperty("label", String.valueOf(operationCall.getOrderIndex() + 1) + '.');
+		return edge;
 	}
 
 }
diff --git a/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java b/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java
index 3212e0a0a7a2b57034ff897244e867d263bc1228..7c17e798d340ce2bd959bcacc097b136b8ccd9d2 100644
--- a/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java
+++ b/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java
@@ -1,14 +1,12 @@
 package kieker.analysis.trace.traversal;
 
-import com.tinkerpop.blueprints.Graph;
-
 import kieker.analysis.domain.OperationCall;
 import kieker.analysis.domain.Trace;
-import kieker.analysis.util.graph.NamedGraph;
+import kieker.analysis.graph.Graph;
 
 import teetime.stage.basic.AbstractTransformation;
 
-public class TraceTraverserStage extends AbstractTransformation<Trace, NamedGraph<Graph>> {
+public class TraceTraverserStage extends AbstractTransformation<Trace, Graph> {
 
 	@Override
 	protected void execute(final Trace trace) {
@@ -21,7 +19,8 @@ public class TraceTraverserStage extends AbstractTransformation<Trace, NamedGrap
 
 		final String name = "trace-" + trace.hashCode();
 
-		final NamedGraph<Graph> graph = new NamedGraph<>(name, name, traceToGraph.getGraph());
+		final Graph graph = traceToGraph.getGraph();
+		graph.setName(name);
 
 		this.getOutputPort().send(graph);
 	}