diff --git a/alib2measurepp/src/processor/MeasurementProcessorOutput.cpp b/alib2measurepp/src/processor/MeasurementProcessorOutput.cpp
index 83eabf5a40dba3ed5aa47703be4d4e2b3fd8d329..2b0f372b342f083698a987ba220bfeea88be8dcc 100644
--- a/alib2measurepp/src/processor/MeasurementProcessorOutput.cpp
+++ b/alib2measurepp/src/processor/MeasurementProcessorOutput.cpp
@@ -3,6 +3,7 @@
  */
 
 #include "MeasurementProcessorOutput.hpp"
+#include "MeasurementProcessorViews.hpp"
 #include "sax/SaxComposeInterface.h"
 #include <set>
 #include <iostream>
@@ -150,7 +151,11 @@ std::vector < MeasurementProcessorOutput::Table > MeasurementProcessorOutput::ge
 	for ( size_t frameIdx = 1; frameIdx < masterFrames.size ( ); ++frameIdx ) {
 		Table & table = tables[frameIdx - 1];
 
-		table.description = to_string ( masterFrames[frameIdx].name ) + " " + to_string ( masterFrames[frameIdx].type );
+		table.description = to_string ( masterFrames[frameIdx].name ) + " " + to_string ( masterFrames[frameIdx].type ) + " :";
+
+		for ( const std::string & attr : mpo.outputEngineAttr )
+			table.description += " " + attr;
+
 		table.header = masterHeader;
 
 		for ( const MPRInputResult & mprir : mpr.inputResults ) {
@@ -171,19 +176,15 @@ std::vector < MeasurementProcessorOutput::Table > MeasurementProcessorOutput::ge
 }
 
 std::string MeasurementProcessorOutput::getData ( const MeasurementFrame & frame, const MeasurementProcessorOutput & mpo ) {
-	// FIXME take in account engineAttr in mpo
-
 	switch ( mpo.outputEngine ) {
 	case OutputEngine::TIME:
-		return std::to_string ( frame.time.duration.count ( ) );
+		return MeasurementProcessorViews::viewTimeDataFrame ( frame, mpo.outputEngineAttr );
 
 	case OutputEngine::MEMORY:
-		return std::to_string ( frame.memory.highWatermark - frame.memory.startHeapUsage );
+		return MeasurementProcessorViews::viewMemoryDataFrame ( frame, mpo.outputEngineAttr );
 
 	case OutputEngine::COUNTER:
-
-		 // FIXME
-		return "";
+		return MeasurementProcessorViews::viewCounterDataFrame ( frame, mpo.outputEngineAttr );
 	}
 }
 
diff --git a/alib2measurepp/src/processor/MeasurementProcessorOutput.hpp b/alib2measurepp/src/processor/MeasurementProcessorOutput.hpp
index f6bdbeab93b91c0e8d3d25ca2fc8e240d66eea44..b2186bb98b6f1696b4061e0086fed53ddc5f0dcf 100644
--- a/alib2measurepp/src/processor/MeasurementProcessorOutput.hpp
+++ b/alib2measurepp/src/processor/MeasurementProcessorOutput.hpp
@@ -7,6 +7,7 @@
 
 #include "../provisioner/MeasurementProvisionerResults.hpp"
 #include <ostream>
+#include <set>
 
 namespace measurements {
 
@@ -19,9 +20,9 @@ struct MeasurementProcessorOutput {
 		TIME, MEMORY, COUNTER
 	};
 
-	OutputFormat outputFormat;
-	OutputEngine outputEngine;
-	std::string	 outputEngineAttr;
+	OutputFormat			 outputFormat;
+	OutputEngine			 outputEngine;
+	std::set < std::string > outputEngineAttr;
 
 	static void outputXml ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & );
 	static void outputStats ( std::ostream &, const MeasurementProvisionerResults &, const MeasurementProcessorOutput & );
diff --git a/alib2measurepp/src/processor/MeasurementProcessorViews.cpp b/alib2measurepp/src/processor/MeasurementProcessorViews.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cf9e827d8830048348e3921a37ce40dddf5e48c2
--- /dev/null
+++ b/alib2measurepp/src/processor/MeasurementProcessorViews.cpp
@@ -0,0 +1,69 @@
+/*
+ * Author: Radovan Cerveny
+ */
+
+#include "MeasurementProcessorViews.hpp"
+
+namespace measurements {
+
+std::string MeasurementProcessorViews::viewTimeDataFrame ( const MeasurementFrame & frame, const std::set < std::string > & outputEngineAttr ) {
+	 // make this default behavior
+	 // if(outputEngineAttr.count(TIME_DURATION_ATTR))
+	if ( outputEngineAttr.count ( INFRAME_ATTR ) )
+		return std::to_string ( frame.time.inFrameDuration.count ( ) );
+	else
+		return std::to_string ( frame.time.duration.count ( ) );
+}
+
+std::string MeasurementProcessorViews::viewMemoryDataFrame ( const MeasurementFrame & frame, const std::set < std::string > & outputEngineAttr ) {
+	if ( outputEngineAttr.count ( MEMORY_SHU_ATTR ) )
+		return std::to_string ( frame.memory.startHeapUsage );
+
+	if ( outputEngineAttr.count ( MEMORY_EHU_ATTR ) )
+		return std::to_string ( frame.memory.endHeapUsage );
+
+	if ( outputEngineAttr.count ( MEMORY_HW_ATTR ) ) {
+		if ( outputEngineAttr.count ( INFRAME_ATTR ) )
+			return std::to_string ( frame.memory.inFrameHighWatermark );
+		else
+			return std::to_string ( frame.memory.highWatermark );
+	}
+
+	 // make this default behavior
+	 // if(outputEngineAttr.count(MEMORY_DELTA_ATTR))
+	if ( outputEngineAttr.count ( INFRAME_ATTR ) )
+		return std::to_string ( frame.memory.inFrameHighWatermark - frame.memory.startHeapUsage );
+	else
+		return std::to_string ( frame.memory.highWatermark - frame.memory.startHeapUsage );
+}
+
+std::string MeasurementProcessorViews::viewCounterDataFrame ( const MeasurementFrame & frame, const std::set < std::string > & outputEngineAttr ) {
+	if ( outputEngineAttr.count ( INFRAME_ATTR ) ) {
+		for ( const std::string & attr : outputEngineAttr ) {
+			if ( attr == INFRAME_ATTR ) continue;
+
+			auto it = frame.counter.counters.find ( measurements::stealthStringFromString ( attr ) );
+
+			if ( it != frame.counter.counters.end ( ) )
+				return std::to_string ( it->second );
+		}
+	} else {
+		auto it = frame.counter.inFrameCounters.find ( measurements::stealthStringFromString ( * outputEngineAttr.begin ( ) ) );
+
+		if ( it != frame.counter.inFrameCounters.end ( ) )
+			return std::to_string ( it->second );
+	}
+
+	 // we default to default constructed value_type
+	return std::to_string ( measurements::CounterHint::value_type { } );
+}
+
+std::string MeasurementProcessorViews::INFRAME_ATTR = "inFrame";
+
+std::string MeasurementProcessorViews::TIME_DURATION_ATTR = "duration";
+
+std::string MeasurementProcessorViews::MEMORY_DELTA_ATTR = "delta";
+std::string MeasurementProcessorViews::MEMORY_SHU_ATTR = "startHeapUsage";
+std::string MeasurementProcessorViews::MEMORY_EHU_ATTR = "endHeapUsage";
+std::string MeasurementProcessorViews::MEMORY_HW_ATTR  = "highWatermark";
+}
diff --git a/alib2measurepp/src/processor/MeasurementProcessorViews.hpp b/alib2measurepp/src/processor/MeasurementProcessorViews.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4d06d74585f843231f55b4cc17c39febf3be83bb
--- /dev/null
+++ b/alib2measurepp/src/processor/MeasurementProcessorViews.hpp
@@ -0,0 +1,37 @@
+/*
+ * Author: Radovan Cerveny
+ */
+
+#ifndef MEASUREMENT_PROCESSOR_VIEWS_HPP_
+#define MEASUREMENT_PROCESSOR_VIEWS_HPP_
+
+#include <measure>
+#include <set>
+
+namespace measurements {
+
+class MeasurementProcessorViews {
+public:
+	 // general
+	static std::string INFRAME_ATTR;
+
+	 // TimeDataFrame
+	static std::string TIME_DURATION_ATTR;
+
+	 // MemoryDataFrame
+	static std::string MEMORY_DELTA_ATTR;
+	static std::string MEMORY_SHU_ATTR;
+	static std::string MEMORY_EHU_ATTR;
+	static std::string MEMORY_HW_ATTR;
+
+	// CounterDataFrame
+	// no specific attrs
+
+	static std::string viewTimeDataFrame ( const MeasurementFrame &, const std::set < std::string > & );
+	static std::string viewMemoryDataFrame ( const MeasurementFrame &, const std::set < std::string > & );
+	static std::string viewCounterDataFrame ( const MeasurementFrame &, const std::set < std::string > & );
+};
+
+}
+
+#endif /* MEASUREMENT_PROCESSOR_VIEWS_HPP_ */
diff --git a/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp b/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp
index 8a001d683c6d955c910d9bf2faa17b9b907c93d0..96822514b9623f521f234cb27e729ec98b89f441 100644
--- a/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp
+++ b/alib2measurepp/src/provisioner/MeasurementProvisioner.cpp
@@ -143,8 +143,6 @@ MPRPipelineResult MeasurementProvisioner::runPipeline ( const MPPipeline & pipel
 
 	 // if everything went smoothly, we aggregate the results
 	if ( pipelineFinalResults.pipelineStatus.exitCode == 0 ) {
-		// FIXME we need proper aggregation
-
 		vector < vector < MeasurementResults > > transposedCommandMeasurementSubResults ( pipeline.size ( ) );
 
 		for ( vector < MeasurementResults > & commandResults : commandMeasurementSubResults )
diff --git a/ameasurep2/src/ameasureproc.cpp b/ameasurep2/src/ameasureproc.cpp
index 8094265d34ed2e1f98ecf34540d490c8a80463a7..ba60963a3fd6c6661821635b5b092ecd00b1c6a4 100644
--- a/ameasurep2/src/ameasureproc.cpp
+++ b/ameasurep2/src/ameasureproc.cpp
@@ -33,7 +33,7 @@ int main ( int argc, char * * argv ) {
 		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" );
+		TCLAP::MultiArg < std::string > engineAttr ( "", "engineAttr", "Engine attribute", false, "string" );
 		cmd.add ( engineAttr );
 
 		TCLAP::MultiArg < std::string > filterByFrameType ( "", "filterFrameType", "Filter by frame type", false, "string" );
@@ -91,7 +91,8 @@ int main ( int argc, char * * argv ) {
 			output.outputEngine = measurements::MeasurementProcessorOutput::OutputEngine::COUNTER;
 
 		if ( engineAttr.isSet ( ) )
-			output.outputEngineAttr = engineAttr.getValue ( );
+			for ( const std::string & attr : engineAttr.getValue ( ) )
+				output.outputEngineAttr.insert ( attr );
 
 		std::cout << measurements::MeasurementProcessor::output ( processedResults, output ) << std::endl;