diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 5f6141660ade4083d3a425575c3dee5287fb4f56..1d92c8b275b99fa541d91b1753cbec0175c307dd 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -9,6 +9,7 @@ org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
 org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
@@ -22,8 +23,10 @@ org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
@@ -33,6 +36,8 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration
 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
 org.eclipse.jdt.core.formatter.blank_lines_after_package=1
@@ -53,6 +58,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
@@ -68,7 +74,7 @@ org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
 org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
 org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
 org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
-org.eclipse.jdt.core.formatter.comment.line_length=165
+org.eclipse.jdt.core.formatter.comment.line_length=100
 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
 org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
 org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
@@ -89,7 +95,8 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
 org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
-org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.indentation.size=2
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
@@ -98,6 +105,7 @@ org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
 org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
@@ -145,6 +153,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=inser
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
 org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
@@ -222,6 +231,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do n
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
@@ -276,16 +286,28 @@ org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
 org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
 org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
 org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=165
+org.eclipse.jdt.core.formatter.lineSplit=100
 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
 org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
 org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
-org.eclipse.jdt.core.formatter.tabulation.char=tab
-org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=2
 org.eclipse.jdt.core.formatter.use_on_off_tags=false
 org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
 org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
 org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
 org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
index 2c9a6e2f077b9657836e54c02783c5cc3b54d9d0..95fc2a88820bbb9ffab9b6c165fc4fa66eac643b 100644
--- a/.settings/org.eclipse.jdt.ui.prefs
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -11,10 +11,12 @@ cleanup.always_use_blocks=true
 cleanup.always_use_parentheses_in_expressions=true
 cleanup.always_use_this_for_non_static_field_access=true
 cleanup.always_use_this_for_non_static_method_access=true
+cleanup.convert_functional_interfaces=false
 cleanup.convert_to_enhanced_for_loop=true
 cleanup.correct_indentation=true
 cleanup.format_source_code=true
 cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
 cleanup.make_local_variable_final=true
 cleanup.make_parameters_final=true
 cleanup.make_private_fields_final=true
@@ -29,6 +31,7 @@ cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=tru
 cleanup.qualify_static_member_accesses_with_declaring_class=true
 cleanup.qualify_static_method_accesses_with_declaring_class=true
 cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=false
 cleanup.remove_trailing_whitespaces=true
 cleanup.remove_trailing_whitespaces_all=true
 cleanup.remove_trailing_whitespaces_ignore_empty=false
@@ -42,18 +45,20 @@ cleanup.remove_unused_private_methods=true
 cleanup.remove_unused_private_types=true
 cleanup.sort_members=false
 cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
 cleanup.use_blocks=true
 cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
 cleanup.use_parentheses_in_expressions=true
 cleanup.use_this_for_non_static_field_access=true
 cleanup.use_this_for_non_static_field_access_only_if_necessary=false
 cleanup.use_this_for_non_static_method_access=true
 cleanup.use_this_for_non_static_method_access_only_if_necessary=false
-cleanup_profile=_Kieker - Clean Up
+cleanup_profile=_eclipse-cs MooBench
 cleanup_settings_version=2
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_profile=_Kieker - Profile
+formatter_profile=_eclipse-cs MooBench
 formatter_settings_version=12
 org.eclipse.jdt.ui.ignorelowercasenames=true
 org.eclipse.jdt.ui.importorder=java;javax;junit;org;com;mooBench;kieker;kieker.test;
diff --git a/src/mooBench/benchmark/Benchmark.java b/src/mooBench/benchmark/Benchmark.java
index 57357a31f0db56bf68240450b06aaadbbf6344c9..b3377ea32b9ce04abdb143d22958c07b2ce0bb22 100644
--- a/src/mooBench/benchmark/Benchmark.java
+++ b/src/mooBench/benchmark/Benchmark.java
@@ -36,146 +36,205 @@ 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
-		long[] timings;
-		for (int h = 0; h < Benchmark.totalThreads; h++) {
-			timings = benchmarkingThreads[h].getTimings();
-			for (int i = 0; i < Benchmark.totalCalls; i++) {
-				Benchmark.ps.println(threads[h].getName() + ";" + timings[i]);
-			}
-		}
-		Benchmark.ps.close();
-
-		System.out.println("done"); // NOPMD (System.out)
-		System.out.println(" # "); // NOPMD (System.out)
-
-		if (forceTerminate) {
-			System.exit(0);
-		}
-	}
-
-	@SuppressWarnings("static-access")
-	public static void parseAndInitializeArguments(final String[] args) {
-		final Options cmdlOpts = new Options();
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("totalcalls").withArgName("calls").hasArg(true).isRequired(true)
-				.withDescription("Number of total method calls performed.").withValueSeparator('=').create("t"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("methodtime").withArgName("time").hasArg(true).isRequired(true).withDescription("Time a method call takes.")
-				.withValueSeparator('=').create("m"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("totalthreads").withArgName("threads").hasArg(true).isRequired(true)
-				.withDescription("Number of threads started.").withValueSeparator('=').create("h"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("recursiondepth").withArgName("depth").hasArg(true).isRequired(true)
-				.withDescription("Depth of recursion performed.").withValueSeparator('=').create("d"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("output-filename").withArgName("filename").hasArg(true).isRequired(true)
-				.withDescription("Filename of results file. Output is appended if file exists.").withValueSeparator('=').create("o"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("quickstart").isRequired(false).withDescription("Skips initial garbage collection.").create("q"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("forceTerminate").isRequired(false).withDescription("Forces a termination at the end of the benchmark.")
-				.create("f"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("runnable").withArgName("classname").hasArg(true).isRequired(false)
-				.withDescription("Class implementing the Runnable interface. run() method is executed before the benchmark starts.").withValueSeparator('=')
-				.create("r"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("application").withArgName("classname").hasArg(true).isRequired(false)
-				.withDescription("Class implementing the MonitoredClass interface.").withValueSeparator('=')
-				.create("a"));
-		cmdlOpts.addOption(OptionBuilder.withLongOpt("benchmarkthread").withArgName("classname").hasArg(true).isRequired(false)
-				.withDescription("Class implementing the BenchmarkingThread interface.").withValueSeparator('=')
-				.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);
-		}
-	}
+  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);
+    }
+  }
 }
diff --git a/src/mooBench/benchmark/BenchmarkingThread.java b/src/mooBench/benchmark/BenchmarkingThread.java
index 16bcda3a989e03fab14cee136087dcfb3084d1de..043ad1ad19ca8918ff5ece5b35d7d834a3980b67 100644
--- a/src/mooBench/benchmark/BenchmarkingThread.java
+++ b/src/mooBench/benchmark/BenchmarkingThread.java
@@ -17,9 +17,17 @@
 package mooBench.benchmark;
 
 /**
- * @author Jan Waller
+ * @author Jan Waller, Christian Wulf
  */
 public interface BenchmarkingThread extends Runnable {
 
-	public abstract long[] getTimings();
+  /**
+   * @param index
+   *          of the monitored call
+   * @param separatorString
+   *          used to separate the monitored entries
+   * @return all monitored entries for the given <code>index</code> separated by the given
+   *         <code>separatorString</code>
+   */
+  public String print(final int index, final String separatorString);
 }
diff --git a/src/mooBench/benchmark/BenchmarkingThreadMilli.java b/src/mooBench/benchmark/BenchmarkingThreadMilli.java
index 0d3f96657272abdb1d14431b267a6d15317a530c..9f5e249a71ee7202c404b3269722ed5078484351 100644
--- a/src/mooBench/benchmark/BenchmarkingThreadMilli.java
+++ b/src/mooBench/benchmark/BenchmarkingThreadMilli.java
@@ -25,41 +25,46 @@ import mooBench.monitoredApplication.MonitoredClass;
  */
 public final class BenchmarkingThreadMilli implements BenchmarkingThread {
 
-	private final MonitoredClass mc;
-	private final CountDownLatch doneSignal;
-	private final int totalCalls;
-	private final long methodTime;
-	private final int recursionDepth;
-	private final long[] timings;
+  private final MonitoredClass mc;
+  private final CountDownLatch doneSignal;
+  private final int totalCalls;
+  private final long methodTime;
+  private final int recursionDepth;
+  private final long[] timings;
 
-	public BenchmarkingThreadMilli(final MonitoredClass mc, final int totalCalls, final long methodTime, final int recursionDepth, final CountDownLatch doneSignal) {
-		this.mc = mc;
-		this.doneSignal = doneSignal;
-		this.totalCalls = totalCalls;
-		this.methodTime = methodTime;
-		this.recursionDepth = recursionDepth;
-		this.timings = new long[totalCalls];
-	}
+  public BenchmarkingThreadMilli(final MonitoredClass mc, final int totalCalls,
+      final long methodTime, final int recursionDepth, final CountDownLatch doneSignal) {
+    this.mc = mc;
+    this.doneSignal = doneSignal;
+    this.totalCalls = totalCalls;
+    this.methodTime = methodTime;
+    this.recursionDepth = recursionDepth;
+    this.timings = new long[totalCalls];
+  }
 
-	public final long[] getTimings() {
-		synchronized (this) {
-			return this.timings;
-		}
-	}
+  public final long[] getTimings() {
+    synchronized (this) {
+      return this.timings;
+    }
+  }
 
-	public final void run() {
-		long start_ns;
-		long stop_ns;
-		for (int i = 0; i < this.totalCalls; i++) {
-			start_ns = System.currentTimeMillis();
-			this.mc.monitoredMethod(this.methodTime, this.recursionDepth);
-			stop_ns = System.currentTimeMillis();
-			this.timings[i] = stop_ns - start_ns;
-			if ((i % 100000) == 0) {
-				System.out.println(i); // NOPMD (System.out)
-			}
-		}
-		this.doneSignal.countDown();
-	}
+  public String print(final int index, final String separatorString) {
+    return "" + this.timings[index];
+  }
+
+  public final void run() {
+    long start_ns;
+    long stop_ns;
+    for (int i = 0; i < this.totalCalls; i++) {
+      start_ns = System.currentTimeMillis();
+      this.mc.monitoredMethod(this.methodTime, this.recursionDepth);
+      stop_ns = System.currentTimeMillis();
+      this.timings[i] = stop_ns - start_ns;
+      if ((i % 100000) == 0) {
+        System.out.println(i); // NOPMD (System.out)
+      }
+    }
+    this.doneSignal.countDown();
+  }
 
 }
diff --git a/src/mooBench/benchmark/BenchmarkingThreadNano.java b/src/mooBench/benchmark/BenchmarkingThreadNano.java
index 936c549d7fc10bc9cb748d7181e21efbb9670baa..bd0a8c263f7e80b9b2e9a7e4e2d3235681b30ca5 100644
--- a/src/mooBench/benchmark/BenchmarkingThreadNano.java
+++ b/src/mooBench/benchmark/BenchmarkingThreadNano.java
@@ -16,50 +16,91 @@
 
 package mooBench.benchmark;
 
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
 import mooBench.monitoredApplication.MonitoredClass;
 
 /**
- * @author Jan Waller
+ * @author Jan Waller, Aike Sass, Christian Wulf
  */
 public final class BenchmarkingThreadNano implements BenchmarkingThread {
 
-	private final MonitoredClass mc;
-	private final CountDownLatch doneSignal;
-	private final int totalCalls;
-	private final long methodTime;
-	private final int recursionDepth;
-	private final long[] timings;
-
-	public BenchmarkingThreadNano(final MonitoredClass mc, final int totalCalls, final long methodTime, final int recursionDepth, final CountDownLatch doneSignal) {
-		this.mc = mc;
-		this.doneSignal = doneSignal;
-		this.totalCalls = totalCalls;
-		this.methodTime = methodTime;
-		this.recursionDepth = recursionDepth;
-		this.timings = new long[totalCalls];
-	}
-
-	public final long[] getTimings() {
-		synchronized (this) {
-			return this.timings;
-		}
-	}
-
-	public final void run() {
-		long start_ns;
-		long stop_ns;
-		for (int i = 0; i < this.totalCalls; i++) {
-			start_ns = System.nanoTime();
-			this.mc.monitoredMethod(this.methodTime, this.recursionDepth);
-			stop_ns = System.nanoTime();
-			this.timings[i] = stop_ns - start_ns;
-			if ((i % 100000) == 0) {
-				System.out.println(i); // NOPMD (System.out)
-			}
-		}
-		this.doneSignal.countDown();
-	}
+  private final MonitoredClass mc;
+  private final CountDownLatch doneSignal;
+  private final int totalCalls;
+  private final long methodTime;
+  private final int recursionDepth;
+
+  private final long[] timings;
+
+  private final long[] usedHeapMemory;
+  private final MemoryMXBean memory;
+
+  private final List<GarbageCollectorMXBean> collector;
+
+  public BenchmarkingThreadNano(final MonitoredClass mc, final int totalCalls,
+      final long methodTime, final int recursionDepth, final CountDownLatch doneSignal) {
+    this.mc = mc;
+    this.doneSignal = doneSignal;
+    this.totalCalls = totalCalls;
+    this.methodTime = methodTime;
+    this.recursionDepth = recursionDepth;
+    // for monitoring execution times
+    this.timings = new long[totalCalls];
+    // for monitoring memory consumption
+    this.memory = ManagementFactory.getMemoryMXBean();
+    this.usedHeapMemory = new long[totalCalls];
+    // for monitoring the garbage collector
+    this.collector = ManagementFactory.getGarbageCollectorMXBeans();
+  }
+
+  public String print(final int index, final String separatorString) {
+    return "" + this.timings[index] /* + separatorString + this.usedHeapMemory[index] */;
+  }
+
+  public final void run() {
+    long start_ns;
+    long stop_ns;
+    final long gcBefore;
+    final long gcAfter;
+
+    for (int i = 0; i < this.totalCalls; i++) {
+      // gcBefore = this.computeGcCollectionCount();
+      start_ns = this.getCurrentTimestamp();
+
+      this.mc.monitoredMethod(this.methodTime, this.recursionDepth);
+
+      stop_ns = this.getCurrentTimestamp();
+      // gcAfter = this.computeGcCollectionCount();
+
+      // save execution time
+      this.timings[i] = stop_ns - start_ns;
+      if ((i % 100000) == 0) {
+        System.out.println(i); // NOPMD (System.out)
+      }
+      // save heap memory
+      this.usedHeapMemory[i] = this.memory.getHeapMemoryUsage().getUsed();
+    }
+
+    this.doneSignal.countDown();
+  }
+
+  private long computeGcCollectionCount() {
+    long count = 0;
+    for (final GarbageCollectorMXBean bean : this.collector) {
+      count += bean.getCollectionCount();
+      // bean.getCollectionTime()
+    }
+    return count;
+  }
+
+  private long getCurrentTimestamp() {
+    // alternatively: System.currentTimeMillis();
+    return System.nanoTime();
+  }
 
 }