diff --git a/.gitignore b/.gitignore
index 9119436c2cb7628e6c10bdfbc4c83c5b1815f9d9..a543dc02b98a8ce159858947b4f0af8e1343af73 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,9 @@
 /build/
 /dist/
 /tmp/
+
+# Ignore Gradle project-specific cache directory
+.gradle
+
+# Ignore Gradle build output directory
+build
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..041f1ac3cfe6a0d479a35e6c5254670e3be22137
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,36 @@
+/*
+ * 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'
+}
+
+repositories {
+    // Use jcenter for resolving dependencies.
+    // You can declare any Maven/Ivy/file repository here.
+    jcenter()
+    mavenCentral()
+}
+
+dependencies {
+    // This dependency is used by the application.
+    implementation 'com.google.guava:guava:29.0-jre'
+    implementation 'com.beust:jcommander:1.72'
+
+    // Use JUnit test framework
+    testImplementation 'junit:junit:4.13'
+}
+
+subprojects {
+	repositories {
+    // Use jcenter for resolving dependencies.
+    // You can declare any Maven/Ivy/file repository here.
+    jcenter()
+    mavenCentral()
+}
+}
diff --git a/OverheadEvaluationMicrobenchmark/LICENSE b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/LICENSE
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/LICENSE
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/LICENSE
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/benchmark.sh b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/benchmark.sh
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/benchmark.sh
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/benchmark.sh
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector.bat b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector.bat
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector.bat
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/bin/collector.bat
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/collector-2.0.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/collector-2.0.jar
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/collector-2.0.jar
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/collector-2.0.jar
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/jcommander-1.72.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/jcommander-1.72.jar
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/jcommander-1.72.jar
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/jcommander-1.72.jar
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/log4j-1.2.17.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/log4j-1.2.17.jar
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/log4j-1.2.17.jar
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/log4j-1.2.17.jar
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-api-1.7.25.jar
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/collector-2.0/lib/slf4j-log4j12-1.7.25.jar
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/common-functions b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/common-functions
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/common-functions
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/common-functions
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/config b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/config
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/config
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/config
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/lib/.gitignore b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/lib/.gitignore
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/lib/.gitignore
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/lib/.gitignore
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/log4j.cfg b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/log4j.cfg
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/log4j.cfg
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/log4j.cfg
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/moobench-2.0-all.jar b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/moobench-2.0-all.jar
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/moobench-2.0-all.jar
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/moobench-2.0-all.jar
diff --git a/OverheadEvaluationMicrobenchmark/MooBench/r/stats.csv.r b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/r/stats.csv.r
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/MooBench/r/stats.csv.r
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/MooBench/r/stats.csv.r
diff --git a/OverheadEvaluationMicrobenchmark/README b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/README
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/README
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/README
diff --git a/OverheadEvaluationMicrobenchmark/executeRemoteMicroBenchmark.sh b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/executeRemoteMicroBenchmark.sh
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/executeRemoteMicroBenchmark.sh
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/executeRemoteMicroBenchmark.sh
diff --git a/OverheadEvaluationMicrobenchmark/rerun-benchmark.sh b/frameworks/Kieker/OverheadEvaluationMicrobenchmark/rerun-benchmark.sh
similarity index 100%
rename from OverheadEvaluationMicrobenchmark/rerun-benchmark.sh
rename to frameworks/Kieker/OverheadEvaluationMicrobenchmark/rerun-benchmark.sh
diff --git a/frameworks/Kieker/build.gradle b/frameworks/Kieker/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..7f69424a058ee66b36b436a0cd7e67f050d33ab1
--- /dev/null
+++ b/frameworks/Kieker/build.gradle
@@ -0,0 +1,12 @@
+plugins {
+	id 'java'
+	id 'application'
+}
+
+dependencies {
+	implementation project(':moobench')
+	implementation 'net.kieker-monitoring:kieker:1.14'
+	implementation 'net.sourceforge.teetime:teetime:3.0'
+    implementation 'org.slf4j:slf4j-api:1.7.+'
+    implementation 'ch.qos.logback:logback-classic:1.2.3'
+}
diff --git a/frameworks/Kieker/src/kieker/tcp/TestExperiment1.java b/frameworks/Kieker/src/kieker/tcp/TestExperiment1.java
deleted file mode 100644
index 335259ed15996024c25f7c0bf5c8fa13ccc69a4e..0000000000000000000000000000000000000000
--- a/frameworks/Kieker/src/kieker/tcp/TestExperiment1.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/***************************************************************************
- * Copyright 2014 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 kieker.tcp;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import kieker.analysis.AnalysisController;
-import kieker.analysis.IAnalysisController;
-import kieker.analysis.IProjectContext;
-import kieker.analysis.exception.AnalysisConfigurationException;
-import kieker.analysis.plugin.annotation.OutputPort;
-import kieker.analysis.plugin.annotation.Plugin;
-import kieker.analysis.plugin.annotation.Property;
-import kieker.analysis.plugin.reader.AbstractReaderPlugin;
-import kieker.common.configuration.Configuration;
-import kieker.common.exception.MonitoringRecordException;
-import kieker.common.logging.Log;
-import kieker.common.logging.LogFactory;
-import kieker.common.record.AbstractMonitoringRecord;
-import kieker.common.record.IMonitoringRecord;
-import kieker.common.record.misc.RegistryRecord;
-import kieker.common.util.registry.ILookup;
-import kieker.common.util.registry.Lookup;
-
-// Command-Line:
-// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000
-/**
- * @author Jan Waller
- */
-public final class TestExperiment1 {
-	private static final Log LOG = LogFactory.getLog(TestExperiment1.class);
-
-	private TestExperiment1() {}
-
-	public static void main(final String[] args) {
-		final IAnalysisController analysisController = new AnalysisController("TCPThroughput");
-		TestExperiment1.createAndConnectPlugins(analysisController);
-		try {
-			analysisController.run();
-		} catch (final AnalysisConfigurationException ex) {
-			TestExperiment1.LOG.error("Failed to start the example project.", ex);
-		}
-	}
-
-	private static void createAndConnectPlugins(final IAnalysisController analysisController) {
-		final Configuration readerConfig = new Configuration();
-		// readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT1, 10333);
-		// readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT2, 10334);
-		final TCPCountingReader reader = new TCPCountingReader(readerConfig, analysisController);
-		reader.getName(); // to remove unused warning
-	}
-}
-
-/**
- * 
- * @author Jan Waller
- * 
- * @since 1.8
- */
-@Plugin(description = "A reader which reads records from a TCP port",
-		outputPorts = {
-			@OutputPort(name = TCPCountingReader.OUTPUT_PORT_NAME_RECORDS, eventTypes = { IMonitoringRecord.class }, description = "Output Port of the TCPReader")
-		},
-		configuration = {
-			@Property(name = TCPCountingReader.CONFIG_PROPERTY_NAME_PORT1, defaultValue = "10133",
-					description = "The first port of the server used for the TCP connection."),
-			@Property(name = TCPCountingReader.CONFIG_PROPERTY_NAME_PORT2, defaultValue = "10134",
-					description = "The second port of the server used for the TCP connection.")
-		})
-final class TCPCountingReader extends AbstractReaderPlugin {
-
-	/** The name of the output port delivering the received records. */
-	public static final String OUTPUT_PORT_NAME_RECORDS = "monitoringRecords";
-
-	/** The name of the configuration determining the TCP port. */
-	public static final String CONFIG_PROPERTY_NAME_PORT1 = "port1";
-	/** The name of the configuration determining the TCP port. */
-	public static final String CONFIG_PROPERTY_NAME_PORT2 = "port2";
-
-	private static final int MESSAGE_BUFFER_SIZE = 65535;
-
-	static final Log LOG = LogFactory.getLog(TCPCountingReader.class);
-
-	private final int port1;
-	private final int port2;
-	private final ILookup<String> stringRegistry = new Lookup<String>();
-
-	final AtomicInteger counter = new AtomicInteger(0);
-	final ScheduledExecutorService executorService;
-
-	public TCPCountingReader(final Configuration configuration, final IProjectContext projectContext) {
-		super(configuration, projectContext);
-		this.port1 = this.configuration.getIntProperty(CONFIG_PROPERTY_NAME_PORT1);
-		this.port2 = this.configuration.getIntProperty(CONFIG_PROPERTY_NAME_PORT2);
-		this.executorService = new ScheduledThreadPoolExecutor(1);
-	}
-
-	@Override
-	public boolean init() {
-		this.executorService.scheduleAtFixedRate(new Runnable() {
-			public void run() {
-				System.out.println("Records/s: " + TCPCountingReader.this.counter.getAndSet(0));
-			}
-		}, 0, 1, TimeUnit.SECONDS);
-
-		final TCPStringReader tcpStringReader = new TCPStringReader(this.port2, this.stringRegistry);
-		tcpStringReader.start();
-		return super.init();
-	}
-
-	@Override
-	public Configuration getCurrentConfiguration() {
-		final Configuration configuration = new Configuration();
-		configuration.setProperty(CONFIG_PROPERTY_NAME_PORT1, Integer.toString(this.port1));
-		configuration.setProperty(CONFIG_PROPERTY_NAME_PORT2, Integer.toString(this.port2));
-		return configuration;
-	}
-
-	public boolean read() {
-		ServerSocketChannel serversocket = null;
-		try {
-			serversocket = ServerSocketChannel.open();
-			serversocket.socket().bind(new InetSocketAddress(this.port1));
-			if (LOG.isDebugEnabled()) {
-				LOG.debug("Listening on port " + this.port1);
-			}
-			// BEGIN also loop this one?
-			final SocketChannel socketChannel = serversocket.accept();
-			final ByteBuffer buffer = ByteBuffer.allocateDirect(MESSAGE_BUFFER_SIZE);
-			while (socketChannel.read(buffer) != -1) {
-				buffer.flip();
-				// System.out.println("Reading, remaining:" + buffer.remaining());
-				try {
-					while (buffer.hasRemaining()) {
-						buffer.mark();
-						final int clazzid = buffer.getInt();
-						final long loggingTimestamp = buffer.getLong();
-						final IMonitoringRecord record;
-						try { // NOCS (Nested try-catch)
-							record = AbstractMonitoringRecord.createFromByteBuffer(clazzid, buffer, this.stringRegistry);
-							record.setLoggingTimestamp(loggingTimestamp);
-							// super.deliver(OUTPUT_PORT_NAME_RECORDS, record);
-							this.counter.incrementAndGet();
-						} catch (final MonitoringRecordException ex) {
-							LOG.error("Failed to create record.", ex);
-						}
-					}
-					buffer.clear();
-				} catch (final BufferUnderflowException ex) {
-					buffer.reset();
-					// System.out.println("Underflow, remaining:" + buffer.remaining());
-					buffer.compact();
-				}
-			}
-			// System.out.println("Channel closing...");
-			socketChannel.close();
-			// END also loop this one?
-		} catch (final IOException ex) {
-			LOG.error("Error while reading", ex);
-			return false;
-		} finally {
-			if (null != serversocket) {
-				try {
-					serversocket.close();
-				} catch (final IOException e) {
-					if (LOG.isDebugEnabled()) {
-						LOG.debug("Failed to close TCP connection!", e);
-					}
-				}
-			}
-		}
-		return true;
-	}
-
-	public void terminate(final boolean error) {
-		LOG.info("Shutdown of TCPReader requested.");
-		this.executorService.shutdown();
-	}
-}
-
-/**
- * 
- * @author Jan Waller
- * 
- * @since 1.8
- */
-class TCPStringReader extends Thread {
-
-	private static final int MESSAGE_BUFFER_SIZE = 65535;
-
-	private static final Log LOG = LogFactory.getLog(TCPStringReader.class);
-
-	private final int port;
-	private final ILookup<String> stringRegistry;
-
-	public TCPStringReader(final int port, final ILookup<String> stringRegistry) {
-		this.port = port;
-		this.stringRegistry = stringRegistry;
-	}
-
-	@Override
-	public void run() {
-		ServerSocketChannel serversocket = null;
-		try {
-			serversocket = ServerSocketChannel.open();
-			serversocket.socket().bind(new InetSocketAddress(this.port));
-			if (LOG.isDebugEnabled()) {
-				LOG.debug("Listening on port " + this.port);
-			}
-			// BEGIN also loop this one?
-			final SocketChannel socketChannel = serversocket.accept();
-			final ByteBuffer buffer = ByteBuffer.allocateDirect(MESSAGE_BUFFER_SIZE);
-			while (socketChannel.read(buffer) != -1) {
-				buffer.flip();
-				try {
-					while (buffer.hasRemaining()) {
-						buffer.mark();
-						RegistryRecord.registerRecordInRegistry(buffer, this.stringRegistry);
-					}
-					buffer.clear();
-				} catch (final BufferUnderflowException ex) {
-					buffer.reset();
-					buffer.compact();
-				}
-			}
-			socketChannel.close();
-			// END also loop this one?
-		} catch (final IOException ex) {
-			LOG.error("Error while reading", ex);
-		} finally {
-			if (null != serversocket) {
-				try {
-					serversocket.close();
-				} catch (final IOException e) {
-					if (LOG.isDebugEnabled()) {
-						LOG.debug("Failed to close TCP connection!", e);
-					}
-				}
-			}
-		}
-	}
-
-}
diff --git a/frameworks/Kieker/src/kieker/tcp/TestExperiment2.java b/frameworks/Kieker/src/kieker/tcp/TestExperiment2.java
deleted file mode 100644
index 17ab72d6357efb639fce656f7e5da16e48c9c9bd..0000000000000000000000000000000000000000
--- a/frameworks/Kieker/src/kieker/tcp/TestExperiment2.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/***************************************************************************
- * Copyright 2014 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 kieker.tcp;
-
-import java.util.concurrent.TimeUnit;
-
-import kieker.analysis.AnalysisController;
-import kieker.analysis.IAnalysisController;
-import kieker.analysis.exception.AnalysisConfigurationException;
-import kieker.analysis.plugin.filter.flow.EventRecordTraceReconstructionFilter;
-import kieker.analysis.plugin.filter.forward.AnalysisThroughputFilter;
-import kieker.analysis.plugin.filter.forward.TeeFilter;
-import kieker.analysis.plugin.reader.tcp.TCPReader;
-import kieker.analysis.plugin.reader.timer.TimeReader;
-import kieker.common.configuration.Configuration;
-import kieker.common.logging.Log;
-import kieker.common.logging.LogFactory;
-
-// Command-Line:
-// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000
-/**
- * @author Jan Waller
- */
-public final class TestExperiment2 {
-	private static final Log LOG = LogFactory.getLog(TestExperiment2.class);
-
-	private TestExperiment2() {}
-
-	public static void main(final String[] args) throws IllegalStateException, AnalysisConfigurationException {
-		final IAnalysisController analysisController = new AnalysisController("TCPThroughput");
-		TestExperiment2.createAndConnectPlugins(analysisController);
-		try {
-			analysisController.run();
-		} catch (final AnalysisConfigurationException ex) {
-			TestExperiment2.LOG.error("Failed to start the example project.", ex);
-		}
-	}
-
-	private static void createAndConnectPlugins(final IAnalysisController analysisController) throws IllegalStateException, AnalysisConfigurationException {
-		final Configuration readerConfig = new Configuration();
-		// readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT1, 10333);
-		// readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT2, 10334);
-		final TCPReader reader = new TCPReader(readerConfig, analysisController);
-
-		final Configuration timeConfig = new Configuration();
-		final TimeReader timeReader = new TimeReader(timeConfig, analysisController);
-
-		final Configuration configTraceRecon = new Configuration();
-		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name());
-		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_DURATION, "1");
-		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_TIMEOUT, "1");
-		final EventRecordTraceReconstructionFilter traceRecon = new EventRecordTraceReconstructionFilter(configTraceRecon, analysisController);
-
-		analysisController.connect(reader, TCPReader.OUTPUT_PORT_NAME_RECORDS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TRACE_RECORDS);
-		analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TIME_EVENT);
-
-		final Configuration counterConfig = new Configuration();
-		final AnalysisThroughputFilter through = new AnalysisThroughputFilter(counterConfig, analysisController);
-		analysisController.connect(traceRecon, EventRecordTraceReconstructionFilter.OUTPUT_PORT_NAME_TRACE_VALID, through,
-				AnalysisThroughputFilter.INPUT_PORT_NAME_OBJECTS);
-		analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, through, AnalysisThroughputFilter.INPUT_PORT_NAME_TIME);
-
-		final Configuration confTeeFilter = new Configuration();
-		confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_STDOUT);
-		// confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_NULL);
-		final TeeFilter teeFilter = new TeeFilter(confTeeFilter, analysisController);
-		analysisController.connect(through, AnalysisThroughputFilter.OUTPUT_PORT_NAME_THROUGHPUT, teeFilter, TeeFilter.INPUT_PORT_NAME_EVENTS);
-	}
-}
diff --git a/frameworks/Kieker/src/kieker/tcp/TestExperiment3.java b/frameworks/Kieker/src/kieker/tcp/TestExperiment3.java
deleted file mode 100644
index fb0a031c3f6eb2216b5788c4d67133ad8ab850ac..0000000000000000000000000000000000000000
--- a/frameworks/Kieker/src/kieker/tcp/TestExperiment3.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/***************************************************************************
- * Copyright 2014 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 kieker.tcp;
-
-import java.util.concurrent.TimeUnit;
-
-import kieker.analysis.AnalysisController;
-import kieker.analysis.IAnalysisController;
-import kieker.analysis.exception.AnalysisConfigurationException;
-import kieker.analysis.plugin.filter.flow.EventRecordTraceReconstructionFilter;
-import kieker.analysis.plugin.filter.flow.TraceAggregationFilter;
-import kieker.analysis.plugin.filter.forward.TeeFilter;
-import kieker.analysis.plugin.reader.tcp.TCPReader;
-import kieker.analysis.plugin.reader.timer.TimeReader;
-import kieker.common.configuration.Configuration;
-import kieker.common.logging.Log;
-import kieker.common.logging.LogFactory;
-
-// Command-Line:
-// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000
-/**
- * @author Jan Waller
- */
-public final class TestExperiment3 {
-	private static final Log LOG = LogFactory.getLog(TestExperiment3.class);
-
-	private TestExperiment3() {}
-
-	public static void main(final String[] args) throws IllegalStateException, AnalysisConfigurationException {
-		final IAnalysisController analysisController = new AnalysisController("TCPThroughput");
-		TestExperiment3.createAndConnectPlugins(analysisController);
-		try {
-			analysisController.run();
-		} catch (final AnalysisConfigurationException ex) {
-			TestExperiment3.LOG.error("Failed to start the example project.", ex);
-		}
-	}
-
-	private static void createAndConnectPlugins(final IAnalysisController analysisController) throws IllegalStateException, AnalysisConfigurationException {
-		final Configuration readerConfig = new Configuration();
-		// readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT1, 10333);
-		// readerConfig.setProperty(TCPReader.CONFIG_PROPERTY_NAME_PORT2, 10334);
-		final TCPReader reader = new TCPReader(readerConfig, analysisController);
-
-		final Configuration timeConfig = new Configuration();
-		final TimeReader timeReader = new TimeReader(timeConfig, analysisController);
-
-		final Configuration configTraceRecon = new Configuration();
-		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name());
-		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_DURATION, "1");
-		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_TIMEOUT, "1");
-		final EventRecordTraceReconstructionFilter traceRecon = new EventRecordTraceReconstructionFilter(configTraceRecon, analysisController);
-
-		analysisController.connect(reader, TCPReader.OUTPUT_PORT_NAME_RECORDS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TRACE_RECORDS);
-		analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TIME_EVENT);
-
-		final Configuration configTraceAggr = new Configuration();
-		configTraceAggr.setProperty(TraceAggregationFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name());
-		configTraceAggr.setProperty(TraceAggregationFilter.CONFIG_PROPERTY_NAME_MAX_COLLECTION_DURATION, "1");
-		final TraceAggregationFilter traceAggr = new TraceAggregationFilter(configTraceAggr, analysisController);
-
-		analysisController.connect(traceRecon, EventRecordTraceReconstructionFilter.OUTPUT_PORT_NAME_TRACE_VALID, traceAggr,
-				TraceAggregationFilter.INPUT_PORT_NAME_TRACES);
-		analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceAggr, TraceAggregationFilter.INPUT_PORT_NAME_TIME_EVENT);
-
-		final Configuration confTeeFilter = new Configuration();
-		confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_STDOUT);
-		// confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_NULL);
-		final TeeFilter teeFilter = new TeeFilter(confTeeFilter, analysisController);
-		analysisController.connect(traceAggr, TraceAggregationFilter.OUTPUT_PORT_NAME_TRACES, teeFilter, TeeFilter.INPUT_PORT_NAME_EVENTS);
-	}
-}
diff --git a/frameworks/Kieker/src/kieker/Logger.java b/frameworks/Kieker/src/main/java/moobench/kieker/Logger.java
similarity index 87%
rename from frameworks/Kieker/src/kieker/Logger.java
rename to frameworks/Kieker/src/main/java/moobench/kieker/Logger.java
index 55029356a9b746ba01208a056073885f817e25bf..1ade79392d684fe5ef0d5b898318869c75c17cff 100644
--- a/frameworks/Kieker/src/kieker/Logger.java
+++ b/frameworks/Kieker/src/main/java/moobench/kieker/Logger.java
@@ -13,12 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  ***************************************************************************/
-
-package kieker;
+package moobench.kieker;
 
 import java.io.IOException;
 
-import mooBench.benchmark.Benchmark;
+import moobench.benchmark.BenchmarkMain;
 
 /**
  * @author Jan Waller
@@ -28,7 +27,7 @@ public class Logger implements Runnable {
 	public void run() {
 		try {
 			java.util.logging.LogManager.getLogManager().readConfiguration(
-					Benchmark.class.getClassLoader().getResourceAsStream("META-INF/kieker.logging.properties"));
+					BenchmarkMain.class.getClassLoader().getResourceAsStream("META-INF/kieker.logging.properties"));
 		} catch (final IOException ex) {
 			java.util.logging.Logger.getAnonymousLogger().log(java.util.logging.Level.SEVERE, "Could not load default logging.properties file", ex);
 		}
diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration1.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration1.java
new file mode 100644
index 0000000000000000000000000000000000000000..0729de777254de71877fb52792749003a4899c79
--- /dev/null
+++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration1.java
@@ -0,0 +1,15 @@
+package moobench.kieker.tcp;
+
+import kieker.analysis.source.tcp.MultipleConnectionTcpSourceStage;
+import kieker.analysisteetime.plugin.filter.forward.CountingFilter;
+import teetime.framework.Configuration;
+
+public class TestConfiguration1 extends Configuration {
+
+	public TestConfiguration1(int inputPort, int bufferSize) {
+		MultipleConnectionTcpSourceStage source = new MultipleConnectionTcpSourceStage(inputPort, bufferSize, null);
+		CountingFilter counting = new CountingFilter();
+		
+		connectPorts(source.getOutputPort(), counting.getInputPort());
+	}
+}
diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration2.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration2.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5539001a4926afedb749ebecc25fb2f6fdd8331
--- /dev/null
+++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration2.java
@@ -0,0 +1,45 @@
+/**
+ * 
+ */
+package moobench.kieker.tcp;
+
+import java.util.concurrent.TimeUnit;
+
+import kieker.analysis.source.tcp.MultipleConnectionTcpSourceStage;
+import teetime.framework.Configuration;
+
+/**
+ * @author reiner
+ *
+ */
+public class TestConfiguration2 extends Configuration {
+
+	public TestConfiguration2(int inputPort, int bufferSize) {
+		MultipleConnectionTcpSourceStage reader = new MultipleConnectionTcpSourceStage(inputPort, bufferSize, null);
+/*
+		final Configuration timeConfig = new Configuration();
+		final TimeReader timeReader = new TimeReader(timeConfig, analysisController);
+
+		final Configuration configTraceRecon = new Configuration();
+		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name());
+		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_DURATION, "1");
+		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_TIMEOUT, "1");
+		final EventRecordTraceReconstructionFilter traceRecon = new EventRecordTraceReconstructionFilter(configTraceRecon, analysisController);
+
+		analysisController.connect(reader, TCPReader.OUTPUT_PORT_NAME_RECORDS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TRACE_RECORDS);
+		analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TIME_EVENT);
+
+		final Configuration counterConfig = new Configuration();
+		final AnalysisThroughputFilter through = new AnalysisThroughputFilter(counterConfig, analysisController);
+		analysisController.connect(traceRecon, EventRecordTraceReconstructionFilter.OUTPUT_PORT_NAME_TRACE_VALID, through,
+				AnalysisThroughputFilter.INPUT_PORT_NAME_OBJECTS);
+		analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, through, AnalysisThroughputFilter.INPUT_PORT_NAME_TIME);
+
+		final Configuration confTeeFilter = new Configuration();
+		confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_STDOUT);
+		// confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_NULL);
+		final TeeFilter teeFilter = new TeeFilter(confTeeFilter, analysisController);
+		analysisController.connect(through, AnalysisThroughputFilter.OUTPUT_PORT_NAME_THROUGHPUT, teeFilter, TeeFilter.INPUT_PORT_NAME_EVENTS);*/
+	
+	}
+}
diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration3.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration3.java
new file mode 100644
index 0000000000000000000000000000000000000000..a33a4d613d4952d9cca213c56ab57e1239364449
--- /dev/null
+++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestConfiguration3.java
@@ -0,0 +1,42 @@
+package moobench.kieker.tcp;
+
+import java.util.concurrent.TimeUnit;
+
+import kieker.analysis.source.tcp.MultipleConnectionTcpSourceStage;
+import teetime.framework.Configuration;
+
+public class TestConfiguration3 extends Configuration {
+
+	public TestConfiguration3(int inputPort, int bufferSize) {
+		MultipleConnectionTcpSourceStage source = new MultipleConnectionTcpSourceStage(inputPort, bufferSize, null);
+	
+		/*
+			final Configuration timeConfig = new Configuration();
+		final TimeReader timeReader = new TimeReader(timeConfig, analysisController);
+
+		final Configuration configTraceRecon = new Configuration();
+		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name());
+		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_DURATION, "1");
+		configTraceRecon.setProperty(EventRecordTraceReconstructionFilter.CONFIG_PROPERTY_NAME_MAX_TRACE_TIMEOUT, "1");
+		final EventRecordTraceReconstructionFilter traceRecon = new EventRecordTraceReconstructionFilter(configTraceRecon, analysisController);
+
+		analysisController.connect(reader, TCPReader.OUTPUT_PORT_NAME_RECORDS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TRACE_RECORDS);
+		analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceRecon, EventRecordTraceReconstructionFilter.INPUT_PORT_NAME_TIME_EVENT);
+
+		final Configuration configTraceAggr = new Configuration();
+		configTraceAggr.setProperty(TraceAggregationFilter.CONFIG_PROPERTY_NAME_TIMEUNIT, TimeUnit.SECONDS.name());
+		configTraceAggr.setProperty(TraceAggregationFilter.CONFIG_PROPERTY_NAME_MAX_COLLECTION_DURATION, "1");
+		final TraceAggregationFilter traceAggr = new TraceAggregationFilter(configTraceAggr, analysisController);
+
+		analysisController.connect(traceRecon, EventRecordTraceReconstructionFilter.OUTPUT_PORT_NAME_TRACE_VALID, traceAggr,
+				TraceAggregationFilter.INPUT_PORT_NAME_TRACES);
+		analysisController.connect(timeReader, TimeReader.OUTPUT_PORT_NAME_TIMESTAMPS, traceAggr, TraceAggregationFilter.INPUT_PORT_NAME_TIME_EVENT);
+
+		final Configuration confTeeFilter = new Configuration();
+		confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_STDOUT);
+		// confTeeFilter.setProperty(TeeFilter.CONFIG_PROPERTY_NAME_STREAM, TeeFilter.CONFIG_PROPERTY_VALUE_STREAM_NULL);
+		final TeeFilter teeFilter = new TeeFilter(confTeeFilter, analysisController);
+		analysisController.connect(traceAggr, TraceAggregationFilter.OUTPUT_PORT_NAME_TRACES, teeFilter, TeeFilter.INPUT_PORT_NAME_EVENTS);
+*/
+	}
+}
diff --git a/frameworks/Kieker/src/kieker/tcp/TestExperiment0.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment0.java
similarity index 99%
rename from frameworks/Kieker/src/kieker/tcp/TestExperiment0.java
rename to frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment0.java
index f4b174b51c07002f5f7c5a11161212bbfada7a8a..0460b57c66cfe345955d0bb92aad0aad4d652e09 100644
--- a/frameworks/Kieker/src/kieker/tcp/TestExperiment0.java
+++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment0.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package kieker.tcp;
+package moobench.kieker.tcp;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment1.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment1.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4a09a8b0f26a1193ab3eb98a3ec0657f123738b
--- /dev/null
+++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment1.java
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * Copyright 2014 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 moobench.kieker.tcp;
+
+import teetime.framework.Execution;
+
+// Command-Line:
+// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000
+/**
+ * @author Jan Waller
+ */
+public final class TestExperiment1 {
+
+	private TestExperiment1() {}
+
+	public static void main(final String[] args) {
+		TestConfiguration1 config = new TestConfiguration1(Integer.parseInt(args[0]), 8192);
+		Execution<TestConfiguration1> execution = new Execution<TestConfiguration1>(config);
+		execution.executeBlocking();
+	}
+}
diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment2.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment2.java
new file mode 100644
index 0000000000000000000000000000000000000000..663b038c8a1597a093bc69a0592591f3dceec214
--- /dev/null
+++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment2.java
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright 2014 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 moobench.kieker.tcp;
+
+import java.util.concurrent.TimeUnit;
+
+import teetime.framework.Execution;
+
+// Command-Line:
+// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000
+/**
+ * @author Jan Waller
+ */
+public final class TestExperiment2 {
+	
+	private TestExperiment2() {}
+
+	public static void main(final String[] args) {
+		TestConfiguration2 config = new TestConfiguration2(Integer.parseInt(args[0]), 8192);
+		Execution<TestConfiguration2> execution = new Execution<TestConfiguration2>(config);
+		execution.executeBlocking();
+	}
+
+}
diff --git a/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment3.java b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment3.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a854fd36661de78302ac18d926709779fd11408
--- /dev/null
+++ b/frameworks/Kieker/src/main/java/moobench/kieker/tcp/TestExperiment3.java
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright 2014 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 moobench.kieker.tcp;
+
+import java.util.concurrent.TimeUnit;
+
+import teetime.framework.Execution;
+
+// Command-Line:
+// java -javaagent:lib/kieker-1.10-SNAPSHOT_aspectj.jar -Dkieker.monitoring.writer=kieker.monitoring.writer.tcp.TCPWriter -Dkieker.monitoring.writer.tcp.TCPWriter.QueueFullBehavior=1 -jar dist\OverheadEvaluationMicrobenchmark.jar --recursiondepth 10 --totalthreads 1 --methodtime 0 --output-filename raw.csv --totalcalls 10000000
+/**
+ * @author Jan Waller
+ */
+public final class TestExperiment3 {
+
+	private TestExperiment3() {}
+
+	public static void main(final String[] args) {
+		TestConfiguration3 config = new TestConfiguration3(Integer.parseInt(args[0]), 8192);
+		Execution<TestConfiguration3> execution = new Execution<TestConfiguration3>(config);
+		execution.executeBlocking();
+	}
+
+}
diff --git a/frameworks/SPASSmeter/build.gradle b/frameworks/SPASSmeter/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..105b0788bea02b07ba597754e6e39c4f46d134e2
--- /dev/null
+++ b/frameworks/SPASSmeter/build.gradle
@@ -0,0 +1,8 @@
+plugins {
+	id 'java'
+	id 'java-library'
+}
+
+dependencies {
+
+}
diff --git a/frameworks/inspectIT/build.gradle b/frameworks/inspectIT/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..105b0788bea02b07ba597754e6e39c4f46d134e2
--- /dev/null
+++ b/frameworks/inspectIT/build.gradle
@@ -0,0 +1,8 @@
+plugins {
+	id 'java'
+	id 'java-library'
+}
+
+dependencies {
+
+}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..62d4c053550b91381bbd28b1afc82d634bf73a8a
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..622ab64a3cb60378cd29384961554c0b032c9368
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000000000000000000000000000000000000..fbd7c515832dab7b01092e80db76e5e03fe32d29
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# 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
+#
+#      https://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.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=`expr $i + 1`
+    done
+    case $i in
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..5093609d512a96947851d39fa2dc05df2af2248e
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,104 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/lib/commons-cli-1.2.LICENSE b/lib/commons-cli-1.2.LICENSE
deleted file mode 100644
index 9e1db3b220d1643c94f9d452c941f1c3cd079822..0000000000000000000000000000000000000000
--- a/lib/commons-cli-1.2.LICENSE
+++ /dev/null
@@ -1,207 +0,0 @@
-The Apache Software License - ASL - v2.0
-Project: http://commons.apache.org/cli/
-Description: Apache Commons CLI provides a simple API for working with the command line arguments and options.
-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   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.
-
diff --git a/lib/commons-cli-1.2.jar b/lib/commons-cli-1.2.jar
deleted file mode 100644
index ce4b9fffe40c41669797cd806ac989471b2acd84..0000000000000000000000000000000000000000
Binary files a/lib/commons-cli-1.2.jar and /dev/null differ
diff --git a/moobench/build.gradle b/moobench/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..1dbd5d6ac7b51367b9192abbed1c992094e723a0
--- /dev/null
+++ b/moobench/build.gradle
@@ -0,0 +1,12 @@
+plugins {
+	id 'java'
+	id 'application'
+}
+
+dependencies {
+    implementation 'com.beust:jcommander:1.72'
+}
+
+application {
+    mainClass = 'moobench.benchmark.BenchmarkMain'
+}
diff --git a/src/mooBench/monitoredApplication/MonitoredClass.java b/moobench/src/main/java/moobench/application/MonitoredClass.java
similarity index 95%
rename from src/mooBench/monitoredApplication/MonitoredClass.java
rename to moobench/src/main/java/moobench/application/MonitoredClass.java
index db4be4271ac06cf46097ef110b07d0805b428fa2..ce87df4144a29ead8ee2dec4ec6d99b881e17aac 100644
--- a/src/mooBench/monitoredApplication/MonitoredClass.java
+++ b/moobench/src/main/java/moobench/application/MonitoredClass.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package mooBench.monitoredApplication;
+package moobench.application;
 
 /**
  * @author Jan Waller
diff --git a/src/mooBench/monitoredApplication/MonitoredClassSimple.java b/moobench/src/main/java/moobench/application/MonitoredClassSimple.java
similarity index 97%
rename from src/mooBench/monitoredApplication/MonitoredClassSimple.java
rename to moobench/src/main/java/moobench/application/MonitoredClassSimple.java
index 3227e38d823de12297dc1a18ff1c25d839143b80..8ea21fa54774c0084298862acd2628fe840c0d13 100644
--- a/src/mooBench/monitoredApplication/MonitoredClassSimple.java
+++ b/moobench/src/main/java/moobench/application/MonitoredClassSimple.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package mooBench.monitoredApplication;
+package moobench.application;
 
 /**
  * @author Jan Waller
diff --git a/src/mooBench/monitoredApplication/MonitoredClassThreaded.java b/moobench/src/main/java/moobench/application/MonitoredClassThreaded.java
similarity index 97%
rename from src/mooBench/monitoredApplication/MonitoredClassThreaded.java
rename to moobench/src/main/java/moobench/application/MonitoredClassThreaded.java
index 869e0d8d88b3fba41131d364162da1533fc73fe5..060fda2390ee750879b4010c91ed501a96a3701e 100644
--- a/src/mooBench/monitoredApplication/MonitoredClassThreaded.java
+++ b/moobench/src/main/java/moobench/application/MonitoredClassThreaded.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package mooBench.monitoredApplication;
+package moobench.application;
 
 import java.lang.management.ManagementFactory;
 import java.lang.management.ThreadMXBean;
diff --git a/moobench/src/main/java/moobench/benchmark/BenchmarkMain.java b/moobench/src/main/java/moobench/benchmark/BenchmarkMain.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff3eebbc722527e8f85d9c9d66ca9dde297f8322
--- /dev/null
+++ b/moobench/src/main/java/moobench/benchmark/BenchmarkMain.java
@@ -0,0 +1,158 @@
+/***************************************************************************
+ * Copyright 2014 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 moobench.benchmark;
+
+import java.io.BufferedOutputStream;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterException;
+
+import moobench.application.MonitoredClass;
+import moobench.application.MonitoredClassThreaded;
+
+/**
+ * @author Jan Waller
+ */
+public final class BenchmarkMain {
+	private static final String ENCODING = "UTF-8";
+
+	private static PrintStream ps = null;
+	private static String outputFn = null;
+	private static int totalThreads = 0;
+	private static int totalCalls = 0;
+	private static long methodTime = 0;
+	private static int recursionDepth = 0;
+	private static boolean quickstart = false;
+	private static boolean forceTerminate = false;
+	private static MonitoredClass mc = null;
+
+	private static BenchmarkParameter parameter = new BenchmarkParameter();
+
+	private BenchmarkMain() {
+	}
+
+	public static void main(final String[] args) throws InterruptedException {
+
+		// 1. Preparations
+		BenchmarkMain.parseAndInitializeArguments(args);
+
+		System.out.println(" # Experiment run configuration:"); // NOPMD (System.out)
+		System.out.println(" # 1. Output filename " + BenchmarkMain.outputFn); // NOPMD (System.out)
+		System.out.println(" # 2. Recursion Depth " + BenchmarkMain.recursionDepth); // NOPMD (System.out)
+		System.out.println(" # 3. Threads " + BenchmarkMain.totalThreads); // NOPMD (System.out)
+		System.out.println(" # 4. Total-Calls " + BenchmarkMain.totalCalls); // NOPMD (System.out)
+		System.out.println(" # 5. Method-Time " + BenchmarkMain.methodTime); // NOPMD (System.out)
+
+		// 2. Initialize Threads and Classes
+		final CountDownLatch doneSignal = new CountDownLatch(BenchmarkMain.totalThreads);
+		final BenchmarkingThread[] benchmarkingThreads = new BenchmarkingThread[BenchmarkMain.totalThreads];
+		final Thread[] threads = new Thread[BenchmarkMain.totalThreads];
+		for (int i = 0; i < BenchmarkMain.totalThreads; i++) {
+			benchmarkingThreads[i] = new BenchmarkingThreadNano(BenchmarkMain.mc, BenchmarkMain.totalCalls,
+					BenchmarkMain.methodTime, BenchmarkMain.recursionDepth, doneSignal);
+			threads[i] = new Thread(benchmarkingThreads[i], String.valueOf(i + 1));
+		}
+		if (!quickstart) {
+			for (int l = 0; l < 4; l++) {
+				{ // NOCS (reserve mem only within the block)
+					final long freeMemChunks = Runtime.getRuntime().freeMemory() >> 27;
+					// System.out.println("Free-Mem: " + Runtime.getRuntime().freeMemory());
+					final int memSize = 128 * 1024 * 128; // memSize * 8 = total Bytes -> 128MB
+					for (int j = 0; j < freeMemChunks; j++) {
+						final long[] grabMemory = new long[memSize];
+						for (int i = 0; i < memSize; i++) {
+							grabMemory[i] = System.nanoTime();
+						}
+					}
+					// System.out.println("done grabbing memory...");
+					// System.out.println("Free-Mem: " + Runtime.getRuntime().freeMemory());
+				}
+				Thread.sleep(5000);
+			}
+		}
+		final long startTime = System.currentTimeMillis();
+		System.out.println(" # 6. Starting benchmark ..."); // NOPMD (System.out)
+		// 3. Starting Threads
+		for (int i = 0; i < BenchmarkMain.totalThreads; i++) {
+			threads[i].start();
+		}
+
+		// 4. Wait for all Threads
+		try {
+			doneSignal.await();
+		} catch (final InterruptedException e) {
+			e.printStackTrace(); // NOPMD (Stacktrace)
+			System.exit(-1);
+		}
+		final long totalTime = System.currentTimeMillis() - startTime;
+		System.out.println(" #    done (" + TimeUnit.MILLISECONDS.toSeconds(totalTime) + " s)"); // NOPMD
+																									// (System.out)
+
+		// 5. Print experiment statistics
+		System.out.print(" # 7. Writing results ... "); // NOPMD (System.out)
+		// CSV Format: configuration;order_index;Thread-ID;duration_nsec
+		for (int h = 0; h < BenchmarkMain.totalThreads; h++) {
+			final BenchmarkingThread thread = benchmarkingThreads[h];
+			for (int i = 0; i < BenchmarkMain.totalCalls; i++) {
+				final String line = threads[h].getName() + ";" + thread.print(i, ";");
+				BenchmarkMain.ps.println(line);
+			}
+		}
+		BenchmarkMain.ps.close();
+
+		System.out.println("done"); // NOPMD (System.out)
+		System.out.println(" # "); // NOPMD (System.out)
+
+		if (forceTerminate) {
+			System.exit(0);
+		}
+	}
+
+	public static void parseAndInitializeArguments(final String[] argv) {
+		JCommander commander = null;
+		try {
+			commander = JCommander.newBuilder().addObject(parameter).build();
+			commander.parse(argv);
+
+			BenchmarkMain.ps = new PrintStream(
+					new BufferedOutputStream(Files.newOutputStream(parameter.getOutputFile().toPath()), 8192 * 8),
+					false, BenchmarkMain.ENCODING);
+			if (null != parameter.getApplicationClassname()) {
+				mc = ((MonitoredClass) Class.forName(parameter.getApplicationClassname()).newInstance());
+			} else {
+				mc = new MonitoredClassThreaded();
+			}
+			if (null != parameter.getRunnableClassname()) {
+				((Runnable) Class.forName(parameter.getRunnableClassname()).newInstance()).run();
+			}
+		} catch (ParameterException ex) {
+			if (commander != null)
+				commander.usage();
+		} catch (final Exception ex) { // NOCS (e.g., IOException, ParseException,
+										// NumberFormatException)
+			if (commander != null) {
+				commander.usage();
+			}
+			System.out.println(ex.toString()); // NOPMD (Stacktrace)
+			System.exit(-1);
+		}
+	}
+}
diff --git a/moobench/src/main/java/moobench/benchmark/BenchmarkParameter.java b/moobench/src/main/java/moobench/benchmark/BenchmarkParameter.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ffe44f625ebfacb41f56e73211734a48e0581eb
--- /dev/null
+++ b/moobench/src/main/java/moobench/benchmark/BenchmarkParameter.java
@@ -0,0 +1,91 @@
+/**
+ * 
+ */
+package moobench.benchmark;
+
+import java.io.File;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.converters.FileConverter;
+
+/**
+ * @author Reiner Jung
+ *
+ */
+public class BenchmarkParameter {
+	
+	@Parameter(names = { "--totalCalls", "-c" }, required = true, description = "Number of total method calls performed.")
+	long totalCalls;
+	
+	@Parameter(names = { "--methodtime", "-m" }, required = true, description = "Time a method call takes.")
+	long methodTime;
+	
+	@Parameter(names = { "--totalthreads", "-t" }, required = true, description = "Number of threads started.")
+	long totalThreads;
+			
+	@Parameter(names = { "--recursiondepth", "-d" }, required = true, description = "Depth of recursion performed.")
+	long recursionDepth;
+
+	@Parameter(names = { "--output-filename", "-o" }, required = true, converter = FileConverter.class, 
+			description = "Filename of results file. Output is appended if file exists.")
+	File outputFile;
+	
+	@Parameter(names = { "--quickstart", "-q" }, required = false, description = "Skips initial garbage collection.")
+	boolean quickstart;
+	
+	@Parameter(names = { "--forceTerminate", "-f" }, required = false, description = "Forces a termination at the end of the benchmark.")
+	boolean forceTerminate;
+    
+	@Parameter(names = { "--runnable", "-r" }, required = false,
+			description = "Class implementing the Runnable interface. run() method is executed before the benchmark starts.")
+	String runnableClassname;
+	
+    @Parameter(names = { "--application", "-a" }, required = false, description = "Class implementing the MonitoredClass interface.")
+    String applicationClassname;
+    
+    @Parameter(names = { "--benchmarkthread", "-b" }, required = false, description = "Class implementing the BenchmarkingThread interface.")
+    String benchmarkClassname;
+
+	public long getTotalCalls() {
+		return totalCalls;
+	}
+
+	public long getMethodTime() {
+		return methodTime;
+	}
+
+	public long getTotalThreads() {
+		return totalThreads;
+	}
+
+	public long getRecursionDepth() {
+		return recursionDepth;
+	}
+
+	public File getOutputFile() {
+		return outputFile;
+	}
+
+	public boolean isQuickstart() {
+		return quickstart;
+	}
+
+	public boolean isForceTerminate() {
+		return forceTerminate;
+	}
+
+	public String getRunnableClassname() {
+		return runnableClassname;
+	}
+
+	public String getApplicationClassname() {
+		return applicationClassname;
+	}
+
+	public String getBenchmarkClassname() {
+		return benchmarkClassname;
+	}
+    
+    
+    
+}
diff --git a/src/mooBench/benchmark/BenchmarkingThread.java b/moobench/src/main/java/moobench/benchmark/BenchmarkingThread.java
similarity index 97%
rename from src/mooBench/benchmark/BenchmarkingThread.java
rename to moobench/src/main/java/moobench/benchmark/BenchmarkingThread.java
index 043ad1ad19ca8918ff5ece5b35d7d834a3980b67..97b1263fc5571197a375b9ec25b78be9833e9dbe 100644
--- a/src/mooBench/benchmark/BenchmarkingThread.java
+++ b/moobench/src/main/java/moobench/benchmark/BenchmarkingThread.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package mooBench.benchmark;
+package moobench.benchmark;
 
 /**
  * @author Jan Waller, Christian Wulf
diff --git a/src/mooBench/benchmark/BenchmarkingThreadMilli.java b/moobench/src/main/java/moobench/benchmark/BenchmarkingThreadMilli.java
similarity index 96%
rename from src/mooBench/benchmark/BenchmarkingThreadMilli.java
rename to moobench/src/main/java/moobench/benchmark/BenchmarkingThreadMilli.java
index 9f5e249a71ee7202c404b3269722ed5078484351..6fe6dde775b97617f88a9f6457c06e9d2086da4b 100644
--- a/src/mooBench/benchmark/BenchmarkingThreadMilli.java
+++ b/moobench/src/main/java/moobench/benchmark/BenchmarkingThreadMilli.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  ***************************************************************************/
 
-package mooBench.benchmark;
+package moobench.benchmark;
 
 import java.util.concurrent.CountDownLatch;
 
-import mooBench.monitoredApplication.MonitoredClass;
+import moobench.application.MonitoredClass;
 
 /**
  * @author Jan Waller
diff --git a/src/mooBench/benchmark/BenchmarkingThreadNano.java b/moobench/src/main/java/moobench/benchmark/BenchmarkingThreadNano.java
similarity index 97%
rename from src/mooBench/benchmark/BenchmarkingThreadNano.java
rename to moobench/src/main/java/moobench/benchmark/BenchmarkingThreadNano.java
index ad135b30c42f4e089639e922af706ac3f9e431a7..7baf0b6732d4c19fa8e084cafb1719c84b2b7fa7 100644
--- a/src/mooBench/benchmark/BenchmarkingThreadNano.java
+++ b/moobench/src/main/java/moobench/benchmark/BenchmarkingThreadNano.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  ***************************************************************************/
 
-package mooBench.benchmark;
+package moobench.benchmark;
 
 import java.lang.management.GarbageCollectorMXBean;
 import java.lang.management.ManagementFactory;
@@ -22,7 +22,7 @@ import java.lang.management.MemoryMXBean;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
-import mooBench.monitoredApplication.MonitoredClass;
+import moobench.application.MonitoredClass;
 
 /**
  * @author Jan Waller, Aike Sass, Christian Wulf
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..e7d9c6a9329df79ec9dfcff95b81c868b680f3e5
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,16 @@
+/*
+ * This file was generated by the Gradle 'init' task.
+ *
+ * The settings file is used to specify which projects to include in your build.
+ *
+ * Detailed information about configuring a multi-project build in Gradle can be found
+ * in the user manual at https://docs.gradle.org/6.5/userguide/multi_project_builds.html
+ */
+
+rootProject.name = 'moobench'
+
+include 'moobench'
+include 'frameworks:inspectIT'
+include 'frameworks:Kieker'
+include 'frameworks:SPASSmeter'
+
diff --git a/src/META-INF/.gitignore b/src/META-INF/.gitignore
deleted file mode 100644
index 5e7d2734cfc60289debf74293817c0a8f572ff32..0000000000000000000000000000000000000000
--- a/src/META-INF/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-# Ignore everything in this directory
-*
-# Except this file
-!.gitignore
diff --git a/src/mooBench/benchmark/Benchmark.java b/src/mooBench/benchmark/Benchmark.java
deleted file mode 100644
index b3377ea32b9ce04abdb143d22958c07b2ce0bb22..0000000000000000000000000000000000000000
--- a/src/mooBench/benchmark/Benchmark.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/***************************************************************************
- * Copyright 2014 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 mooBench.benchmark;
-
-import java.io.BufferedOutputStream;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.commons.cli.BasicParser;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.OptionBuilder;
-import org.apache.commons.cli.Options;
-
-import mooBench.monitoredApplication.MonitoredClass;
-import mooBench.monitoredApplication.MonitoredClassThreaded;
-
-/**
- * @author Jan Waller
- */
-public final class Benchmark {
-  private static final String ENCODING = "UTF-8";
-
-  private static PrintStream ps = null;
-  private static String outputFn = null;
-  private static int totalThreads = 0;
-  private static int totalCalls = 0;
-  private static long methodTime = 0;
-  private static int recursionDepth = 0;
-  private static boolean quickstart = false;
-  private static boolean forceTerminate = false;
-  private static MonitoredClass mc = null;
-
-  private Benchmark() {}
-
-  public static void main(final String[] args) throws InterruptedException {
-
-    // 1. Preparations
-    Benchmark.parseAndInitializeArguments(args);
-
-    System.out.println(" # Experiment run configuration:"); // NOPMD (System.out)
-    System.out.println(" # 1. Output filename " + Benchmark.outputFn); // NOPMD (System.out)
-    System.out.println(" # 2. Recursion Depth " + Benchmark.recursionDepth); // NOPMD (System.out)
-    System.out.println(" # 3. Threads " + Benchmark.totalThreads); // NOPMD (System.out)
-    System.out.println(" # 4. Total-Calls " + Benchmark.totalCalls); // NOPMD (System.out)
-    System.out.println(" # 5. Method-Time " + Benchmark.methodTime); // NOPMD (System.out)
-
-    // 2. Initialize Threads and Classes
-    final CountDownLatch doneSignal = new CountDownLatch(Benchmark.totalThreads);
-    final BenchmarkingThread[] benchmarkingThreads = new BenchmarkingThread[Benchmark.totalThreads];
-    final Thread[] threads = new Thread[Benchmark.totalThreads];
-    for (int i = 0; i < Benchmark.totalThreads; i++) {
-      benchmarkingThreads[i] = new BenchmarkingThreadNano(Benchmark.mc, Benchmark.totalCalls,
-          Benchmark.methodTime, Benchmark.recursionDepth, doneSignal);
-      threads[i] = new Thread(benchmarkingThreads[i], String.valueOf(i + 1));
-    }
-    if (!quickstart) {
-      for (int l = 0; l < 4; l++) {
-        { // NOCS (reserve mem only within the block)
-          final long freeMemChunks = Runtime.getRuntime().freeMemory() >> 27;
-          // System.out.println("Free-Mem: " + Runtime.getRuntime().freeMemory());
-          final int memSize = 128 * 1024 * 128; // memSize * 8 = total Bytes -> 128MB
-          for (int j = 0; j < freeMemChunks; j++) {
-            final long[] grabMemory = new long[memSize];
-            for (int i = 0; i < memSize; i++) {
-              grabMemory[i] = System.nanoTime();
-            }
-          }
-          // System.out.println("done grabbing memory...");
-          // System.out.println("Free-Mem: " + Runtime.getRuntime().freeMemory());
-        }
-        Thread.sleep(5000);
-      }
-    }
-    final long startTime = System.currentTimeMillis();
-    System.out.println(" # 6. Starting benchmark ..."); // NOPMD (System.out)
-    // 3. Starting Threads
-    for (int i = 0; i < Benchmark.totalThreads; i++) {
-      threads[i].start();
-    }
-
-    // 4. Wait for all Threads
-    try {
-      doneSignal.await();
-    } catch (final InterruptedException e) {
-      e.printStackTrace(); // NOPMD (Stacktrace)
-      System.exit(-1);
-    }
-    final long totalTime = System.currentTimeMillis() - startTime;
-    System.out.println(" #    done (" + TimeUnit.MILLISECONDS.toSeconds(totalTime) + " s)"); // NOPMD
-                                                                                             // (System.out)
-
-    // 5. Print experiment statistics
-    System.out.print(" # 7. Writing results ... "); // NOPMD (System.out)
-    // CSV Format: configuration;order_index;Thread-ID;duration_nsec
-    for (int h = 0; h < Benchmark.totalThreads; h++) {
-      final BenchmarkingThread thread = benchmarkingThreads[h];
-      for (int i = 0; i < Benchmark.totalCalls; i++) {
-        final String line = threads[h].getName() + ";" + thread.print(i, ";");
-        Benchmark.ps.println(line);
-      }
-    }
-    Benchmark.ps.close();
-
-    System.out.println("done"); // NOPMD (System.out)
-    System.out.println(" # "); // NOPMD (System.out)
-
-    if (forceTerminate) {
-      System.exit(0);
-    }
-  }
-
-  public static void parseAndInitializeArguments(final String[] args) {
-    final Options cmdlOpts = new Options();
-    OptionBuilder.withLongOpt("totalcalls");
-    OptionBuilder.withArgName("calls");
-    OptionBuilder.hasArg(true);
-    OptionBuilder.isRequired(true);
-    OptionBuilder
-        .withDescription("Number of total method calls performed.");
-    OptionBuilder.withValueSeparator('=');
-    cmdlOpts.addOption(OptionBuilder.create("t"));
-    OptionBuilder.withLongOpt("methodtime");
-    OptionBuilder.withArgName("time");
-    OptionBuilder.hasArg(true);
-    OptionBuilder.isRequired(true);
-    OptionBuilder.withDescription("Time a method call takes.");
-    OptionBuilder
-        .withValueSeparator('=');
-    cmdlOpts.addOption(OptionBuilder.create("m"));
-    OptionBuilder.withLongOpt("totalthreads");
-    OptionBuilder.withArgName("threads");
-    OptionBuilder.hasArg(true);
-    OptionBuilder.isRequired(true);
-    OptionBuilder
-        .withDescription("Number of threads started.");
-    OptionBuilder.withValueSeparator('=');
-    cmdlOpts.addOption(OptionBuilder.create("h"));
-    OptionBuilder.withLongOpt("recursiondepth");
-    OptionBuilder.withArgName("depth");
-    OptionBuilder.hasArg(true);
-    OptionBuilder.isRequired(true);
-    OptionBuilder
-        .withDescription("Depth of recursion performed.");
-    OptionBuilder.withValueSeparator('=');
-    cmdlOpts.addOption(OptionBuilder.create("d"));
-    OptionBuilder.withLongOpt("output-filename");
-    OptionBuilder.withArgName("filename");
-    OptionBuilder.hasArg(true);
-    OptionBuilder.isRequired(true);
-    OptionBuilder
-        .withDescription("Filename of results file. Output is appended if file exists.");
-    OptionBuilder.withValueSeparator('=');
-    cmdlOpts.addOption(OptionBuilder.create("o"));
-    OptionBuilder.withLongOpt("quickstart");
-    OptionBuilder.isRequired(false);
-    OptionBuilder.withDescription("Skips initial garbage collection.");
-    cmdlOpts.addOption(OptionBuilder.create("q"));
-    OptionBuilder.withLongOpt("forceTerminate");
-    OptionBuilder.isRequired(false);
-    OptionBuilder.withDescription("Forces a termination at the end of the benchmark.");
-    cmdlOpts.addOption(OptionBuilder
-        .create("f"));
-    OptionBuilder.withLongOpt("runnable");
-    OptionBuilder.withArgName("classname");
-    OptionBuilder.hasArg(true);
-    OptionBuilder.isRequired(false);
-    OptionBuilder
-        .withDescription(
-            "Class implementing the Runnable interface. run() method is executed before the benchmark starts.");
-    OptionBuilder.withValueSeparator('=');
-    cmdlOpts.addOption(OptionBuilder
-        .create("r"));
-    OptionBuilder.withLongOpt("application");
-    OptionBuilder.withArgName("classname");
-    OptionBuilder.hasArg(true);
-    OptionBuilder.isRequired(false);
-    OptionBuilder
-        .withDescription("Class implementing the MonitoredClass interface.");
-    OptionBuilder.withValueSeparator('=');
-    cmdlOpts.addOption(OptionBuilder
-        .create("a"));
-    OptionBuilder.withLongOpt("benchmarkthread");
-    OptionBuilder.withArgName("classname");
-    OptionBuilder.hasArg(true);
-    OptionBuilder.isRequired(false);
-    OptionBuilder
-        .withDescription("Class implementing the BenchmarkingThread interface.");
-    OptionBuilder.withValueSeparator('=');
-    cmdlOpts.addOption(OptionBuilder
-        .create("b"));
-    try {
-      CommandLine cmdl = null;
-      final CommandLineParser cmdlParser = new BasicParser();
-      cmdl = cmdlParser.parse(cmdlOpts, args);
-      Benchmark.outputFn = cmdl.getOptionValue("output-filename");
-      Benchmark.totalCalls = Integer.parseInt(cmdl.getOptionValue("totalcalls"));
-      Benchmark.methodTime = Integer.parseInt(cmdl.getOptionValue("methodtime"));
-      Benchmark.totalThreads = Integer.parseInt(cmdl.getOptionValue("totalthreads"));
-      Benchmark.recursionDepth = Integer.parseInt(cmdl.getOptionValue("recursiondepth"));
-      Benchmark.quickstart = cmdl.hasOption("quickstart");
-      Benchmark.forceTerminate = cmdl.hasOption("forceTerminate");
-      Benchmark.ps = new PrintStream(
-          new BufferedOutputStream(new FileOutputStream(Benchmark.outputFn, true), 8192 * 8), false,
-          Benchmark.ENCODING);
-      final String application = cmdl.getOptionValue("application");
-      if (null != application) {
-        mc = ((MonitoredClass) Class.forName(application).newInstance());
-      } else {
-        mc = new MonitoredClassThreaded();
-      }
-      final String clazzname = cmdl.getOptionValue("runnable");
-      if (null != clazzname) {
-        ((Runnable) Class.forName(clazzname).newInstance()).run();
-      }
-    } catch (final Exception ex) { // NOCS (e.g., IOException, ParseException,
-                                   // NumberFormatException)
-      new HelpFormatter().printHelp(Benchmark.class.getName(), cmdlOpts);
-      System.out.println(ex.toString()); // NOPMD (Stacktrace)
-      System.exit(-1);
-    }
-  }
-}