diff --git a/.settings/edu.umd.cs.findbugs.core.prefs b/.settings/edu.umd.cs.findbugs.core.prefs
index 5ce4d272957809afd699ae2bca04931cfbfc3849..0e7e100572c6fde0d34a0a1848a59dafc8989de9 100644
--- a/.settings/edu.umd.cs.findbugs.core.prefs
+++ b/.settings/edu.umd.cs.findbugs.core.prefs
@@ -1,5 +1,5 @@
 #FindBugs User Preferences
-#Wed Dec 17 09:02:35 CET 2014
+#Wed Dec 17 15:04:09 CET 2014
 detector_threshold=3
 effort=max
 excludefilter0=.fbExcludeFilterFile|true
diff --git a/run-configurations/ComparisonMethodcallWithPorts.launch b/run-configurations/ComparisonMethodcallWithPorts.launch
index c5391996699e84d0ac1ab95bb6495293d3efdb62..af42b657fd71b5977e0f5df0221b0e4f7ce31d4d 100644
--- a/run-configurations/ComparisonMethodcallWithPorts.launch
+++ b/run-configurations/ComparisonMethodcallWithPorts.launch
@@ -11,8 +11,6 @@
 <stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
 <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
 <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
-<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/>
 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="teetime.examples.ComparisonMethodcallWithPorts"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="teetime"/>
-<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/>
 </launchConfiguration>
diff --git a/src/main/java/util/KiekerLoadDriver.java b/src/main/java/util/KiekerLoadDriver.java
index 410b823f7f2a5f94060020e0c1dae6738de01edf..d8d1a25cda342bf32e9dd11314c54057c0d19a62 100644
--- a/src/main/java/util/KiekerLoadDriver.java
+++ b/src/main/java/util/KiekerLoadDriver.java
@@ -14,7 +14,7 @@ import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
-import teetime.framework.RunnableProducerStage;
+import teetime.framework.RunnableStage;
 import teetime.framework.Stage;
 import teetime.framework.pipe.IPipeFactory;
 import teetime.framework.pipe.PipeFactoryRegistry;
@@ -34,13 +34,13 @@ import kieker.common.util.registry.Registry;
 public class KiekerLoadDriver {
 
 	private final List<IMonitoringRecord> elementCollection = new LinkedList<IMonitoringRecord>();
-	private final RunnableProducerStage runnableStage;
+	private final RunnableStage runnableStage;
 	private long[] timings;
 	private final IPipeFactory intraThreadPipeFactory;
 
 	public KiekerLoadDriver(final File directory) {
 		Stage producerPipeline = this.buildProducerPipeline(directory);
-		runnableStage = new RunnableProducerStage(producerPipeline);
+		runnableStage = new RunnableStage(producerPipeline);
 		intraThreadPipeFactory = PipeFactoryRegistry.INSTANCE.getPipeFactory(ThreadCommunication.INTRA, PipeOrdering.ARBITRARY, false);
 	}
 
diff --git a/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceLogging.java b/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceLogging.java
index 76b249041db81342d2dc15dc5e99b3c3fcf63dfc..226b9baf69b8df5cea8ddc4f4de0a69a4f8725f3 100644
--- a/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceLogging.java
+++ b/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceLogging.java
@@ -1,7 +1,7 @@
 package teetime.examples.kiekerdays;
 
 import teetime.framework.Stage;
-import teetime.framework.RunnableProducerStage;
+import teetime.framework.RunnableStage;
 import teetime.stage.io.network.TcpReader;
 
 public class TcpTraceLogging {
@@ -10,7 +10,7 @@ public class TcpTraceLogging {
 
 	public void init() {
 		Stage tcpPipeline = this.buildTcpPipeline();
-		this.tcpThread = new Thread(new RunnableProducerStage(tcpPipeline));
+		this.tcpThread = new Thread(new RunnableStage(tcpPipeline));
 	}
 
 	public void start() {
diff --git a/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceLoggingExplorviz.java b/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceLoggingExplorviz.java
index 2fef38d2e11bcf3b321e3771a7dbbb940ddb1404..eec9b2aa87bb4a7c548197eec4f6ce77d6128857 100644
--- a/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceLoggingExplorviz.java
+++ b/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceLoggingExplorviz.java
@@ -1,7 +1,7 @@
 package teetime.examples.kiekerdays;
 
 import teetime.framework.Stage;
-import teetime.framework.RunnableProducerStage;
+import teetime.framework.RunnableStage;
 import teetime.framework.pipe.SingleElementPipe;
 import teetime.stage.basic.Sink;
 import teetime.stage.explorviz.KiekerRecordTcpReader;
@@ -14,7 +14,7 @@ public class TcpTraceLoggingExplorviz {
 
 	public void init() {
 		Stage tcpPipeline = this.buildTcpPipeline();
-		this.tcpThread = new Thread(new RunnableProducerStage(tcpPipeline));
+		this.tcpThread = new Thread(new RunnableStage(tcpPipeline));
 	}
 
 	public void start() {
diff --git a/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceReconstruction.java b/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceReconstruction.java
index 1105940fa923c0401d34931929a0c3e4a3f6b6e8..3357b1ad8f73e0a5c3ea25a80db90e27a436a5eb 100644
--- a/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceReconstruction.java
+++ b/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceReconstruction.java
@@ -6,7 +6,7 @@ import java.util.List;
 
 import teetime.framework.Stage;
 import teetime.framework.Pipeline;
-import teetime.framework.RunnableProducerStage;
+import teetime.framework.RunnableStage;
 import teetime.framework.pipe.IPipe;
 import teetime.framework.pipe.IPipeFactory;
 import teetime.framework.pipe.PipeFactoryRegistry;
@@ -51,14 +51,14 @@ public class TcpTraceReconstruction {
 
 	public void init() {
 		Pipeline<Distributor<IMonitoringRecord>> tcpPipeline = this.buildTcpPipeline();
-		this.tcpThread = new Thread(new RunnableProducerStage(tcpPipeline));
+		this.tcpThread = new Thread(new RunnableStage(tcpPipeline));
 
 		this.numWorkerThreads = Math.min(NUM_VIRTUAL_CORES, this.numWorkerThreads);
 		this.workerThreads = new Thread[this.numWorkerThreads];
 
 		for (int i = 0; i < this.workerThreads.length; i++) {
 			Stage pipeline = this.buildPipeline(tcpPipeline.getLastStage());
-			this.workerThreads[i] = new Thread(new RunnableProducerStage(pipeline));
+			this.workerThreads[i] = new Thread(new RunnableStage(pipeline));
 		}
 	}
 
diff --git a/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceReduction.java b/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceReduction.java
index d211ff0befae744992e59010fb5726a01e66d415..e248282aad73e5ab26ddc0134940d89fbf384ed3 100644
--- a/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceReduction.java
+++ b/src/performancetest/java/teetime/examples/kiekerdays/TcpTraceReduction.java
@@ -8,7 +8,7 @@ import java.util.TreeMap;
 
 import teetime.framework.Stage;
 import teetime.framework.Pipeline;
-import teetime.framework.RunnableProducerStage;
+import teetime.framework.RunnableStage;
 import teetime.framework.pipe.IPipe;
 import teetime.framework.pipe.IPipeFactory;
 import teetime.framework.pipe.PipeFactoryRegistry;
@@ -59,17 +59,17 @@ public class TcpTraceReduction {
 
 	public void init() {
 		Pipeline<Distributor<IMonitoringRecord>> tcpPipeline = this.buildTcpPipeline();
-		this.tcpThread = new Thread(new RunnableProducerStage(tcpPipeline));
+		this.tcpThread = new Thread(new RunnableStage(tcpPipeline));
 
 		Pipeline<Distributor<Long>> clockStage = this.buildClockPipeline(5000);
-		this.clockThread = new Thread(new RunnableProducerStage(clockStage));
+		this.clockThread = new Thread(new RunnableStage(clockStage));
 
 		this.numWorkerThreads = Math.min(NUM_VIRTUAL_CORES, this.numWorkerThreads);
 		this.workerThreads = new Thread[this.numWorkerThreads];
 
 		for (int i = 0; i < this.workerThreads.length; i++) {
 			Stage pipeline = this.buildPipeline(tcpPipeline.getLastStage(), clockStage.getLastStage());
-			this.workerThreads[i] = new Thread(new RunnableProducerStage(pipeline));
+			this.workerThreads[i] = new Thread(new RunnableStage(pipeline));
 		}
 	}
 
diff --git a/src/performancetest/java/teetime/examples/traceReconstruction/TraceReconstructionAnalysis.java b/src/performancetest/java/teetime/examples/traceReconstruction/TraceReconstructionAnalysis.java
index 69e12db424e422ce789fe4db6a7cfe8b02743e09..3341f172ed8403fc4a936080b531203e07744eb6 100644
--- a/src/performancetest/java/teetime/examples/traceReconstruction/TraceReconstructionAnalysis.java
+++ b/src/performancetest/java/teetime/examples/traceReconstruction/TraceReconstructionAnalysis.java
@@ -5,7 +5,7 @@ import java.util.LinkedList;
 import java.util.List;
 
 import teetime.framework.AnalysisConfiguration;
-import teetime.framework.RunnableProducerStage;
+import teetime.framework.RunnableStage;
 import teetime.framework.Stage;
 import teetime.framework.pipe.IPipeFactory;
 import teetime.framework.pipe.PipeFactoryRegistry.PipeOrdering;
@@ -59,10 +59,10 @@ public class TraceReconstructionAnalysis extends AnalysisConfiguration {
 
 	private void init() {
 		Clock clockStage = this.buildClockPipeline();
-		this.clockThread = new Thread(new RunnableProducerStage(clockStage));
+		this.clockThread = new Thread(new RunnableStage(clockStage));
 
 		Stage pipeline = this.buildPipeline(clockStage);
-		this.workerThread = new Thread(new RunnableProducerStage(pipeline));
+		this.workerThread = new Thread(new RunnableStage(pipeline));
 	}
 
 	private Clock buildClockPipeline() {
diff --git a/src/performancetest/java/util/test/PerformanceTest.java b/src/performancetest/java/util/test/PerformanceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a37bccda14028e26ee5397898f60e3f5afca817
--- /dev/null
+++ b/src/performancetest/java/util/test/PerformanceTest.java
@@ -0,0 +1,70 @@
+package util.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+import teetime.util.StopWatch;
+import teetime.util.TimestampObject;
+
+public abstract class PerformanceTest {
+
+	protected static final PerformanceCheckProfileRepository PERFORMANCE_CHECK_PROFILE_REPOSITORY = PerformanceCheckProfileRepository.INSTANCE;
+	protected static final int NUM_OBJECTS_TO_CREATE = 1000000;
+	protected static final int NUM_NOOP_FILTERS = 800;
+
+	public static final MeasurementRepository MEASUREMENT_REPOSITORY = new MeasurementRepository();
+
+	protected Description description;
+
+	protected StopWatch stopWatch;
+	protected List<TimestampObject> timestampObjects;
+
+	static {
+		System.setProperty("logback.configurationFile", "src/test/resources/logback.groovy");
+	}
+
+	@Rule
+	public final TestRule watcher = new TestWatcher() {
+		@Override
+		protected void starting(final Description description) {
+			PerformanceTest.this.description = description;
+			// System.out.println("getDisplayName(): " + description.getDisplayName());
+		}
+	};
+
+	@Before
+	public void before() {
+		this.stopWatch = new StopWatch();
+		this.timestampObjects = new ArrayList<TimestampObject>(NUM_OBJECTS_TO_CREATE);
+	}
+
+	@After
+	public void after() {
+		String testMethodIdentifier = MeasurementRepository.buildTestMethodIdentifier(description.getTestClass(), description.getMethodName());
+		PerformanceResult performanceResult = StatisticsUtil.computeStatistics(this.stopWatch.getDurationInNs(), this.timestampObjects);
+		MEASUREMENT_REPOSITORY.performanceResults.put(testMethodIdentifier, performanceResult);
+
+		addToRepository(performanceResult);
+
+		System.out.println("Duration: " + TimeUnit.NANOSECONDS.toMillis(performanceResult.overallDurationInNs) + " ms");
+		System.out.println("avg duration: " + TimeUnit.NANOSECONDS.toMicros(performanceResult.avgDurInNs) + " µs");
+		System.out.println(StatisticsUtil.getQuantilesString(performanceResult.quantiles));
+		System.out.println("confidenceWidth: " + performanceResult.confidenceWidthInNs + " ns");
+		System.out.println("[" + TimeUnit.NANOSECONDS.toMicros(performanceResult.avgDurInNs - performanceResult.confidenceWidthInNs) + " µs, "
+				+ TimeUnit.NANOSECONDS.toMicros(performanceResult.avgDurInNs + performanceResult.confidenceWidthInNs) + " µs]");
+	}
+
+	@Deprecated
+	private void addToRepository(final PerformanceResult performanceResult) {
+		MEASUREMENT_REPOSITORY.performanceResults.put(this.description.getDisplayName(), performanceResult);
+	}
+
+}