diff --git a/Jenkinsfile b/Jenkinsfile
index c988db31fa1a96858952d4a4166aa91c3e610998..353d723548073c3f55cb9dd4a95833af2333a399 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -63,16 +63,19 @@ pipeline {
           sshagent(credentials: ['kieker-irl-key']) {
              unstash 'yaml'
              sh '''
-                 echo "put kieker-python-results.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
-                 echo "put kieker-java-results.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
-                 echo "put open-telementry-results.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
-                 echo "put insepct-it-results.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
-#	         sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/all-results.json
-#                 compile-results/bin/compile-results results-Kieker/results-text.csv all-results.json
-#                 echo "put all-results.json" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
-#                 echo "put partial-results.json" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
-#                 echo "put relative-results.json" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
-                '''
+                 mkdir all
+                 cd all
+	         sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/kieker-java.yaml
+	         sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/kieker-python.yaml
+#	         sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/opentelemetry.yaml
+#	         sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}/inspectit.yaml
+                 cd ..
+                 compile-results/bin/compile-results -i *-results.yaml -l all -t all -j all -w 100
+                 cd all
+                 echo "put *.yaml" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
+                 echo "put *.html" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
+                 echo "put *.json" | sftp -oNoHostAuthenticationForLocalhost=yes -oStrictHostKeyChecking=no -oUser=repo  -F /dev/null -i ${KEYSTORE} ${UPDATE_SITE_URL}
+               '''
           }
        }
        post {
diff --git a/frameworks/Kieker/java/benchmark.sh b/frameworks/Kieker/java/benchmark.sh
index f415b3b455a57680a2c914dc6221ddf8a2614ffe..3ceefc51b6839d5bfe619aa0c7c14766d59ad016 100755
--- a/frameworks/Kieker/java/benchmark.sh
+++ b/frameworks/Kieker/java/benchmark.sh
@@ -55,6 +55,12 @@ info "----------------------------------"
 info "Setup..."
 info "----------------------------------"
 
+# This is necessary, as the framework name is originally
+# derived from the directory the script is sitting in, but
+# Kieker supports multiple languages and has multiple
+# sub directories for each programming language.
+export FRAMEWORK_NAME="kieker-${FRAMEWORK_NAME}"
+
 cd "${BASE_DIR}"
 
 # load agent
diff --git a/frameworks/Kieker/python/benchmark.sh b/frameworks/Kieker/python/benchmark.sh
index cdb96b4213e37782f09dca9d5c8273cb0539405f..30cc37b8e221dd0def1a9959052e80aec4944a73 100755
--- a/frameworks/Kieker/python/benchmark.sh
+++ b/frameworks/Kieker/python/benchmark.sh
@@ -55,6 +55,12 @@ info "----------------------------------"
 info "Setup..."
 info "----------------------------------"
 
+# This is necessary, as the framework name is originally
+# derived from the directory the script is sitting in, but
+# Kieker supports multiple languages and has multiple
+# sub directories for each programming language.
+export FRAMEWORK_NAME="kieker-${FRAMEWORK_NAME}"
+
 cd "${BASE_DIR}"
 
 # load agent
diff --git a/frameworks/statistics.r b/frameworks/statistics.r
index 34434e0457f7da615703e52742864513a0b5d9eb..3906626122abec4817700bbe87e292822b98480f 100644
--- a/frameworks/statistics.r
+++ b/frameworks/statistics.r
@@ -90,19 +90,27 @@ print(resultstext)
 
 currentTime <- as.numeric(Sys.time())
 
+mktext <- function(value) {
+    if (is.na(value)) {
+       return(".NAN")
+    } else {
+       return(format(value, scientific=TRUE))
+    }
+}
+
 write(paste("kind:", configs.framework_name), file=out_yaml_fn,append=FALSE)
 write("experiments:", file=out_yaml_fn, append=TRUE)
 write(paste("- timestamp:", currentTime), file=out_yaml_fn, append=TRUE)
 write("  measurements:", file=out_yaml_fn, append=TRUE)
 for (writer_idx in (1:(numberOfWriters))) {
    write(paste("    ", configs.labels[writer_idx], ": [", 
-      format(printvalues["mean",writer_idx], scientific=TRUE), ",",
-      format(printvalues["sd",writer_idx], scientific=TRUE), ",", 
-      format(printvalues["ci95%",writer_idx], scientific=TRUE), ",",
-      format(printvalues["md25%",writer_idx], scientific=TRUE), ",",
-      format(printvalues["md50%",writer_idx], scientific=TRUE), ",",
-      format(printvalues["md75%",writer_idx], scientific=TRUE), ",",
-      format(printvalues["max",writer_idx], scientific=TRUE), ",",
-      format(printvalues["min",writer_idx], scientific=TRUE), "]"), file=out_yaml_fn, append=TRUE)
+      mktext(printvalues["mean",writer_idx]), ",",
+      mktext(printvalues["sd",writer_idx]), ",", 
+      mktext(printvalues["ci95%",writer_idx]), ",",
+      mktext(printvalues["md25%",writer_idx]), ",",
+      mktext(printvalues["md50%",writer_idx]), ",",
+      mktext(printvalues["md75%",writer_idx]), ",",
+      mktext(printvalues["max",writer_idx]), ",",
+      mktext(printvalues["min",writer_idx]), "]"), file=out_yaml_fn, append=TRUE)
 }
 # end
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/ChartAssemblerStage.java b/tools/compile-results/src/main/java/moobench/tools/results/ChartAssemblerStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..66a525b46faca72122c887e71ac21ea7a237ce61
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/ChartAssemblerStage.java
@@ -0,0 +1,57 @@
+/**
+ * 
+ */
+package moobench.tools.results;
+
+import java.util.List;
+import java.util.Map;
+
+import moobench.tools.results.data.Chart;
+import moobench.tools.results.data.Experiment;
+import moobench.tools.results.data.ExperimentLog;
+import moobench.tools.results.data.Measurements;
+import moobench.tools.results.data.ValueTuple;
+import teetime.stage.basic.AbstractTransformation;
+
+/**
+ * @author Reiner Jung
+ * @since 1.3.0
+ *
+ */
+public class ChartAssemblerStage extends AbstractTransformation<ExperimentLog, Chart> {
+
+	@Override
+	protected void execute(ExperimentLog element) throws Exception {
+		Chart chart = new Chart(element.getKind());
+		for (Experiment experiment : element.getExperiments()) {
+			long timestamp = Double.valueOf(experiment.getTimestamp()).longValue();
+			ValueTuple tuple = new ValueTuple(timestamp);
+			
+			addHeaderIfMissing(chart.getHeaders(), experiment.getMeasurements());
+			fillInData(chart.getHeaders(), tuple.getValues(), experiment.getMeasurements());
+			
+			chart.getValues().add(tuple);
+		}
+		
+		this.outputPort.send(chart);
+	}
+
+	private void fillInData(List<String> headers, List<Double> values, Map<String, Measurements> measurements) {
+		for (String key : headers) {
+			Measurements value = measurements.get(key);
+			if (value != null) {
+				values.add(value.getMean());
+			} else
+				values.add(Double.NaN);
+		}
+	}
+
+	private void addHeaderIfMissing(List<String> headers, Map<String, Measurements> measurements) {
+		for (String key : measurements.keySet()) {
+			if (!headers.stream().anyMatch(header -> header.equals(key))) {
+				headers.add(key);
+			}
+		}		
+	}
+
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/CompileResultsMain.java b/tools/compile-results/src/main/java/moobench/tools/results/CompileResultsMain.java
index 8035cf4580510889fb33d0ba0c8a23912075d43b..9dd450d1a594012ba0e5bbdbf81bc3c224f0655f 100644
--- a/tools/compile-results/src/main/java/moobench/tools/results/CompileResultsMain.java
+++ b/tools/compile-results/src/main/java/moobench/tools/results/CompileResultsMain.java
@@ -4,8 +4,6 @@
 package moobench.tools.results;
 
 import java.io.File;
-import java.nio.file.Files;
-import java.nio.file.Path;
 
 import com.beust.jcommander.JCommander;
 
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/ComputeTableStage.java b/tools/compile-results/src/main/java/moobench/tools/results/ComputeTableStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd341abdc9eeaed100de5ddf7db9ea981d00c923
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/ComputeTableStage.java
@@ -0,0 +1,63 @@
+/**
+ *
+ */
+package moobench.tools.results;
+
+import java.util.List;
+import java.util.Map.Entry;
+
+import moobench.tools.results.data.Experiment;
+import moobench.tools.results.data.ExperimentLog;
+import moobench.tools.results.data.Measurements;
+import moobench.tools.results.data.TableInformation;
+import teetime.stage.basic.AbstractTransformation;
+
+/**
+ * @author reiner
+ *
+ */
+public class ComputeTableStage extends AbstractTransformation<ExperimentLog, TableInformation> {
+
+    @Override
+    protected void execute(final ExperimentLog log) throws Exception {
+        final List<Experiment> experiments = log.getExperiments();
+        if (experiments.size() > 0) {
+            final Experiment current = experiments.get(experiments.size()-1);
+            int first = experiments.size() - 10;
+            int last = experiments.size() - 2;
+            if (first < 0) {
+                first = 0;
+            }
+            if (last < 0) {
+                last = 0;
+            }
+            final Experiment previous = new Experiment();
+            for (int i = first; i < last; i++) {
+                final Experiment experiment = experiments.get(i);
+                for (final Entry<String, Measurements> entry : experiment.getMeasurements().entrySet()) {
+                    final Measurements measurements = entry.getValue();
+                    if (!previous.getMeasurements().containsKey(entry.getKey())) {
+                        previous.getMeasurements().put(entry.getKey(), measurements);
+                    } else {
+                        final Measurements previousMeasurements = previous.getMeasurements().get(entry.getKey());
+                        previous.getMeasurements().put(entry.getKey(), this.computePrevious(previousMeasurements, measurements));
+                    }
+                }
+            }
+
+            this.outputPort.send(new TableInformation(log.getKind(), current, previous));
+        }
+    }
+
+    private Measurements computePrevious(final Measurements previousMeasurements, final Measurements measurements) {
+        return new Measurements((measurements.getMean() + previousMeasurements.getMean())/2,
+                (measurements.getStandardDeviation() + previousMeasurements.getStandardDeviation())/2,
+                (measurements.getConvidence() + previousMeasurements.getConvidence())/2,
+                (measurements.getLowerQuartile() + previousMeasurements.getLowerQuartile())/2,
+                (measurements.getMedian() + previousMeasurements.getMedian())/2,
+                (measurements.getUpperQuartile() + previousMeasurements.getUpperQuartile())/2,
+                (measurements.getMin() + previousMeasurements.getMin())/2,
+                (measurements.getMax() + previousMeasurements.getMax())/2);
+    }
+
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/ElementProducer.java b/tools/compile-results/src/main/java/moobench/tools/results/ElementProducer.java
index 3695517d76fb50007e1e548a037bac8eab48d7fb..e27cafb71d0e05e4313ec50874dd2e94aec99c01 100644
--- a/tools/compile-results/src/main/java/moobench/tools/results/ElementProducer.java
+++ b/tools/compile-results/src/main/java/moobench/tools/results/ElementProducer.java
@@ -25,8 +25,10 @@ public class ElementProducer<O> extends AbstractProducerStage<O> {
 	@Override
 	protected void execute() throws Exception {
 		for (O element : elements) {
+			this.logger.debug(String.format("Reading log %s", element));
 			this.outputPort.send(element);
 		}
+		this.workCompleted();
 	}
 
 }
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/FileSink.java b/tools/compile-results/src/main/java/moobench/tools/results/FileSink.java
new file mode 100644
index 0000000000000000000000000000000000000000..df1b3e00e9398f502396756d1464a2f769e0d94b
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/FileSink.java
@@ -0,0 +1,22 @@
+package moobench.tools.results;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+
+import moobench.tools.results.data.OutputFile;
+import teetime.framework.AbstractConsumerStage;
+
+public class FileSink extends AbstractConsumerStage<OutputFile> {
+
+    @Override
+    protected void execute(final OutputFile outputFile) throws Exception {
+        try (final BufferedWriter writer = Files.newBufferedWriter(outputFile.getFilePath())) {
+            writer.write(outputFile.getContent());
+            writer.close();
+        } catch(final IOException e) {
+            this.logger.error("Cannot write file {}", outputFile.getFilePath().toString());
+        }
+    }
+
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/GenerateHtmlTableStage.java b/tools/compile-results/src/main/java/moobench/tools/results/GenerateHtmlTableStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..4780590a2bc3dbf3ec1044e6eb716c5985f241ff
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/GenerateHtmlTableStage.java
@@ -0,0 +1,75 @@
+package moobench.tools.results;
+
+import java.nio.file.Path;
+import java.util.Set;
+
+import moobench.tools.results.data.Measurements;
+import moobench.tools.results.data.OutputFile;
+import moobench.tools.results.data.TableInformation;
+import teetime.stage.basic.AbstractTransformation;
+
+public class GenerateHtmlTableStage extends AbstractTransformation<TableInformation, OutputFile> {
+
+    private final Path tablePath;
+
+    public GenerateHtmlTableStage(final Path tablePath) {
+        this.tablePath = tablePath;
+    }
+
+    @Override
+    protected void execute(final TableInformation element) throws Exception {
+        String content = "<table>\n" + "  <tr>\n" + "    <th>setup</th>\n" + "    <th>run</th>\n"
+                + "    <th>mean</th>\n" + "    <th>ci</th>\n" + "    <th>sd</th>\n" + "    <th>1.quartile</th>\n"
+                + "    <th>median</th>\n" + "    <th>3.quartile</th>\n" + "    <th>min</th>\n" + "    <th>max</th>\n"
+                + "  </tr>\n";
+        final Set<String> currentKeySet = element.getCurrent().getMeasurements().keySet();
+        final Set<String> previousKeySet = element.getPrevious().getMeasurements().keySet();
+        final Set<String> completeKeySet = new OrderedSet<>();
+        if (currentKeySet != null) {
+            completeKeySet.addAll(currentKeySet);
+        }
+        if (previousKeySet != null) {
+            completeKeySet.addAll(previousKeySet);
+        }
+
+        for (final String key : completeKeySet) {
+            content += this.addMode(key, element.getCurrent().getMeasurements().get(key),
+                    element.getPrevious().getMeasurements().get(key));
+        }
+        content += "</table>\n";
+        this.outputPort.send(new OutputFile(this.tablePath.resolve(element.getName() + ".html"), content));
+    }
+
+    private String addMode(final String key, final Measurements current, final Measurements previous) {
+        String result = "";
+        if (current != null) {
+            result = this.createRow(key, "current", current);
+        }
+        if (previous != null) {
+            result += this.createRow(key, "past", previous);
+        }
+        return result;
+    }
+
+    private String createRow(final String key, final String run, final Measurements measurements) {
+        final StringBuilder cells = new StringBuilder();
+        cells.append(String.format("    <td style=\"text-align: left;\">%s</td>\n", key));
+        cells.append(String.format("    <td style=\"text-align: left;\">%s</td>\n", run));
+
+        this.addDouble(cells, measurements.getMean());
+        this.addDouble(cells, measurements.getConvidence());
+        this.addDouble(cells, measurements.getStandardDeviation());
+        this.addDouble(cells, measurements.getLowerQuartile());
+        this.addDouble(cells, measurements.getMedian());
+        this.addDouble(cells, measurements.getUpperQuartile());
+        this.addDouble(cells, measurements.getMin());
+        this.addDouble(cells, measurements.getMax());
+
+        return String.format("  <tr>\n%s  </tr>\n", cells.toString());
+    }
+
+    private StringBuilder addDouble(final StringBuilder cells, final Double value) {
+        return cells.append(String.format("    <td style=\"text-align: right;\">%1.2f</td>\n", value));
+    }
+
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/JsonLogSink.java b/tools/compile-results/src/main/java/moobench/tools/results/JsonLogSink.java
new file mode 100644
index 0000000000000000000000000000000000000000..9dd23fc882e55d1e5a9147d3916f523ba3ed5bd2
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/JsonLogSink.java
@@ -0,0 +1,44 @@
+package moobench.tools.results;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import moobench.tools.results.data.Chart;
+import moobench.tools.results.data.ValueTuple;
+import teetime.framework.AbstractConsumerStage;
+
+public class JsonLogSink extends AbstractConsumerStage<Chart> {
+
+	private Path path;
+
+	public JsonLogSink(Path path) {
+		this.path = path;
+	}
+
+	@Override
+	protected void execute(Chart chart) throws Exception {
+		Path jsonLog = this.path.resolve(chart.getName() + ".json");
+	    ObjectMapper mapper = new ObjectMapper();
+	    
+		ObjectNode node = mapper.createObjectNode();
+		ArrayNode arrayNode = node.putArray("results");
+		
+		for(ValueTuple value : chart.getValues()) {
+			ObjectNode objectNode = mapper.createObjectNode();
+			for (int i = 0;i < chart.getHeaders().size();i++) {
+				String name = chart.getHeaders().get(i);
+				Double number = value.getValues().get(i);
+				objectNode.put(name, number);
+			}
+			objectNode.put("time", value.getTimestamp());
+			arrayNode.add(objectNode);
+		}
+		
+		mapper.writeValue(Files.newBufferedWriter(jsonLog), node);
+	}
+
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/LogAppenderStage.java b/tools/compile-results/src/main/java/moobench/tools/results/LogAppenderStage.java
index 0c7f4664fe3af86c746770efc79756a9ff928160..128eab4cf5052ab4ca8741e55caeade98ea12722 100644
--- a/tools/compile-results/src/main/java/moobench/tools/results/LogAppenderStage.java
+++ b/tools/compile-results/src/main/java/moobench/tools/results/LogAppenderStage.java
@@ -3,56 +3,37 @@
  */
 package moobench.tools.results;
 
+import java.util.HashMap;
 import java.util.Map;
 
 import moobench.tools.results.data.Experiment;
 import moobench.tools.results.data.ExperimentLog;
-import teetime.framework.AbstractStage;
-import teetime.framework.InputPort;
+import teetime.framework.AbstractConsumerStage;
 import teetime.framework.OutputPort;
 
 /**
  * @author Reiner Jung
  * @since 1.3.0
  */
-public class LogAppenderStage extends AbstractStage {
+public class LogAppenderStage extends AbstractConsumerStage<ExperimentLog> {
 
-	private final InputPort<ExperimentLog> newDataInputPort = this.createInputPort(ExperimentLog.class);
-	private final InputPort<ExperimentLog> logInputPort = this.createInputPort(ExperimentLog.class);
 	private final OutputPort<ExperimentLog> outputPort = this.createOutputPort(ExperimentLog.class);
 	
-	private Map<String,ExperimentLog> logs;
-
-	public InputPort<ExperimentLog> getNewDataInputPort() {
-		return newDataInputPort;
-	}
-	
-	public InputPort<ExperimentLog> getLogInputPort() {
-		return logInputPort;
-	}
+	private Map<String,ExperimentLog> logs = new HashMap<>();
 	
 	public OutputPort<ExperimentLog> getOutputPort() {
 		return outputPort;
 	}
 	
 	@Override
-	protected void execute() throws Exception {
-		ExperimentLog newData = this.newDataInputPort.receive();
-		if (newData != null) {
-			appendData(newData);
-		}
-		ExperimentLog logData = this.logInputPort.receive();
-		if (logData != null) {
-			appendData(logData);
-		}
-	}
-	
-	private void appendData(ExperimentLog newData) {
-		ExperimentLog presentLog = logs.get(newData.getKind());
+	protected void execute(ExperimentLog log) throws Exception {
+		ExperimentLog presentLog = logs.get(log.getKind());
 		if (presentLog != null) {
-			for (Experiment experiment : newData.getExperiments()) {
+			for (Experiment experiment : log.getExperiments()) {
 				presentLog.getExperiments().add(experiment);
 			}
+		} else {
+			logs.put(log.getKind(), log);
 		}
 	}
 	
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/LogWriter.java b/tools/compile-results/src/main/java/moobench/tools/results/LogWriter.java
deleted file mode 100644
index cce1495031ebb4cf3d231afec6ee0367fa25de21..0000000000000000000000000000000000000000
--- a/tools/compile-results/src/main/java/moobench/tools/results/LogWriter.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package moobench.tools.results;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import teetime.framework.AbstractConsumerStage;
-
-public class LogWriter extends AbstractConsumerStage<List<Map<String,JsonNode>>> {
-	
-	private Path logJson;
-
-	public LogWriter(Path logJson) {
-		this.logJson = logJson;
-	}
-
-	@Override
-	protected void execute(List<Map<String,JsonNode>> list) throws Exception {
-		ObjectMapper mapper = new ObjectMapper();
-		ObjectNode node = mapper.createObjectNode();
-		ArrayNode arrayNode = node.putArray("results");
-		
-		for(Map<String, JsonNode> map : list) {
-			ObjectNode objectNode = mapper.createObjectNode();
-			for (Entry<String, JsonNode> entry : map.entrySet()) {
-				JsonNode value = entry.getValue();
-				if (value.isDouble())
-					objectNode.put(entry.getKey(), value.asDouble());
-				else if (value.isInt())
-					objectNode.put(entry.getKey(), value.asInt());
-				else
-					this.logger.warn("property {} is of type {}", entry.getKey(), value.getNodeType().toString());
-			}
-			arrayNode.add(objectNode);
-		}
-		
-		mapper.writeValue(Files.newBufferedWriter(logJson), node);
-	}
-
-}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/MainLogReader.java b/tools/compile-results/src/main/java/moobench/tools/results/MainLogReader.java
deleted file mode 100644
index f22e2aecebc783488b302b8290d9473edc689e0c..0000000000000000000000000000000000000000
--- a/tools/compile-results/src/main/java/moobench/tools/results/MainLogReader.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * 
- */
-package moobench.tools.results;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import teetime.framework.AbstractProducerStage;
-
-/**
- * @author reiner
- *
- */
-public class MainLogReader extends AbstractProducerStage<List<Map<String,JsonNode>>> {
-	
-	private static final String RESULTS_LABEL = "results";
-
-	private final Path mainLogJson;
-
-	public MainLogReader(Path mainLogJson) {
-		this.mainLogJson = mainLogJson;
-	}
-
-	@Override
-	protected void execute() throws JsonProcessingException, IOException {
-		List<Map<String,JsonNode>> result = new ArrayList<Map<String,JsonNode>>();
-		JsonNode node;
-		if (Files.exists(mainLogJson)) {
-			node = readJsonFile();
-		} else {
-			node = readJsonString();
-		}
-		
-		JsonNode resultsNode = node.get(RESULTS_LABEL);
-		if ((resultsNode instanceof ArrayNode)) {
-			ArrayNode arrayNode = (ArrayNode)resultsNode;
-			Iterator<JsonNode> iterator = arrayNode.elements();
-			while (iterator.hasNext()) {
-				JsonNode element = iterator.next();
-				if (element instanceof ObjectNode) {
-					ObjectNode objectNode = (ObjectNode)element;
-										
-					Iterator<Entry<String, JsonNode>> elementIterator = objectNode.fields();
-					Map<String,JsonNode> row = new HashMap<>();
-					while (elementIterator.hasNext()) {
-						Entry<String, JsonNode> parameter = elementIterator.next();
-						row.put(parameter.getKey(), parameter.getValue());
-					}
-					result.add(row);
-				}
-			}
-		}
-		
-		this.outputPort.send(result);
-		this.workCompleted();
-	}
-	
-
-	
-	private JsonNode readJsonString() throws JsonMappingException, JsonProcessingException {
-		ObjectMapper mapper = new ObjectMapper();
-		String value = "{ \"results\" : [] }";
-		return mapper.readTree(value);
-	}
-
-	private JsonNode readJsonFile() throws JsonProcessingException, IOException {
-		ObjectMapper mapper = new ObjectMapper();
-		return mapper.readTree(Files.newInputStream(mainLogJson));
-	}
-
-}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/MappingFileReader.java b/tools/compile-results/src/main/java/moobench/tools/results/MappingFileReader.java
deleted file mode 100644
index 30e3de105393d6f6a5f6403ca055c24f5baaa72a..0000000000000000000000000000000000000000
--- a/tools/compile-results/src/main/java/moobench/tools/results/MappingFileReader.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package moobench.tools.results;
-
-import java.nio.file.Path;
-import java.util.Map;
-
-import teetime.framework.AbstractProducerStage;
-
-public class MappingFileReader extends AbstractProducerStage<Map<String,String>> {
-
-	public MappingFileReader(Path mappingFile) {
-		// TODO Auto-generated constructor stub
-	}
-
-	@Override
-	protected void execute() throws Exception {
-		// TODO Auto-generated method stub
-		this.workCompleted();
-	}
-
-}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/MergeDataStage.java b/tools/compile-results/src/main/java/moobench/tools/results/MergeDataStage.java
deleted file mode 100644
index 85cd673c0cd9be0f43ca6b5596adf663eee10aa8..0000000000000000000000000000000000000000
--- a/tools/compile-results/src/main/java/moobench/tools/results/MergeDataStage.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package moobench.tools.results;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import teetime.framework.AbstractStage;
-import teetime.framework.InputPort;
-import teetime.framework.OutputPort;
-
-public class MergeDataStage extends AbstractStage {
-	
-	private static final String BUILD_LABEL = "build";
-
-	private final InputPort<Map<String, String>> mappingInputPort = this.createInputPort();
-	private final InputPort<List<Map<String, JsonNode>>> mainLogInputPort = this.createInputPort();
-	private final InputPort<Map<String, JsonNode>> newDataInputPort = this.createInputPort();
-
-	private final OutputPort<List<Map<String, JsonNode>>> outputPort = this.createOutputPort();
-	
-	private List<Map<String, JsonNode>> mainLog;
-	private List<Map<String, JsonNode>> bufferLog = new ArrayList<>();
-	private Map<String, String> mapping;
-
-	
-	@Override
-	protected void execute() throws Exception {
-		List<Map<String, JsonNode>> log = this.mainLogInputPort.receive();
-		if (log != null) {
-			mainLog = log;
-		}
-		Map<String, String> newMapping = this.mappingInputPort.receive();
-		if (newMapping != null) {
-			mapping = newMapping;
-		}
-		Map<String, JsonNode> newData = this.newDataInputPort.receive();
-		if (newData != null) {
-			bufferLog.add(newData);
-		}
-	}
-		
-	@Override
-	protected void onTerminating() {
-		moveNewData();
-		this.outputPort.send(mainLog);
-		super.onTerminating();
-	}
-	
-	private void moveNewData() {
-		int last = mainLog.size()-1;
-		int build = mainLog.get(last).get(BUILD_LABEL).asInt() + 1;
-		
-		Map<String,JsonNode> node = new HashMap<>();
-		node.put(BUILD_LABEL, new ObjectMapper().getNodeFactory().numberNode(build));
-		
-		for (Map<String, JsonNode> data : bufferLog) {
-			for (Entry<String, JsonNode> entry : data.entrySet()) {
-				node.put(entry.getKey(), entry.getValue());
-			}
-		}
-		bufferLog.clear();
-		mainLog.add(node);
-	}
-
-
-	public InputPort<List<Map<String, JsonNode>>> getMainLogInputPort() {
-		return this.mainLogInputPort;
-	}
-
-	public InputPort<Map<String,String>> getMappingInputPort() {
-		return this.mappingInputPort;
-	}
-
-	public InputPort<Map<String,JsonNode>> getNewDataInputPort() {
-		return this.newDataInputPort ;
-	}
-
-	public OutputPort<List<Map<String, JsonNode>>> getOutputPort() {
-		return this.outputPort;
-	}
-
-}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/OrderedSet.java b/tools/compile-results/src/main/java/moobench/tools/results/OrderedSet.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2f6bb66fb8bdc84963dbe66b8d215ec4a373e86
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/OrderedSet.java
@@ -0,0 +1,29 @@
+package moobench.tools.results;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+
+public class OrderedSet<T> extends ArrayList<T> implements Set<T> {
+
+    private static final long serialVersionUID = 719655465496957772L;
+
+    @Override
+    public boolean add(final T value) {
+        if (!super.contains(value)) {
+            return super.add(value);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean addAll(final Collection<? extends T> values) {
+        boolean changed = false;
+        for(final T value : values) {
+            changed |= this.add(value);
+        }
+        return changed;
+    }
+
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/SpecialArrayElementStage.java b/tools/compile-results/src/main/java/moobench/tools/results/SpecialArrayElementStage.java
deleted file mode 100644
index 0579d9997a48952474eacc23f8807150447364c2..0000000000000000000000000000000000000000
--- a/tools/compile-results/src/main/java/moobench/tools/results/SpecialArrayElementStage.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package moobench.tools.results;
-
-import java.nio.file.Path;
-import java.util.List;
-
-import teetime.framework.AbstractProducerStage;
-
-public class SpecialArrayElementStage extends AbstractProducerStage<Path> {
-
-	private List<Path> resultCsvPaths;
-
-	public SpecialArrayElementStage(List<Path> resultCsvPaths) {
-		this.resultCsvPaths = resultCsvPaths;
-	}
-
-	@Override
-	protected void execute() throws Exception {
-		for(Path path : resultCsvPaths) {
-			this.outputPort.send(path);
-		}
-		this.workCompleted();
-	}
-}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/TailChartStage.java b/tools/compile-results/src/main/java/moobench/tools/results/TailChartStage.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d0e484918c8b7e438fe332a210c3c2ae89e3e7f
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/TailChartStage.java
@@ -0,0 +1,40 @@
+/**
+ * 
+ */
+package moobench.tools.results;
+
+import moobench.tools.results.data.Chart;
+import teetime.stage.basic.AbstractFilter;
+
+/**
+ * @author reiner
+ *
+ */
+public class TailChartStage extends AbstractFilter<Chart> {
+
+	private Integer window;
+
+	public TailChartStage(Integer window) {
+		this.window = window;
+	}
+
+	@Override
+	protected void execute(Chart chart) throws Exception {
+		if (window != null) {
+			int size = chart.getValues().size();
+			if (size > window) {
+				Chart newChart = new Chart(chart.getName());
+				newChart.getHeaders().addAll(chart.getHeaders());
+				for (int i = size - window; i < size;i++) {
+					newChart.getValues().add(chart.getValues().get(i));
+				}
+				this.outputPort.send(newChart);
+			} else {
+				this.outputPort.send(chart);
+			}
+		} else {
+			this.outputPort.send(chart);
+		}
+	}
+
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java b/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java
index 8232d5c4eec39fc0a85dfcc8eeacb2f32a882171..90b56acf33b3bfe64942f24efe9288786e093187 100644
--- a/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java
+++ b/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java
@@ -1,11 +1,10 @@
 package moobench.tools.results;
 
+import java.io.File;
+import java.io.FilenameFilter;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.databind.JsonNode;
 
 import moobench.tools.results.data.ExperimentLog;
 import teetime.framework.Configuration;
@@ -14,36 +13,62 @@ import teetime.stage.basic.distributor.strategy.CopyByReferenceStrategy;
 
 public class TeetimeConfiguration extends Configuration {
 
-	public TeetimeConfiguration(Settings settings) {
-		List<Path> logFilePaths = new ArrayList<Path>();
-		for (Path path : settings.getInputPaths()) {
-			logFilePaths.add(settings.getLogPath().resolve(path.getFileName()));
-		}
-			
-		ElementProducer<Path> yamlInputPathsProducer = new ElementProducer<>(settings.getInputPaths());
-		ElementProducer<Path> yamlLogPathsProducer = new ElementProducer<>(logFilePaths);
-		
-		YamlReaderStage yamlInputReader = new YamlReaderStage();
-		YamlReaderStage yamlLogReader = new YamlReaderStage();
-
-		LogAppenderStage logAppenderStage = new LogAppenderStage();
-		Distributor<ExperimentLog> distributor = new Distributor<>(new CopyByReferenceStrategy());
-
-		YamlLogSink yamlLogSink = new YamlLogSink();
-		
-		//ChartAssemblerStage :: chartAssemblerStage
-		//JsonLogSink :: jsonLogSink
-		//GenerateHtmlTable :: generateHtmlTable
-		//FileSink :: fileSink
-
-		this.connectPorts(yamlInputPathsProducer.getOutputPort(), yamlInputReader.getInputPort());
-		this.connectPorts(yamlLogPathsProducer.getOutputPort(), yamlLogReader.getInputPort());
-		
-		this.connectPorts(yamlInputReader.getOutputPort(), logAppenderStage.getNewDataInputPort());
-		this.connectPorts(yamlLogReader.getOutputPort(), logAppenderStage.getLogInputPort());
-		
-		this.connectPorts(logAppenderStage.getOutputPort(), distributor.getInputPort());
-		
-		this.connectPorts(distributor.getNewOutputPort(), yamlLogSink.getInputPort());
-	}
+    public TeetimeConfiguration(final Settings settings) {
+        final List<Path> logFilePaths = this.createInputPaths(settings);
+
+        final ElementProducer<Path> yamlInputPathsProducer = new ElementProducer<>(logFilePaths);
+
+        final YamlReaderStage yamlInputReader = new YamlReaderStage();
+
+        final LogAppenderStage logAppenderStage = new LogAppenderStage();
+        final Distributor<ExperimentLog> distributor = new Distributor<>(new CopyByReferenceStrategy());
+
+        final YamlLogSink yamlLogSink = new YamlLogSink(settings.getLogPath());
+
+        final ChartAssemblerStage chartAssemblerStage = new ChartAssemblerStage();
+        final TailChartStage tailChartStage = new TailChartStage(settings.getWindow());
+        final JsonLogSink jsonLogSink = new JsonLogSink(settings.getJsonLogPath());
+        final ComputeTableStage computeTableStage = new ComputeTableStage();
+        final GenerateHtmlTableStage generateHtmlTableStage = new GenerateHtmlTableStage(settings.getTablePath());
+        final FileSink fileSink = new FileSink();
+
+        this.connectPorts(yamlInputPathsProducer.getOutputPort(), yamlInputReader.getInputPort());
+        this.connectPorts(yamlInputReader.getOutputPort(), logAppenderStage.getInputPort());
+
+        this.connectPorts(logAppenderStage.getOutputPort(), distributor.getInputPort());
+
+        this.connectPorts(distributor.getNewOutputPort(), yamlLogSink.getInputPort());
+        this.connectPorts(distributor.getNewOutputPort(), chartAssemblerStage.getInputPort());
+        this.connectPorts(distributor.getNewOutputPort(), computeTableStage.getInputPort());
+
+        this.connectPorts(computeTableStage.getOutputPort(), generateHtmlTableStage.getInputPort());
+        this.connectPorts(generateHtmlTableStage.getOutputPort(), fileSink.getInputPort());
+
+        this.connectPorts(chartAssemblerStage.getOutputPort(), tailChartStage.getInputPort());
+        this.connectPorts(tailChartStage.getOutputPort(), jsonLogSink.getInputPort());
+    }
+
+    private List<Path> createInputPaths(final Settings settings) {
+        final ArrayList<Path> logFilePaths = new ArrayList<Path>();
+        for (final Path path : settings.getInputPaths()) {
+            logFilePaths.add(path);
+        }
+        final FilenameFilter filter = new FilenameFilter() {
+
+            @Override
+            public boolean accept(final File file, final String name) {
+                final int last = name.lastIndexOf(".");
+                if (last < 0) {
+                    return false;
+                }
+                final String extension = name.substring(last+1);
+                return "yaml".equals(extension);
+            }
+        };
+        for (final File file : settings.getLogPath().toFile().listFiles(filter)) {
+            logFilePaths.add(file.toPath());
+        }
+
+        return logFilePaths;
+    }
 }
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/YamlLogSink.java b/tools/compile-results/src/main/java/moobench/tools/results/YamlLogSink.java
index 7603550727d283cc64d4a2abdd902e86819cb1fd..de3d9186bb32e0c7b2fa4461a0d03519b4bbf029 100644
--- a/tools/compile-results/src/main/java/moobench/tools/results/YamlLogSink.java
+++ b/tools/compile-results/src/main/java/moobench/tools/results/YamlLogSink.java
@@ -1,13 +1,67 @@
 package moobench.tools.results;
 
+import java.io.FileWriter;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.representer.Represent;
+import org.yaml.snakeyaml.representer.Representer;
+
 import moobench.tools.results.data.ExperimentLog;
+import moobench.tools.results.data.Measurements;
 import teetime.framework.AbstractConsumerStage;
 
 public class YamlLogSink extends AbstractConsumerStage<ExperimentLog> {
 
+	Path logPath;
+	
+	public YamlLogSink(Path logPath) {
+		this.logPath = logPath;
+	}
+	
 	@Override
-	protected void execute(ExperimentLog element) throws Exception {
-		// TODO Auto-generated method stub
+	protected void execute(ExperimentLog log) throws Exception {
+		Path logPath = this.logPath.resolve(String.format("%s.yaml", log.getKind()));
+
+		Representer representer = new LogRepresenter();
+		DumperOptions options = new DumperOptions();
+		Yaml yaml = new Yaml(representer, options);
+    
+	    FileWriter writer = new FileWriter(logPath.toFile());
+	    yaml.dump(log, writer);        
+	}
+	
+	private class LogRepresenter extends Representer {
+		
+		public LogRepresenter() {
+	        this.representers.put(Measurements.class, new RepresentMeasurements());
+	    }
+		
+		private class RepresentMeasurements implements Represent {
+
+			@Override
+			public Node representData(Object data) {
+				Measurements measurements = (Measurements)data;
+				
+				List<Double> values = new ArrayList<>();
+				values.add(measurements.getMean());
+				values.add(measurements.getStandardDeviation());
+				values.add(measurements.getConvidence());
+				values.add(measurements.getLowerQuartile());
+				values.add(measurements.getMedian());
+				values.add(measurements.getUpperQuartile());
+				values.add(measurements.getMin());
+				values.add(measurements.getMax());
+				
+				return representSequence(new Tag("!!" + Measurements.class.getCanonicalName()), values, defaultFlowStyle);
+			}
+			
+		}
 	}
 
 }
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/YamlReaderStage.java b/tools/compile-results/src/main/java/moobench/tools/results/YamlReaderStage.java
index e64b2e50a1fa5c20ba63bf41882decf1f1ddf83f..0cbbe6c34793606988c285a3a007b41f4bc56791 100644
--- a/tools/compile-results/src/main/java/moobench/tools/results/YamlReaderStage.java
+++ b/tools/compile-results/src/main/java/moobench/tools/results/YamlReaderStage.java
@@ -14,11 +14,14 @@ public class YamlReaderStage extends AbstractTransformation<Path, ExperimentLog>
 
 	@Override
 	protected void execute(Path path) throws Exception {
-		Yaml yaml = new Yaml(new Constructor(ExperimentLog.class));
-		InputStream inputStream = Files.newInputStream(path);
-		ExperimentLog data = yaml.load(inputStream);
-		
-		this.outputPort.send(data);
+		if (Files.exists(path)) {
+			Yaml yaml = new Yaml(new Constructor(ExperimentLog.class));
+			InputStream inputStream = Files.newInputStream(path);
+			ExperimentLog data = yaml.load(inputStream);
+			
+			this.outputPort.send(data);
+		} else
+			this.logger.error("Cannot read YAML log file {}", path.toString());
 	}
 
 }
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/data/Chart.java b/tools/compile-results/src/main/java/moobench/tools/results/data/Chart.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c6ca85152ef21a72033e256889627318774a05b
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/data/Chart.java
@@ -0,0 +1,27 @@
+package moobench.tools.results.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Chart {
+	
+	final String name;
+	final List<String> headers = new ArrayList<>();
+	final List<ValueTuple> values = new ArrayList<ValueTuple>();
+	
+	public Chart(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+	}
+
+	public List<String> getHeaders() {
+		return headers;
+	}
+	
+	public List<ValueTuple> getValues() {
+		return values;
+	}	
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/data/Measurements.java b/tools/compile-results/src/main/java/moobench/tools/results/data/Measurements.java
index e6d1dc877f81286b282e2f4a292ff8d7685f53d8..a14f9bd44de1cdf04198cd0cf3993735822b7ffc 100644
--- a/tools/compile-results/src/main/java/moobench/tools/results/data/Measurements.java
+++ b/tools/compile-results/src/main/java/moobench/tools/results/data/Measurements.java
@@ -2,16 +2,16 @@ package moobench.tools.results.data;
 
 public class Measurements {
 		
-	private double mean;
-	private double convidence;
-	private double standardDeviation;
-	private double lowerQuartile;
-	private double median;
-	private double upperQuartile;
-	private double max;
-	private double min;
+	private Double mean;
+	private Double convidence;
+	private Double standardDeviation;
+	private Double lowerQuartile;
+	private Double median;
+	private Double upperQuartile;
+	private Double max;
+	private Double min;
 
-	public Measurements(double mean, double standardDeviation, double convidence, double lowerQuartile, double median, double upperQuartile, double min, double max) {
+	public Measurements(Double mean, Double standardDeviation, Double convidence, Double lowerQuartile, Double median, Double upperQuartile, Double min, Double max) {
 		this.mean = mean;
 		this.convidence = convidence;
 		this.standardDeviation = standardDeviation;
@@ -22,7 +22,7 @@ public class Measurements {
 		this.max = max;
 	}
 	
-	public double getMean() {
+	public Double getMean() {
 		return mean;
 	}
 	
@@ -32,31 +32,31 @@ public class Measurements {
 	 * 
 	 * @return convidence value
 	 */
-	public double getConvidence() {
+	public Double getConvidence() {
 		return convidence;
 	}
 	
-	public double getStandardDeviation() {
+	public Double getStandardDeviation() {
 		return standardDeviation;
 	}
 	
-	public double getLowerQuartile() {
+	public Double getLowerQuartile() {
 		return lowerQuartile;
 	}
 	
-	public double getMedian() {
+	public Double getMedian() {
 		return median;
 	}
 	
-	public double getUpperQuartile() {
+	public Double getUpperQuartile() {
 		return upperQuartile;
 	}
 	
-	public double getMin() {
+	public Double getMin() {
 		return min;
 	}
 	
-	public double getMax() {
+	public Double getMax() {
 		return max;
 	}
 
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/data/OutputFile.java b/tools/compile-results/src/main/java/moobench/tools/results/data/OutputFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1bdfe117964ac1dc5e10a152b7a7ebb89f26f49
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/data/OutputFile.java
@@ -0,0 +1,23 @@
+package moobench.tools.results.data;
+
+import java.nio.file.Path;
+
+public class OutputFile {
+
+    Path filePath;
+    String content;
+
+    public OutputFile(final Path filePath, final String content) {
+        this.filePath = filePath;
+        this.content = content;
+    }
+
+    public Path getFilePath() {
+        return this.filePath;
+    }
+
+    public String getContent() {
+        return this.content;
+    }
+
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/data/TableInformation.java b/tools/compile-results/src/main/java/moobench/tools/results/data/TableInformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a73e5d80ee8a7417e24af91ed03d81a32c96c81
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/data/TableInformation.java
@@ -0,0 +1,27 @@
+package moobench.tools.results.data;
+
+public class TableInformation {
+
+    private final String name;
+
+    private final Experiment current;
+    private final Experiment previous;
+
+    public TableInformation(final String name, final Experiment current, final Experiment previous) {
+        this.name = name;
+        this.current = current;
+        this.previous = previous;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public Experiment getCurrent() {
+        return this.current;
+    }
+
+    public Experiment getPrevious() {
+        return this.previous;
+    }
+}
diff --git a/tools/compile-results/src/main/java/moobench/tools/results/data/ValueTuple.java b/tools/compile-results/src/main/java/moobench/tools/results/data/ValueTuple.java
new file mode 100644
index 0000000000000000000000000000000000000000..905a075dcf60ae76ffa9dea58cc41805141562fd
--- /dev/null
+++ b/tools/compile-results/src/main/java/moobench/tools/results/data/ValueTuple.java
@@ -0,0 +1,23 @@
+package moobench.tools.results.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ValueTuple {
+	
+	long timestamp;
+	
+	List<Double> values = new ArrayList<>();
+	
+	public ValueTuple(long timestamp) {
+		this.timestamp = timestamp;
+	}
+	
+	public long getTimestamp() {
+		return timestamp;
+	}
+	
+	public List<Double> getValues() {
+		return values;
+	}
+}