diff --git a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/BenchmarkJobManager.java b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/BenchmarkJobManager.java
index 10183f091d72da27ca5d9e5c0fe0467064d368af..c08c18d07ec090a9d02ebfc908960a1b11f6f41c 100644
--- a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/BenchmarkJobManager.java
+++ b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/BenchmarkJobManager.java
@@ -1,11 +1,17 @@
 package cz.it4i.fiji.haas_spim_benchmark.core;
 
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.text.MessageFormat;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
@@ -27,7 +33,6 @@ import net.imagej.updater.util.Progress;
 
 public class BenchmarkJobManager {
 
-	@SuppressWarnings("unused")
 	private static Logger log = LoggerFactory
 			.getLogger(cz.it4i.fiji.haas_spim_benchmark.core.BenchmarkJobManager.class);
 
@@ -42,10 +47,10 @@ public class BenchmarkJobManager {
 		}
 
 		public void startJob(Progress progress) throws IOException {
-			jobInfo.uploadFilesByName(Arrays.asList(CONFIG_YAML), progress);
-			String outputName = getOutputName(jobInfo.openLocalFile(CONFIG_YAML));
+			jobInfo.uploadFilesByName(Arrays.asList(Constants.CONFIG_YAML), progress);
+			String outputName = getOutputName(jobInfo.openLocalFile(Constants.CONFIG_YAML));
 			jobInfo.submit();
-			jobInfo.setProperty(SPIM_OUTPUT_FILENAME_PATTERN, outputName);
+			jobInfo.setProperty(Constants.SPIM_OUTPUT_FILENAME_PATTERN, outputName);
 		}
 
 		public JobState getState() {
@@ -56,7 +61,7 @@ public class BenchmarkJobManager {
 			JobInfo ji = jobInfo;
 			if (ji.needsDownload()) {
 				if (ji.getState() == JobState.Finished) {
-					String filePattern = ji.getProperty(SPIM_OUTPUT_FILENAME_PATTERN);
+					String filePattern = ji.getProperty(Constants.SPIM_OUTPUT_FILENAME_PATTERN);
 					ji.downloadData(downloadFinishedData(filePattern), progress, false);
 				} else if (ji.getState() == JobState.Failed) {
 					ji.downloadData(downloadFailedData(), progress, false);
@@ -67,6 +72,9 @@ public class BenchmarkJobManager {
 		public void downloadStatistics(Progress progress) throws IOException {
 			JobInfo ji = jobInfo;
 			ji.downloadData(BenchmarkJobManager.downloadStatistics(), progress, true);
+			Path resultFile = ji.getDirectory().resolve(Constants.BENCHMARK_RESULT_FILE);
+			if (resultFile != null)
+				BenchmarkJobManager.formatResultFile(resultFile);
 		}
 
 		public List<String> getOutput(List<JobSynchronizableFile> files) {
@@ -130,15 +138,6 @@ public class BenchmarkJobManager {
 		}
 	}
 
-	private static final String HAAS_JOB_NAME = "HaaSSPIMBenchmark";
-	private static final int HAAS_CLUSTER_NODE_TYPE = 6;
-	private static final int HAAS_TEMPLATE_ID = 4;
-	private static final String HAAS_PROJECT_ID = "DD-17-31";
-	private static final int HAAS_TIMEOUT = 9600;
-
-	private static final String SPIM_OUTPUT_FILENAME_PATTERN = "spim.outputFilenamePattern";
-	private static final String CONFIG_YAML = "config.yaml";
-
 	private JobManager jobManager;
 
 	public BenchmarkJobManager(BenchmarkSPIMParameters params) throws IOException {
@@ -157,7 +156,7 @@ public class BenchmarkJobManager {
 	}
 
 	private HaaSClient.UploadingFile getUploadingFile() {
-		return new UploadingFileFromResource("", CONFIG_YAML);
+		return new UploadingFileFromResource("", Constants.CONFIG_YAML);
 	}
 
 	private Job convertJob(JobInfo jobInfo) {
@@ -185,30 +184,114 @@ public class BenchmarkJobManager {
 
 	}
 
-	private Predicate<String> downloadFinishedData(String filePattern) {
+	private static Predicate<String> downloadFinishedData(String filePattern) {
 		return name -> {
-			Path p = Paths.get(name);
-			String fileName = p.getFileName().toString();
+			Path path = getPathSafely(name);
+			if (path == null)
+				return false;
+			
+			String fileName = path.getFileName().toString();
 			return fileName.startsWith(filePattern) && fileName.endsWith("h5") || fileName.equals(filePattern + ".xml")
-					|| fileName.equals("benchmark_result.csv");
+					|| fileName.equals(Constants.BENCHMARK_RESULT_FILE);
 		};
 	}
 
-	static private Predicate<String> downloadStatistics() {
+	private static Predicate<String> downloadStatistics() {
 		return name -> {
-			Path p = Paths.get(name);
-			String fileName = p.getFileName().toString();
-			return fileName.equals("benchmark_result.csv");
+			Path path = getPathSafely(name);
+			if (path == null)
+				return false;
+			
+			String fileName = path.getFileName().toString();
+			return fileName.equals(Constants.BENCHMARK_RESULT_FILE);
 		};
 	}
 
-	private Predicate<String> downloadFailedData() {
+	private static Predicate<String> downloadFailedData() {
 		return name -> {
-			Path p = Paths.get(name);
-			return p.getFileName().toString().startsWith("snakejob.")
-					|| p.getParent().getFileName().toString().equals("logs");
+			Path path = getPathSafely(name);
+			if (path == null)
+				return false;
+			
+			return path.getFileName().toString().startsWith("snakejob.")
+					|| path.getParent().getFileName().toString().equals("logs");
 		};
 	}
+	
+	private static Path getPathSafely(String name) {
+		try {
+			return Paths.get(name);
+		} catch(InvalidPathException ex) {
+			return null;
+		}
+	}
+	
+	private static void formatResultFile(Path filename) throws FileNotFoundException {
+		
+		List<ResultFileTask> identifiedTasks = new LinkedList<ResultFileTask>();
+		
+		try {
+			String line = null;
+			final String separator = ";";
+			
+			ResultFileTask processedTask = null;			
+			List<ResultFileJob> jobs = new LinkedList<>();
+			
+			BufferedReader reader = Files.newBufferedReader(filename);
+			while (null != (line = reader.readLine())) {
+				
+				line = line.trim();
+				if (line.isEmpty()) {
+					continue;
+				}
+				
+				String[] columns = line.split(separator);
+				
+				if (columns[0].equals(Constants.STATISTICS_TASK_NAME)) {
+					
+					// If there is a task being processed, add all cached jobs to it and wrap it up
+					if (null != processedTask ) {
+						processedTask.jobs.addAll(jobs);
+						identifiedTasks.add(processedTask);
+					}
+					
+					// Start processing a new task
+					processedTask = new ResultFileTask(columns[1]);
+					jobs.clear();
+					
+				} else if (columns[0].equals(Constants.STATISTICS_JOB_IDS)) {
+					
+					// Cache all found jobs
+					for (int i = 1; i < columns.length; i++) {
+						jobs.add(new ResultFileJob(columns[i]));
+					}
+					
+				} else if (!columns[0].equals(Constants.STATISTICS_JOB_COUNT)) {
+					
+					// Save values of a given property to cached jobs
+					for (int i = 1; i < columns.length; i++) {
+						jobs.get(i - 1).setValue(columns[0], columns[i]);
+					}
+					
+				} 
+			}
+			
+			// If there is a task being processed, add all cached jobs to it and wrap it up
+			if (null != processedTask ) {
+				processedTask.jobs.addAll(jobs);
+				identifiedTasks.add(processedTask);
+			}
+			
+		} catch (IOException e) {
+			log.error(e.getMessage(), e);
+		} 
+		
+		for (ResultFileTask task : identifiedTasks) {
+			Object[] args = {Constants.STATISTICS_TASK_NAME_MAP.get(task.name), task.getJobCount(), task.getAverageMemoryUsage()};
+			MessageFormat fmt = new MessageFormat(Constants.STATISTICS_OUTPUT_MESSAGE);
+			System.out.println(fmt.format(args));
+		}
+	}
 
 	private static Settings constructSettingsFromParams(BenchmarkSPIMParameters params) {
 		// TODO Auto-generated method stub
@@ -221,17 +304,17 @@ public class BenchmarkJobManager {
 
 			@Override
 			public int getTimeout() {
-				return HAAS_TIMEOUT;
+				return Constants.HAAS_TIMEOUT;
 			}
 
 			@Override
 			public long getTemplateId() {
-				return HAAS_TEMPLATE_ID;
+				return Constants.HAAS_TEMPLATE_ID;
 			}
 
 			@Override
 			public String getProjectId() {
-				return HAAS_PROJECT_ID;
+				return Constants.HAAS_PROJECT_ID;
 			}
 
 			@Override
@@ -246,7 +329,7 @@ public class BenchmarkJobManager {
 
 			@Override
 			public String getJobName() {
-				return HAAS_JOB_NAME;
+				return Constants.HAAS_JOB_NAME;
 			}
 
 			@Override
@@ -256,7 +339,7 @@ public class BenchmarkJobManager {
 
 			@Override
 			public long getClusterNodeType() {
-				return HAAS_CLUSTER_NODE_TYPE;
+				return Constants.HAAS_CLUSTER_NODE_TYPE;
 			}
 		};
 	}
diff --git a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/Constants.java b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/Constants.java
index 367ef54df3ca69b2dc82e879f4c0088737adf470..0e4f436ca65c9eb2174a0d2d91496394c1bf2248 100644
--- a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/Constants.java
+++ b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/Constants.java
@@ -1,5 +1,41 @@
 package cz.it4i.fiji.haas_spim_benchmark.core;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public interface Constants {
 	long HAAS_UPDATE_TIMEOUT = 1000;
+	String HAAS_JOB_NAME = "HaaSSPIMBenchmark";
+	int HAAS_CLUSTER_NODE_TYPE = 6;
+	int HAAS_TEMPLATE_ID = 4;
+	String HAAS_PROJECT_ID = "DD-17-31";
+	int HAAS_TIMEOUT = 9600;
+
+	String SPIM_OUTPUT_FILENAME_PATTERN = "spim.outputFilenamePattern";
+	String CONFIG_YAML = "config.yaml";
+	String BENCHMARK_RESULT_FILE = "benchmark_result.csv";
+	
+	String STATISTICS_TASK_NAME = "Task name";
+	String STATISTICS_JOB_IDS = "job ids";
+	String STATISTICS_JOB_COUNT = "jobs #";
+	String STATISTICS_RESOURCES_MEMORY_USAGE = "resources_used.mem";
+	String STATISTICS_RESOURCES_WALL_TIME = "resources_used.walltime";
+	String STATISTICS_RESOURCES_CPU_PERCENTAGE = "resources_used.cpupercent";
+	
+	Map<String, String> STATISTICS_TASK_NAME_MAP = new HashMap<String, String>() {
+		private static final long serialVersionUID = 1L;
+	{
+		put("define_xml_tif", "Define dataset");
+		put("hdf5_xml", "Define hdf5 dataset");
+		put("resave_hdf5", "Resave to hdf5");
+		put("registration", "Detection and registration");
+		put("xml_merge", "Merge xml");
+		put("timelapse", "Time lapse registration");
+		put("fusion", "Average fusion");
+		put("deconvolution", "Deconvolution GPU");
+		put("define_output", "Define output");
+		put("hdf5_xml_output", "Define hdf5 output");
+		put("resave_hdf5_output", "Resave output to hdf5");
+	}};
+	String STATISTICS_OUTPUT_MESSAGE = "{0} needed {1} {1,choice,0#jobs|1#job|1<jobs} and {2} MB of memory in average.";
 }
diff --git a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ResultFileJob.java b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ResultFileJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..f67fee23997feb9a8782eab46e65ebd43e1b7a21
--- /dev/null
+++ b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ResultFileJob.java
@@ -0,0 +1,21 @@
+package cz.it4i.fiji.haas_spim_benchmark.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ResultFileJob {
+	String id;
+	Map<String, String> values = new HashMap<>();
+
+	public ResultFileJob(String id) {
+		this.id = id;
+	}
+
+	public String getValue(String key) {
+		return values.get(key);
+	}
+
+	public void setValue(String key, String value) {
+		values.put(key, value);
+	}
+}
\ No newline at end of file
diff --git a/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ResultFileTask.java b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ResultFileTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..88767ed9748b70ddd2cf921d2733e05e7b73824d
--- /dev/null
+++ b/haas-spim-benchmark/src/main/java/cz/it4i/fiji/haas_spim_benchmark/core/ResultFileTask.java
@@ -0,0 +1,36 @@
+package cz.it4i.fiji.haas_spim_benchmark.core;
+
+import java.util.LinkedList;
+import java.util.stream.Collectors;
+
+public class ResultFileTask {
+	String name;
+	LinkedList<ResultFileJob> jobs;
+
+	public ResultFileTask(String name) {
+		this.name = name;
+		this.jobs = new LinkedList<ResultFileJob>();
+	}
+
+	public int getJobCount() {
+		return this.jobs.size();
+	}
+
+	public double getAverageMemoryUsage() {
+		return getAverage(Constants.STATISTICS_RESOURCES_MEMORY_USAGE);
+	}
+
+	public double getAverageWallTime() {
+		return getAverage(Constants.STATISTICS_RESOURCES_WALL_TIME);
+	}
+
+	public double getAverageCpuPercentage() {
+		return getAverage(Constants.STATISTICS_RESOURCES_CPU_PERCENTAGE);
+	}
+	
+	private Double getAverage(String propertyName) {
+		return jobs.stream().map(job -> job.getValue(propertyName))
+				.map(memStr -> Double.parseDouble(memStr))
+				.collect(Collectors.averagingDouble(d->d)).doubleValue();
+	}
+}
\ No newline at end of file