diff --git a/alib2measurepp/src/processor/MeasurementProcessor.cpp b/alib2measurepp/src/processor/MeasurementProcessor.cpp
index 1ee1ddee166b00c213a86626ff554125d1eac1bf..39a83208998a473ff0bb0611af96037334099431 100644
--- a/alib2measurepp/src/processor/MeasurementProcessor.cpp
+++ b/alib2measurepp/src/processor/MeasurementProcessor.cpp
@@ -3,28 +3,28 @@
  */
 
 #include "MeasurementProcessor.hpp"
-#include <iostream>
+#include <sstream>
 
 namespace measurements {
 
-MeasurementProvisionerResults MeasurementProcessor::process ( MeasurementProvisionerResults mpr, const MeasurementProcessorFilter & filter ) {
+MeasurementProvisionerResults MeasurementProcessor::process ( const MeasurementProvisionerResults & mpr, const MeasurementProcessorFilter & filter ) {
 	MeasurementProvisionerResults newmpr;
 
-	for ( MPRResults & mprr : mpr.results ) {
+	for ( const MPRResults & mprr : mpr.results ) {
 		MPRResults newmprr;
-		newmprr.inputs = std::move ( mprr.inputs );
+		newmprr.inputs = mprr.inputs;
 
-		for ( MPRPipelineResults & mprpr : mprr.pipelineResults ) {
+		for ( const MPRPipelineResults & mprpr : mprr.pipelineResults ) {
 			MPRPipelineResults newmprpr;
-			newmprpr.pipelineStatus = std::move ( mprpr.pipelineStatus );
+			newmprpr.pipelineStatus = mprpr.pipelineStatus;
 
-			for ( MPRPipelineCommandResults & mprpcr : mprpr.commandResults ) {
+			for ( const MPRPipelineCommandResults & mprpcr : mprpr.commandResults ) {
 
 				 // filter out commands
 				if ( !filter.matches ( MeasurementProcessorFilter::FilterType::COMMAND, mprpcr.command ) ) continue;
 
 				MPRPipelineCommandResults newmprpcr;
-				newmprpcr.command = std::move ( mprpcr.command );
+				newmprpcr.command = mprpcr.command;
 
 				newmprpcr.measurementResults = processMeasurementResults ( mprpcr.measurementResults, filter );
 
@@ -48,37 +48,65 @@ MeasurementResults MeasurementProcessor::processMeasurementResults ( const Measu
 	std::function < void ( unsigned, unsigned ) > dfsLambda;
 
 	dfsLambda = [&] ( unsigned idx, unsigned newmrParentIdx ) {
-					if ( idx == 0 ) {
-						newmr.frames.push_back ( mr.frames[0] );
-						newmr.frames[0].sub_idxs.clear ( );
-
-						for ( unsigned subIdx : mr.frames[idx].sub_idxs )
-							dfsLambda ( subIdx, 0 );
-					} else {
-						const MeasurementFrame & curFrame = mr.frames[idx];
-
-						bool filteredOut = false;
-						filteredOut |= !filter.matches ( MeasurementProcessorFilter::FilterType::FRAME_TYPE, to_string ( curFrame.type ) );
-						filteredOut |= !filter.matches ( MeasurementProcessorFilter::FilterType::FRAME_NAME, to_string ( curFrame.name ) );
-
-						if ( !filteredOut ) {
-							unsigned newmrIdx = newmr.frames.size ( );
-							newmr.frames.push_back ( mr.frames[idx] );
-							newmr.frames[newmrIdx].sub_idxs.clear ( );
-							newmr.frames[newmrParentIdx].sub_idxs.push_back ( newmrIdx );
-
-							for ( unsigned subIdx : mr.frames[idx].sub_idxs )
-								dfsLambda ( subIdx, newmrIdx );
-						} else {
-							for ( unsigned subIdx : mr.frames[idx].sub_idxs )
-								dfsLambda ( subIdx, newmrParentIdx );
-						}
-					}
-				};
+		if ( idx == 0 ) {
+			newmr.frames.push_back ( mr.frames[0] );
+			newmr.frames[0].sub_idxs.clear ( );
+
+			for ( unsigned subIdx : mr.frames[idx].sub_idxs )
+				dfsLambda ( subIdx, 0 );
+		} else {
+			const MeasurementFrame & curFrame = mr.frames[idx];
+
+			bool filteredOut = false;
+			filteredOut |= !filter.matches ( MeasurementProcessorFilter::FilterType::FRAME_TYPE, to_string ( curFrame.type ) );
+			filteredOut |= !filter.matches ( MeasurementProcessorFilter::FilterType::FRAME_NAME, to_string ( curFrame.name ) );
+
+			if ( !filteredOut ) {
+				unsigned newmrIdx = newmr.frames.size ( );
+				newmr.frames.push_back ( mr.frames[idx] );
+				newmr.frames[newmrIdx].sub_idxs.clear ( );
+				newmr.frames[newmrParentIdx].sub_idxs.push_back ( newmrIdx );
+
+				for ( unsigned subIdx : mr.frames[idx].sub_idxs )
+					dfsLambda ( subIdx, newmrIdx );
+			} else {
+				for ( unsigned subIdx : mr.frames[idx].sub_idxs )
+					dfsLambda ( subIdx, newmrParentIdx );
+			}
+		}
+	};
 
 	dfsLambda ( 0, 0 );
 
 	return newmr;
 }
 
+std::string MeasurementProcessor::output ( const MeasurementProvisionerResults & mpr, const MeasurementProcessorOutput & output ) {
+	std::stringstream ss;
+
+	MeasurementProcessor::output ( ss, mpr, output );
+
+	return ss.str ( );
+}
+
+void MeasurementProcessor::output ( std::ostream & os, const MeasurementProvisionerResults & mpr, const MeasurementProcessorOutput & output ) {
+	switch ( output.outputFormat ) {
+	case MeasurementProcessorOutput::OutputFormat::XML:
+		MeasurementProcessorOutput::outputXml ( os, mpr, output );
+		break;
+
+	case MeasurementProcessorOutput::OutputFormat::STATS:
+		MeasurementProcessorOutput::outputStats ( os, mpr, output );
+		break;
+
+	case MeasurementProcessorOutput::OutputFormat::CSV:
+		MeasurementProcessorOutput::outputCsv ( os, mpr, output );
+		break;
+
+	case MeasurementProcessorOutput::OutputFormat::HTML:
+		MeasurementProcessorOutput::outputHtml ( os, mpr, output );
+		break;
+	}
+}
+
 }
diff --git a/alib2measurepp/src/processor/MeasurementProcessor.hpp b/alib2measurepp/src/processor/MeasurementProcessor.hpp
index 9684f2463f93a849fb71e5c402c48cefb11108b5..ce79a55393698fc23723d1520cda0867d107da19 100644
--- a/alib2measurepp/src/processor/MeasurementProcessor.hpp
+++ b/alib2measurepp/src/processor/MeasurementProcessor.hpp
@@ -7,6 +7,8 @@
 
 #include "../provisioner/MeasurementProvisionerResults.hpp"
 #include "MeasurementProcessorFilter.hpp"
+#include "MeasurementProcessorOutput.hpp"
+#include <ostream>
 
 namespace measurements {
 
@@ -14,9 +16,11 @@ class MeasurementProcessor {
 
 	static MeasurementResults processMeasurementResults ( const MeasurementResults &, const MeasurementProcessorFilter & );
 
-
 public:
-	static MeasurementProvisionerResults process ( MeasurementProvisionerResults, const MeasurementProcessorFilter & );
+	static MeasurementProvisionerResults process ( const MeasurementProvisionerResults &, const MeasurementProcessorFilter & );
+
+	static std::string output ( const MeasurementProvisionerResults &, const MeasurementProcessorOutput & );
+	static void output ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & );
 };
 
 }
diff --git a/alib2measurepp/src/processor/MeasurementProcessorOutput.cpp b/alib2measurepp/src/processor/MeasurementProcessorOutput.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e9d080d0b63852ca0ec3ae4aa9bb651d6b48fdc2
--- /dev/null
+++ b/alib2measurepp/src/processor/MeasurementProcessorOutput.cpp
@@ -0,0 +1,57 @@
+/*
+ * Author: Radovan Cerveny
+ */
+
+#include "MeasurementProcessorOutput.hpp"
+#include <set>
+#include <iostream>
+
+namespace measurements {
+
+void MeasurementProcessorOutput::outputXml ( std::ostream & os, const MeasurementProvisionerResults & mpr, const MeasurementProcessorOutput & ) {
+	os << mpr;
+}
+
+void MeasurementProcessorOutput::outputStats ( std::ostream & os, const MeasurementProvisionerResults & mpr, const MeasurementProcessorOutput & ) {
+
+	std::vector < int > errorExitCodes;
+	std::set < std::string > measuredPipelines;
+
+	for ( const MPRResults & mprr : mpr.results )
+		for ( const MPRPipelineResults & mprpr : mprr.pipelineResults ) {
+			if ( mprpr.pipelineStatus.exitCode != 0 )
+				errorExitCodes.push_back ( mprpr.pipelineStatus.exitCode );
+
+			std::string pipeline;
+
+			for ( auto it = mprpr.commandResults.cbegin ( ); it != mprpr.commandResults.cend ( ); ++it ) {
+				if ( it != mprpr.commandResults.cbegin ( ) )
+					pipeline += " | ";
+
+				pipeline += it->command;
+			}
+
+			measuredPipelines.insert ( pipeline );
+		}
+
+	os << "Total measurements: " << mpr.results.size ( ) << std::endl;
+	os << "Errors: ";
+
+	if ( errorExitCodes.size ( ) == 0 )
+		os << "none" << std::endl;
+	else
+		os << errorExitCodes << std::endl;
+
+	os << "Measured pipelines:" << std::endl;
+
+	for ( const std::string & pipeline : measuredPipelines )
+		os << "  " << pipeline << std::endl;
+}
+
+void MeasurementProcessorOutput::outputCsv ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & ) {
+}
+
+void MeasurementProcessorOutput::outputHtml ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & ) {
+}
+
+}
diff --git a/alib2measurepp/src/processor/MeasurementProcessorOutput.hpp b/alib2measurepp/src/processor/MeasurementProcessorOutput.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6c726cd004fb7a1af561e217258b7b431c117a27
--- /dev/null
+++ b/alib2measurepp/src/processor/MeasurementProcessorOutput.hpp
@@ -0,0 +1,34 @@
+/*
+ * Author: Radovan Cerveny
+ */
+
+#ifndef MEASUREMENT_PROCESSOR_OUTPUT_HPP_
+#define MEASUREMENT_PROCESSOR_OUTPUT_HPP_
+
+#include "../provisioner/MeasurementProvisionerResults.hpp"
+#include <ostream>
+
+namespace measurements {
+
+struct MeasurementProcessorOutput {
+	enum class OutputFormat {
+		XML, STATS,	CSV, HTML
+	};
+
+	enum class OutputEngine {
+		TIME, MEMORY, COUNTER
+	};
+
+	OutputFormat outputFormat;
+	OutputEngine outputEngine;
+	std::string	 outputEngineAttr;
+
+	static void outputXml ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & );
+	static void outputStats ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & );
+	static void outputCsv ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & );
+	static void outputHtml ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & );
+};
+
+}
+
+#endif /* MEASUREMENT_PROCESSOR_OUTPUT_HPP_ */
diff --git a/ameasurep2/src/ameasureproc.cpp b/ameasurep2/src/ameasureproc.cpp
index 5dec69b7be41176e3280ada793ec78efe8d51ad7..8094265d34ed2e1f98ecf34540d490c8a80463a7 100644
--- a/ameasurep2/src/ameasureproc.cpp
+++ b/ameasurep2/src/ameasureproc.cpp
@@ -19,11 +19,10 @@ int main ( int argc, char * * argv ) {
 		allowedOutput.push_back ( "stats" );
 		allowedOutput.push_back ( "csv" );
 		allowedOutput.push_back ( "html" );
-		allowedOutput.push_back ( "table" );
 		TCLAP::ValuesConstraint < std::string > allowedOutputValues ( allowedOutput );
 
-		TCLAP::ValueArg < std::string > output ( "o", "output", "Output format", false, "string", & allowedOutputValues );
-		cmd.add ( output );
+		TCLAP::ValueArg < std::string > outputFormat ( "o", "output", "Output format", false, "xml", & allowedOutputValues );
+		cmd.add ( outputFormat );
 
 		std::vector < std::string > allowedEngine;
 		allowedEngine.push_back ( "time" );
@@ -31,9 +30,12 @@ int main ( int argc, char * * argv ) {
 		allowedEngine.push_back ( "counter" );
 		TCLAP::ValuesConstraint < std::string > allowedEngineValues ( allowedEngine );
 
-		TCLAP::ValueArg < std::string > engine ( "e", "engine", "Engine type", false, "string", & allowedEngineValues );
+		TCLAP::ValueArg < std::string > engine ( "e", "engine", "Engine type", false, "time", & allowedEngineValues );
 		cmd.add ( engine );
 
+		TCLAP::ValueArg < std::string > engineAttr ( "", "engineAttr", "Engine attribute", false, "", "string" );
+		cmd.add ( engineAttr );
+
 		TCLAP::MultiArg < std::string > filterByFrameType ( "", "filterFrameType", "Filter by frame type", false, "string" );
 		cmd.add ( filterByFrameType );
 
@@ -70,7 +72,28 @@ int main ( int argc, char * * argv ) {
 
 		auto processedResults = measurements::MeasurementProcessor::process ( results, filter );
 
-		std::cout << processedResults << std::endl;
+		measurements::MeasurementProcessorOutput output;
+
+		if ( outputFormat.getValue ( ) == "xml" )
+			output.outputFormat = measurements::MeasurementProcessorOutput::OutputFormat::XML;
+		else if ( outputFormat.getValue ( ) == "stats" )
+			output.outputFormat = measurements::MeasurementProcessorOutput::OutputFormat::STATS;
+		else if ( outputFormat.getValue ( ) == "csv" )
+			output.outputFormat = measurements::MeasurementProcessorOutput::OutputFormat::CSV;
+		else if ( outputFormat.getValue ( ) == "html" )
+			output.outputFormat = measurements::MeasurementProcessorOutput::OutputFormat::HTML;
+
+		if ( engine.getValue ( ) == "time" )
+			output.outputEngine = measurements::MeasurementProcessorOutput::OutputEngine::TIME;
+		else if ( engine.getValue ( ) == "memory" )
+			output.outputEngine = measurements::MeasurementProcessorOutput::OutputEngine::MEMORY;
+		else if ( engine.getValue ( ) == "counter" )
+			output.outputEngine = measurements::MeasurementProcessorOutput::OutputEngine::COUNTER;
+
+		if ( engineAttr.isSet ( ) )
+			output.outputEngineAttr = engineAttr.getValue ( );
+
+		std::cout << measurements::MeasurementProcessor::output ( processedResults, output ) << std::endl;
 
 		return 0;