From 2d5e1c3a2910f7e68d3a915d927e235ed76af766 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 4 Jul 2017 22:28:29 +0200
Subject: [PATCH] new algorithm, cast, type abstraction

---
 .../src/abstraction/AlgorithmAbstraction.hpp  | 175 ++++++++++++++++++
 .../src/abstraction/AlgorithmRegistry.hpp     | 125 +++++++++++++
 .../src/abstraction/CastAbstraction.hpp       |  37 ++++
 alib2common/src/abstraction/CastRegistry.hpp  | 108 +++++++++++
 .../src/abstraction/DowncastAbstraction.hpp   |  37 ++++
 .../src/abstraction/DowncastRegistry.hpp      |  71 +++++++
 .../src/abstraction/ImmediateRegistry.hpp     |  77 ++++++++
 .../abstraction/ImmediateValueAbstraction.hpp |  30 +++
 .../src/abstraction/NormalizeAbstraction.hpp  |  37 ++++
 .../src/abstraction/NormalizeRegistry.hpp     |  74 ++++++++
 .../NullaryOperationAbstraction.hpp           |  60 ++++++
 .../src/abstraction/OperationAbstraction.hpp  |  51 +++++
 .../src/abstraction/PrimitiveRegistrator.cpp  |  54 ++++++
 alib2common/src/abstraction/Registry.cpp      |  57 ++++++
 alib2common/src/abstraction/Registry.h        |  31 ++++
 .../src/abstraction/ResultClassSelector.hpp   |  29 +++
 .../abstraction/UnaryOperationAbstraction.hpp |  91 +++++++++
 .../abstraction/ValueOperationAbstraction.hpp |  91 +++++++++
 .../abstraction/ValuePrinterAbstraction.hpp   |  33 ++++
 .../src/abstraction/ValuePrinterRegistry.hpp  |  74 ++++++++
 .../abstraction/VoidOperationAbstraction.hpp  |  63 +++++++
 .../abstraction/XmlFileWriterAbstraction.hpp  |  35 ++++
 .../src/abstraction/XmlFileWriterRegistry.hpp |  75 ++++++++
 .../src/abstraction/XmlParserAbstraction.hpp  |  36 ++++
 .../src/abstraction/XmlParserRegistry.hpp     |  70 +++++++
 25 files changed, 1621 insertions(+)
 create mode 100644 alib2common/src/abstraction/AlgorithmAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/AlgorithmRegistry.hpp
 create mode 100644 alib2common/src/abstraction/CastAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/CastRegistry.hpp
 create mode 100644 alib2common/src/abstraction/DowncastAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/DowncastRegistry.hpp
 create mode 100644 alib2common/src/abstraction/ImmediateRegistry.hpp
 create mode 100644 alib2common/src/abstraction/ImmediateValueAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/NormalizeAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/NormalizeRegistry.hpp
 create mode 100644 alib2common/src/abstraction/NullaryOperationAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/OperationAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/PrimitiveRegistrator.cpp
 create mode 100644 alib2common/src/abstraction/Registry.cpp
 create mode 100644 alib2common/src/abstraction/Registry.h
 create mode 100644 alib2common/src/abstraction/ResultClassSelector.hpp
 create mode 100644 alib2common/src/abstraction/UnaryOperationAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/ValueOperationAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/ValuePrinterAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/ValuePrinterRegistry.hpp
 create mode 100644 alib2common/src/abstraction/VoidOperationAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/XmlFileWriterAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/XmlFileWriterRegistry.hpp
 create mode 100644 alib2common/src/abstraction/XmlParserAbstraction.hpp
 create mode 100644 alib2common/src/abstraction/XmlParserRegistry.hpp

diff --git a/alib2common/src/abstraction/AlgorithmAbstraction.hpp b/alib2common/src/abstraction/AlgorithmAbstraction.hpp
new file mode 100644
index 0000000000..273789b692
--- /dev/null
+++ b/alib2common/src/abstraction/AlgorithmAbstraction.hpp
@@ -0,0 +1,175 @@
+/*
+ * AlgorithmAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _ALGORITHM_ABSTRACTION_HPP_
+#define _ALGORITHM_ABSTRACTION_HPP_
+
+#include <abstraction/ResultClassSelector.hpp>
+#include <tuple>
+#include <memory>
+#include <abstraction/Registry.h>
+
+namespace abstraction {
+
+template < class ReturnType, class ... ParamTypes >
+class Callback {
+	std::function < ReturnType ( ParamTypes ... ) > m_callback;
+
+public:
+	Callback ( std::function < ReturnType ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
+	}
+
+	ReturnType * operator ( ) ( ParamTypes ... params ) {
+		return new ReturnType ( m_callback ( std::forward < ParamTypes > ( params ) ... ) );
+	}
+};
+
+template < class ReturnType, class ... ParamTypes >
+class Callback < ReturnType *, ParamTypes ... > {
+	std::function < ReturnType * ( ParamTypes ... ) > m_callback;
+
+public:
+	Callback ( std::function < ReturnType * ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
+	}
+
+	ReturnType * operator ( ) ( ParamTypes ... params ) {
+		return m_callback ( std::forward < ParamTypes > ( params ) ... );
+	}
+};
+
+template < class ReturnType, class ... ParamTypes >
+class AlgorithmAbstractionBase : public ResultClassSelector < ReturnType >::OutputClass {
+protected:
+	std::tuple < std::shared_ptr < ValueOperationAbstraction < typename std::decay < ParamTypes >::type > > ... > inputs;
+
+	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) override {
+		auto attachCallback = [ & ] ( auto & param ) {
+			if ( param != nullptr )
+				return false;
+
+			typename std::decay < decltype ( param )>::type validData = std::dynamic_pointer_cast < typename std::decay < decltype ( param ) >::type::element_type > ( input );
+			if ( validData ) {
+				param = validData;
+				return true;
+			} else {
+				return false;
+			}
+		};
+		return std::call_on_nth < bool > ( inputs, index, attachCallback );
+	}
+
+	virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) override {
+		bool res = false;
+		std::foreach ( inputs, [ & ] ( auto & param ) {
+				if ( param == input ) {
+					param = nullptr;
+					res = true;
+				}
+			} );
+		return res;
+	}
+
+public:
+	virtual bool inputsReady ( ) const override {
+		auto readyCallback = [ ] ( const auto & param ) {
+			return ( bool ) param && param->isReady ( );
+		};
+
+		return all_of ( inputs, readyCallback );
+	}
+
+	virtual bool inputsAttached ( ) const override {
+		auto attachedCallback = [ ] ( const auto & param ) {
+			return ( bool ) param;
+		};
+
+		return all_of ( inputs, attachedCallback );
+	}
+
+	virtual bool eval ( ) override {
+		if ( ! inputsAttached ( ) )
+			return false;
+
+		if ( this->cached ( ) )
+			return true;
+
+		auto evalCallback = [ ] ( const auto & param ) {
+			return param->eval ( );
+		};
+
+		if ( ! all_of ( inputs, evalCallback ) )
+			return false;
+
+		return this->run ( );
+	}
+
+	virtual unsigned numberOfParams ( ) const override {
+		return sizeof ... ( ParamTypes );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getImmediateValueFromParam ( unsigned index, const std::string & value ) const override {
+		auto callback = [ & ] ( auto & param ) {
+			std::string paramType = std::type_name < typename std::decay < decltype ( param ) >::type::element_type::return_type > ( );
+			return Registry::getImmediateAbstraction ( std::move ( paramType ), value );
+		};
+		return std::call_on_nth < std::shared_ptr < OperationAbstraction > > ( inputs, index, callback );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getXmlParserFromParam ( unsigned index, std::deque < sax::Token > tokens ) const override {
+		auto callback = [ & ] ( auto & param ) {
+			std::string paramType = std::type_name < typename std::decay < decltype ( param ) >::type::element_type::return_type > ( );
+			return Registry::getXmlParserAbstraction ( std::move ( paramType ), std::move ( tokens ) );
+		};
+		return std::call_on_nth < std::shared_ptr < OperationAbstraction > > ( inputs, index, callback );
+	}
+};
+
+template < class ReturnType, class ... ParamTypes >
+class AlgorithmAbstraction : public AlgorithmAbstractionBase < ReturnType, ParamTypes ... > {
+	Callback < ReturnType, ParamTypes ... > m_callback;
+
+public:
+	AlgorithmAbstraction ( std::function < ReturnType ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
+	}
+
+	virtual bool run ( ) override {
+		if ( ! this->inputsReady ( ) )
+			return false;
+
+		if ( this->cached ( ) )
+			return true;
+
+		this->run_helper ( m_callback, this->inputs, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } );
+		return true;
+	}
+
+};
+
+template < class ReturnType, class ... ParamTypes >
+class AlgorithmAbstraction < ReturnType *, ParamTypes ... > : public AlgorithmAbstractionBase < ReturnType, ParamTypes ... > {
+	Callback < ReturnType *, ParamTypes ... > m_callback;
+
+public:
+	AlgorithmAbstraction ( std::function < ReturnType * ( ParamTypes ... ) > callback ) : m_callback ( callback ) {
+	}
+
+	virtual bool run ( ) override {
+		if ( ! this->inputsReady ( ) )
+			return false;
+
+		if ( this->cached ( ) )
+			return true;
+
+		this->run_helper ( m_callback, this->inputs, std::make_index_sequence < sizeof ... ( ParamTypes ) > { } );
+		return true;
+	}
+
+};
+
+} /* namespace abstraction */
+
+#endif /* _ALGORITHM_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/AlgorithmRegistry.hpp b/alib2common/src/abstraction/AlgorithmRegistry.hpp
new file mode 100644
index 0000000000..79d6b70075
--- /dev/null
+++ b/alib2common/src/abstraction/AlgorithmRegistry.hpp
@@ -0,0 +1,125 @@
+/*
+ * AlgorithmRegistry.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _ALGORITHM_REGISTRY_HPP_
+#define _ALGORITHM_REGISTRY_HPP_
+
+#include <functional>
+#include <memory>
+#include <vector>
+#include <string>
+
+#include <exception/CommonException.h>
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class AlgorithmRegistry {
+	class Entry {
+		bool m_downcast;
+		bool m_normalize;
+
+	public:
+		Entry ( bool downcast, bool normalize ) : m_downcast ( downcast ), m_normalize ( normalize ) {
+
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0;
+
+		bool getDowncast ( ) const {
+			return m_downcast;
+		}
+
+		bool getNormalize ( ) const {
+			return m_normalize;
+		}
+	};
+
+	template < class Return, class ... Params >
+	class EntryImpl : public Entry {
+		std::function < Return ( Params ... ) > m_callback;
+
+	public:
+		EntryImpl ( std::function < Return ( Params ... ) > callback, bool downcast, bool normalize ) : Entry ( downcast, normalize ), m_callback ( callback ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
+	};
+
+	template < class Return, class ... Params >
+	class EntryImpl < Return *, Params ... > : public Entry {
+		std::function < Return * ( Params ... ) > m_callback;
+
+	public:
+		EntryImpl ( std::function < Return * ( Params ... ) > callback, bool downcast, bool normalize ) : Entry ( downcast, normalize ), m_callback ( callback ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
+	};
+
+	static std::map < std::string, std::map < std::vector < std::type_index >, std::unique_ptr < Entry > > > & getEntries ( ) {
+		static std::map < std::string, std::map < std::vector < std::type_index >, std::unique_ptr < Entry > > > algorithmGroups;
+		return algorithmGroups;
+	};
+
+public:
+	template < class Algo, class ReturnType, class ... ParamTypes >
+	static void registerAlgorithm ( ReturnType ( * callback ) ( ParamTypes ... ), bool downcast, bool normalize ) {
+		std::string algorithm = std::type_name < Algo > ( );
+
+		std::vector < std::type_index > params;
+		( void ) std::initializer_list < int > { ( params.push_back ( std::type_index ( typeid ( typename std::decay < ParamTypes >::type ) ) ), 0 ) ... };
+
+		if ( ! getEntries ( ) [ algorithm ].insert ( std::make_pair ( params, std::unique_ptr < Entry > ( new EntryImpl < ReturnType, ParamTypes ... > ( callback, downcast, normalize ) ) ) ).second )
+			throw ::exception::CommonException ( "Callback for " + algorithm + " already registered." );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes, bool & downcast, bool & normalize ) {
+		auto group = getEntries ( ).find ( name );
+		if ( group == getEntries ( ).end ( ) )
+			throw exception::CommonException ( "Entry " + name + " not available" );
+
+		auto overload = group->second.find ( paramTypes );
+		if ( overload == group->second.end ( ) ) {
+			std::stringstream ss;
+			ss << paramTypes;
+
+			throw exception::CommonException ( "Entry overload " + ss.str ( ) + " not available" );
+		}
+
+		downcast = overload->second->getDowncast ( );
+		normalize = overload->second->getNormalize ( );
+
+		return overload->second->getAbstraction ( );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes ) {
+		bool downcast;
+		bool normalize;
+		return getAbstraction ( std::move ( name ), paramTypes, downcast, normalize );
+	}
+};
+
+} /* namespace abstraction */
+
+#include <abstraction/AlgorithmAbstraction.hpp>
+
+namespace abstraction {
+
+template < class Return, class ... Params >
+std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::EntryImpl < Return, Params ... >::getAbstraction ( ) const {
+	return std::make_shared < abstraction::AlgorithmAbstraction < Return, Params ... > > ( m_callback );
+}
+
+template < class Return, class ... Params >
+std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::EntryImpl < Return *, Params ... >::getAbstraction ( ) const {
+	return std::make_shared < abstraction::AlgorithmAbstraction < Return *, Params ... > > ( m_callback );
+}
+
+} /* namespace abstraction */
+
+#endif /* _ALGORITHM_REGISTRY_HPP_ */
diff --git a/alib2common/src/abstraction/CastAbstraction.hpp b/alib2common/src/abstraction/CastAbstraction.hpp
new file mode 100644
index 0000000000..87ce0eb5cb
--- /dev/null
+++ b/alib2common/src/abstraction/CastAbstraction.hpp
@@ -0,0 +1,37 @@
+/*
+ * CastAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _CAST_ABSTRACTION_HPP_
+#define _CAST_ABSTRACTION_HPP_
+
+#include <abstraction/UnaryOperationAbstraction.hpp>
+#include <tuple>
+
+namespace abstraction {
+
+template < class ReturnType, class ParamType >
+class CastAbstraction : public UnaryOperationAbstraction < ReturnType, ParamType > {
+public:
+	CastAbstraction ( ) {
+	}
+
+	virtual bool run ( ) override {
+		if ( ! this->inputsReady ( ) )
+			return false;
+
+		if ( this->cached ( ) )
+			return true;
+
+		this->m_data = std::unique_ptr < ReturnType > ( new ReturnType ( this->m_param->getData ( ) ) );
+
+		return true;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _CAST_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/CastRegistry.hpp b/alib2common/src/abstraction/CastRegistry.hpp
new file mode 100644
index 0000000000..f365c635a6
--- /dev/null
+++ b/alib2common/src/abstraction/CastRegistry.hpp
@@ -0,0 +1,108 @@
+/*
+ * CastRegistry.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _CAST_REGISTRY_HPP_
+#define _CAST_REGISTRY_HPP_
+
+#include <memory>
+#include <string>
+
+#include <exception/CommonException.h>
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class CastRegistry {
+	class Entry {
+	public:
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0;
+
+	};
+
+	template < class Return, class Param >
+	class DefaultEntryImpl : public Entry {
+	public:
+		DefaultEntryImpl ( ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
+	};
+
+	template < class Return, class Param >
+	class AlgorithmEntryImpl : public Entry {
+		std::function < Return ( Param ) > m_callback;
+	public:
+		AlgorithmEntryImpl ( std::function < Return ( Param ) > callback ) : m_callback ( callback ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
+	};
+
+	static std::map < std::pair < std::string, std::string >, std::unique_ptr < Entry > > & getEntries ( ) {
+		static std::map < std::pair < std::string, std::string >, std::unique_ptr < Entry > > casts;
+		return casts;
+	};
+
+public:
+	template < class TargetType, class ParamType >
+	static void registerCast ( std::string target, std::string param ) {
+		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new DefaultEntryImpl < TargetType, ParamType > ( ) ) ) ).second )
+			throw ::exception::CommonException ( "Entry from " + param + " to " + target + " already registered." );
+	}
+
+	template < class TargetType, class ParamType >
+	static void registerCast ( ) {
+		std::string target = std::type_name < TargetType > ( );
+		std::string param = std::type_name < ParamType > ( );
+
+		registerCast < TargetType, ParamType > ( target, param );
+	}
+
+	template < class TargetType, class ParamType >
+	static void registerCastAlgorithm ( std::string target, std::string param, TargetType ( * callback ) ( ParamType ) ) {
+		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( target, param ), std::unique_ptr < Entry > ( new AlgorithmEntryImpl < TargetType, ParamType > ( callback ) ) ) ).second )
+			throw ::exception::CommonException ( "Entry from " + param + " to " + target + " already registered." );
+	}
+
+	template < class TargetType, class ParamType >
+	static void registerCastAlgorithm ( TargetType ( * callback ) ( ParamType ) ) {
+		std::string target = std::type_name < TargetType > ( );
+		std::string param = std::type_name < ParamType > ( );
+
+		registerCastAlgorithm < TargetType, ParamType > ( target, param, callback );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string target, std::string param ) {
+		auto cast = getEntries ( ).find ( std::make_pair ( target, param ) );
+		if ( cast == getEntries ( ).end ( ) )
+			throw exception::CommonException ( "Entry from " + param + " to " + target + " not available." );
+
+		return cast->second->getAbstraction ( );
+	}
+
+};
+
+} /* namespace abstraction */
+
+#include <abstraction/CastAbstraction.hpp>
+#include <abstraction/AlgorithmAbstraction.hpp>
+
+namespace abstraction {
+
+template < class Return, class Param >
+std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::DefaultEntryImpl < Return, Param >::getAbstraction ( ) const {
+	return std::make_shared < abstraction::CastAbstraction < Return, Param > > ( );
+}
+
+template < class Return, class Param >
+std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::AlgorithmEntryImpl < Return, Param >::getAbstraction ( ) const {
+	return std::make_shared < abstraction::AlgorithmAbstraction < Return, Param > > ( m_callback );
+}
+
+} /* namespace abstraction */
+
+#endif /* _CAST_REGISTRY_HPP_ */
diff --git a/alib2common/src/abstraction/DowncastAbstraction.hpp b/alib2common/src/abstraction/DowncastAbstraction.hpp
new file mode 100644
index 0000000000..71504db528
--- /dev/null
+++ b/alib2common/src/abstraction/DowncastAbstraction.hpp
@@ -0,0 +1,37 @@
+/*
+ * DowncastAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _DOWNCAST_ABSTRACTION_HPP_
+#define _DOWNCAST_ABSTRACTION_HPP_
+
+#include <abstraction/UnaryOperationAbstraction.hpp>
+#include <memory>
+
+namespace abstraction {
+
+template < class ConcreteType, class BaseType >
+class DowncastAbstraction : public UnaryOperationAbstraction < ConcreteType, BaseType > {
+public:
+	DowncastAbstraction ( ) {
+	}
+
+	virtual bool run ( ) override {
+		if ( ! this->inputsReady ( ) )
+			return false;
+
+		if ( this->cached ( ) )
+			return true;
+
+		this->m_data = std::unique_ptr < ConcreteType > ( static_cast < ConcreteType * > ( this->m_param->getData ( ).clone ( ) ) );
+
+		return true;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _DOWNCAST_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/DowncastRegistry.hpp b/alib2common/src/abstraction/DowncastRegistry.hpp
new file mode 100644
index 0000000000..223fe6ced4
--- /dev/null
+++ b/alib2common/src/abstraction/DowncastRegistry.hpp
@@ -0,0 +1,71 @@
+/*
+ * DowncastRegistry.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _DOWNCAST_REGISTRY_HPP_
+#define _DOWNCAST_REGISTRY_HPP_
+
+#include <memory>
+#include <string>
+
+#include <exception/CommonException.h>
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class DowncastRegistry {
+	class Entry {
+	public:
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0;
+
+	};
+
+	template < class ConcreteType, class BaseType >
+	class EntryImpl : public Entry {
+	public:
+		EntryImpl ( ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
+	};
+
+	static std::map < std::pair < std::string, std::string >, std::unique_ptr < Entry > > & getEntries ( ) {
+		static std::map < std::pair < std::string, std::string >, std::unique_ptr < Entry > > fileWriters;
+		return fileWriters;
+	}
+
+public:
+	template < class ConcreteType, class BaseType >
+	static void registerDowncast ( ) {
+		std::string concrete = std::type_name < ConcreteType > ( );
+		std::string base = std::type_name < BaseType > ( );
+		if ( ! getEntries ( ).insert ( std::make_pair ( std::make_pair ( concrete, base ), std::unique_ptr < Entry > ( new EntryImpl < ConcreteType, BaseType > ( ) ) ) ).second )
+			throw ::exception::CommonException ( "Downcasting for " + base + " to " + concrete + " already registered." );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string concrete, std::string base ) {
+		auto res = getEntries ( ).find ( std::make_pair ( concrete, base ) );
+		if ( res == getEntries ( ).end ( ) )
+			throw exception::CommonException ( "Entry " + concrete + ", " + base + " not available." );
+
+		return res->second->getAbstraction ( );
+	}
+};
+
+} /* namespace abstraction */
+
+#include <abstraction/DowncastAbstraction.hpp>
+
+namespace abstraction {
+
+template < class ConcreteType, class BaseType >
+std::shared_ptr < abstraction::OperationAbstraction > DowncastRegistry::EntryImpl < ConcreteType, BaseType >::getAbstraction ( ) const {
+	return std::make_shared < DowncastAbstraction < ConcreteType, BaseType > > ( );
+}
+
+} /* namespace abstraction */
+
+#endif /* _DOWNCAST_REGISTRY_HPP_ */
diff --git a/alib2common/src/abstraction/ImmediateRegistry.hpp b/alib2common/src/abstraction/ImmediateRegistry.hpp
new file mode 100644
index 0000000000..2a63eb4f6f
--- /dev/null
+++ b/alib2common/src/abstraction/ImmediateRegistry.hpp
@@ -0,0 +1,77 @@
+/*
+ * ImmediateRegistry.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _IMMEDIATE_REGISTRY_HPP_
+#define _IMMEDIATE_REGISTRY_HPP_
+
+#include <factory/XmlDataFactory.hpp>
+
+#include <memory>
+#include <string>
+
+#include <exception/CommonException.h>
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class ImmediateRegistry {
+	class Entry {
+	public:
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string value ) const = 0;
+
+	};
+
+	template < class Result >
+	class EntryImpl : public Entry {
+	public:
+		EntryImpl ( ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string value ) const override;
+	};
+
+	static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) {
+		static std::map < std::string, std::unique_ptr < Entry > > fileWriters;
+		return fileWriters;
+	}
+
+public:
+	template < class ResultType >
+	static void registerImmediate ( std::string result ) {
+		if ( ! getEntries ( ).insert ( std::make_pair ( result, std::unique_ptr < Entry > ( new EntryImpl < ResultType > ( ) ) ) ).second )
+			throw ::exception::CommonException ( "Entry " + result + " already registered." );
+	}
+
+	template < class ResultType >
+	static void registerImmediate ( ) {
+		std::string result = std::type_name < ResultType > ( );
+		registerImmediate < ResultType > ( std::move ( result ) );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string result, std::string value ) {
+		auto res = getEntries ( ).find ( result );
+		if ( res == getEntries ( ).end ( ) )
+			throw exception::CommonException ( "Entry " + result + " not available." );
+
+		return res->second->getAbstraction ( value );
+	}
+};
+
+} /* namespace abstraction */
+
+#include <abstraction/ImmediateValueAbstraction.hpp>
+
+namespace abstraction {
+
+template < class Result >
+std::shared_ptr < abstraction::OperationAbstraction > ImmediateRegistry::EntryImpl < Result >::getAbstraction ( std::string value ) const {
+	return std::make_shared < ImmediateValueAbstraction < Result > > ( std::from_string < Result > ( value ) );
+}
+
+} /* namespace abstraction */
+
+#endif /* _IMMEDIATE_REGISTRY_HPP_ */
diff --git a/alib2common/src/abstraction/ImmediateValueAbstraction.hpp b/alib2common/src/abstraction/ImmediateValueAbstraction.hpp
new file mode 100644
index 0000000000..286c7947b0
--- /dev/null
+++ b/alib2common/src/abstraction/ImmediateValueAbstraction.hpp
@@ -0,0 +1,30 @@
+/*
+ * ImmediateValueAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _IMMEDIATE_VALUE_ABSTRACTION_HPP_
+#define _IMMEDIATE_VALUE_ABSTRACTION_HPP_
+
+#include <abstraction/NullaryOperationAbstraction.hpp>
+#include <tuple>
+
+namespace abstraction {
+
+template < class ReturnType >
+class ImmediateValueAbstraction : public NullaryOperationAbstraction < ReturnType > {
+public:
+	ImmediateValueAbstraction ( ReturnType result ) {
+		this->m_data = std::unique_ptr < ReturnType > ( new ReturnType ( result ) );
+	}
+
+	virtual bool run ( ) override {
+		return true;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _IMMEDIATE_VALUE_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/NormalizeAbstraction.hpp b/alib2common/src/abstraction/NormalizeAbstraction.hpp
new file mode 100644
index 0000000000..a0aa378852
--- /dev/null
+++ b/alib2common/src/abstraction/NormalizeAbstraction.hpp
@@ -0,0 +1,37 @@
+/*
+ * NormalizeAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _NORMALIZE_ABSTRACTION_HPP_
+#define _NORMALIZE_ABSTRACTION_HPP_
+
+#include <abstraction/UnaryOperationAbstraction.hpp>
+#include <tuple>
+
+namespace abstraction {
+
+template < class ReturnType, class ParamType >
+class NormalizeAbstraction : public UnaryOperationAbstraction < ReturnType, ParamType > {
+public:
+	NormalizeAbstraction ( ) {
+	}
+
+	virtual bool run ( ) override {
+		if ( ! this->inputsReady ( ) )
+			return false;
+
+		if ( this->cached ( ) )
+			return true;
+
+		this->m_data = std::unique_ptr < ReturnType > ( ( ReturnType * ) std::move ( this->m_param->getData ( ) ).normalize ( ) );
+
+		return true;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _NORMALIZE_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/NormalizeRegistry.hpp b/alib2common/src/abstraction/NormalizeRegistry.hpp
new file mode 100644
index 0000000000..45d4429f5f
--- /dev/null
+++ b/alib2common/src/abstraction/NormalizeRegistry.hpp
@@ -0,0 +1,74 @@
+/*
+ * NormalizeRegistry.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _NORMALIZE_REGISTRY_HPP_
+#define _NORMALIZE_REGISTRY_HPP_
+
+#include <memory>
+#include <string>
+
+#include <exception/CommonException.h>
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class NormalizeRegistry {
+	class Entry {
+	public:
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0;
+
+	};
+
+	template < class Param >
+	class EntryImpl : public Entry {
+	public:
+		EntryImpl ( ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
+	};
+
+	static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) {
+		static std::map < std::string, std::unique_ptr < Entry > > fileWriters;
+		return fileWriters;
+	}
+
+public:
+	template < class ParamType >
+	static void registerNormalize ( std::string param ) {
+		getEntries ( ).insert ( std::make_pair ( param, std::unique_ptr < Entry > ( new EntryImpl < ParamType > ( ) ) ) );
+	}
+
+	template < class ParamType >
+	static void registerNormalize ( ) {
+		std::string param = std::type_name < ParamType > ( );
+		registerNormalize < ParamType > ( std::move ( param ) );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string param ) {
+		auto res = getEntries ( ).find ( param );
+		if ( res == getEntries ( ).end ( ) )
+			throw exception::CommonException ( "Entry " + param + " not available." );
+
+		return res->second->getAbstraction ( );
+	}
+};
+
+} /* namespace abstraction */
+
+#include <abstraction/NormalizeAbstraction.hpp>
+
+namespace abstraction {
+
+template < class Param >
+std::shared_ptr < abstraction::OperationAbstraction > NormalizeRegistry::EntryImpl < Param >::getAbstraction ( ) const {
+	return std::make_shared < NormalizeAbstraction < typename Param::normalized_type, Param > > ( );
+}
+
+} /* namespace abstraction */
+
+#endif /* _NORMALIZE_REGISTRY_HPP_ */
diff --git a/alib2common/src/abstraction/NullaryOperationAbstraction.hpp b/alib2common/src/abstraction/NullaryOperationAbstraction.hpp
new file mode 100644
index 0000000000..9885926381
--- /dev/null
+++ b/alib2common/src/abstraction/NullaryOperationAbstraction.hpp
@@ -0,0 +1,60 @@
+/*
+ * NullaryOperationAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _NULLARY_OPERATION_ABSTRACTION_HPP_
+#define _NULLARY_OPERATION_ABSTRACTION_HPP_
+
+#include <abstraction/ResultClassSelector.hpp>
+#include <exception/CommonException.h>
+
+namespace abstraction {
+
+template < class ReturnType >
+class NullaryOperationAbstraction : public ResultClassSelector < ReturnType >::OutputClass {
+	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > &, unsigned ) override {
+		return false;
+	}
+
+	virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & ) override {
+		return true;
+	}
+
+public:
+	NullaryOperationAbstraction ( ) {
+	}
+
+	virtual bool inputsReady ( ) const override {
+		return true;
+	}
+
+	virtual bool inputsAttached ( ) const override {
+		return true;
+	}
+
+	virtual bool eval ( ) override {
+		if ( this->cached ( ) )
+			return true;
+
+		return this->run ( );
+	}
+
+	virtual unsigned numberOfParams ( ) const override {
+		return 0;
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getImmediateValueFromParam ( unsigned, const std::string & ) const override {
+		throw exception::CommonException ( "Nullary algorithm does not have any parameter." );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getXmlParserFromParam ( unsigned, std::deque < sax::Token > ) const override {
+		throw exception::CommonException ( "Nullary algorithm does not have any parameter." );
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _NULLARY_OPERATION_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/OperationAbstraction.hpp b/alib2common/src/abstraction/OperationAbstraction.hpp
new file mode 100644
index 0000000000..fbd76dab58
--- /dev/null
+++ b/alib2common/src/abstraction/OperationAbstraction.hpp
@@ -0,0 +1,51 @@
+/*
+ * OperationAbstraction.hpp
+ *
+ *  Created on: 10. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _OPERATION_ABSTRACTION_HPP_
+#define _OPERATION_ABSTRACTION_HPP_
+
+#include <memory>
+#include <string>
+#include <tuple>
+#include <functional>
+
+#include <exception/CommonException.h>
+#include <factory/XmlDataFactory.hpp>
+
+namespace abstraction {
+
+class OperationAbstraction : public std::enable_shared_from_this < OperationAbstraction > {
+public:
+	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) = 0;
+	virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) = 0;
+
+	virtual ~OperationAbstraction ( ) noexcept {
+	}
+
+	virtual bool inputsReady ( ) const = 0;
+	virtual bool inputsAttached ( ) const = 0;
+	virtual bool run ( ) = 0;
+	virtual bool eval ( ) = 0;
+	virtual std::type_index type ( ) const = 0;
+	virtual std::type_index runtime_type ( ) const = 0;
+	virtual unsigned numberOfParams ( ) const = 0;
+	virtual bool cached ( ) const = 0;
+
+	virtual std::shared_ptr < OperationAbstraction > getXmlParserFromParam ( unsigned index, std::deque < sax::Token > tokens ) const = 0;
+	virtual std::shared_ptr < OperationAbstraction > getImmediateValueFromParam ( unsigned index, const std::string & data ) const = 0;
+
+	virtual std::shared_ptr < OperationAbstraction > getXmlFileWriterFromResult ( const std::string & filename ) const = 0;
+	virtual std::shared_ptr < OperationAbstraction > getValuePrinterFromResult ( ) const = 0;
+	virtual std::shared_ptr < OperationAbstraction > getCastFromResult ( const std::string & type ) const = 0;
+	virtual std::shared_ptr < OperationAbstraction > getNormalizeResult ( ) const = 0;
+	virtual std::shared_ptr < OperationAbstraction > getDowncastResult ( ) const = 0;
+
+};
+
+} /* namespace abstraction */
+
+#endif /* _OPERATION_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/PrimitiveRegistrator.cpp b/alib2common/src/abstraction/PrimitiveRegistrator.cpp
new file mode 100644
index 0000000000..f8545dcee2
--- /dev/null
+++ b/alib2common/src/abstraction/PrimitiveRegistrator.cpp
@@ -0,0 +1,54 @@
+/*
+ * PrimitiveRegistrator.cpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#include "CastRegistry.hpp"
+#include "XmlFileWriterRegistry.hpp"
+#include "NormalizeRegistry.hpp"
+#include "ValuePrinterRegistry.hpp"
+#include "ImmediateRegistry.hpp"
+
+#include <primitive/Double.h>
+#include <primitive/Integer.h>
+#include <primitive/Bool.h>
+#include <primitive/UnsignedLong.h>
+#include <primitive/String.h>
+
+namespace abstraction {
+
+class PrimitiveCasts {
+public:
+	PrimitiveCasts ( ) {
+		abstraction::CastRegistry::registerCast < double, int > ( );
+		abstraction::CastRegistry::registerCast < int, double > ( );
+
+		abstraction::CastRegistry::registerCastAlgorithm < std::string, int > ( std::to_string );
+		abstraction::CastRegistry::registerCastAlgorithm < int, std::string > ( (int(*)(std::string)) std::from_string < int > );
+
+		abstraction::CastRegistry::registerCast < bool, int > ( );
+
+		abstraction::CastRegistry::registerCast < size_t, int > ( "size_t", std::type_name < int > ( ) );
+		abstraction::CastRegistry::registerCast < size_t, int > ( );
+		abstraction::CastRegistry::registerCast < int, size_t > ( );
+
+		abstraction::CastRegistry::registerCast < int, primitive::Integer > ( );
+	
+		abstraction::XmlFileWriterRegistry::registerXmlFileWriter < int > ( );
+		abstraction::XmlFileWriterRegistry::registerXmlFileWriter < double > ( );
+		abstraction::XmlFileWriterRegistry::registerXmlFileWriter < std::string > ( );
+
+		abstraction::ValuePrinterRegistry::registerValuePrinter < int > ( );
+		abstraction::ValuePrinterRegistry::registerValuePrinter < double > ( );
+		abstraction::ValuePrinterRegistry::registerValuePrinter < std::string > ( );
+
+		abstraction::ImmediateRegistry::registerImmediate < int > ( );
+		abstraction::ImmediateRegistry::registerImmediate < std::string > ( );
+	}
+};
+
+auto primitiveCasts = PrimitiveCasts ( );
+
+} /* namespace abstraction */
diff --git a/alib2common/src/abstraction/Registry.cpp b/alib2common/src/abstraction/Registry.cpp
new file mode 100644
index 0000000000..25cd777c4c
--- /dev/null
+++ b/alib2common/src/abstraction/Registry.cpp
@@ -0,0 +1,57 @@
+/*
+ * Registry.cpp
+ *
+ *  Created on: 10. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#include <abstraction/Registry.h>
+
+#include <abstraction/AlgorithmRegistry.hpp>
+#include <abstraction/ImmediateRegistry.hpp>
+#include <abstraction/XmlParserRegistry.hpp>
+#include <abstraction/XmlFileWriterRegistry.hpp>
+#include <abstraction/ValuePrinterRegistry.hpp>
+#include <abstraction/CastRegistry.hpp>
+#include <abstraction/NormalizeRegistry.hpp>
+#include <abstraction/DowncastRegistry.hpp>
+
+namespace abstraction {
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getAlgorithmAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes ) {
+	return AlgorithmRegistry::getAbstraction ( std::move ( name ), paramTypes );
+}
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getAlgorithmAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes, bool & unwrap, bool & normalize ) {
+	return AlgorithmRegistry::getAbstraction ( std::move ( name ), paramTypes, unwrap, normalize );
+}
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getCastAbstraction ( std::string target, std::string param ) {
+	return CastRegistry::getAbstraction ( std::move ( target ), std::move ( param ) );
+}
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getImmediateAbstraction ( std::string result, std::string value ) {
+	return ImmediateRegistry::getAbstraction ( std::move ( result ), std::move ( value ) );
+}
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getNormalizeAbstraction ( std::string param ) {
+	return NormalizeRegistry::getAbstraction ( std::move ( param ) );
+}
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getDowncastAbstraction ( std::string concrete, std::string base ) {
+	return DowncastRegistry::getAbstraction ( std::move ( concrete ), std::move ( base ) );
+}
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getValuePrinterAbstraction ( std::string param ) {
+	return ValuePrinterRegistry::getAbstraction ( std::move ( param ) );
+}
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getXmlFileWriterAbstraction ( std::string param, std::string filename ) {
+	return XmlFileWriterRegistry::getAbstraction ( std::move ( param ), std::move ( filename ) );
+}
+
+std::shared_ptr < abstraction::OperationAbstraction > Registry::getXmlParserAbstraction ( std::string typeName, std::deque < sax::Token > tokens ) {
+	return XmlParserRegistry::getAbstraction ( std::move ( typeName ), std::move ( tokens ) );
+}
+
+} /* namespace abstraction */
diff --git a/alib2common/src/abstraction/Registry.h b/alib2common/src/abstraction/Registry.h
new file mode 100644
index 0000000000..e61f1d5075
--- /dev/null
+++ b/alib2common/src/abstraction/Registry.h
@@ -0,0 +1,31 @@
+/*
+ * Registry.h
+ *
+ *  Created on: 10. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _REGISTRY_H_
+#define _REGISTRY_H_
+
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class Registry {
+public:
+	static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes );
+	static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( std::string name, const std::vector < std::type_index > & paramTypes, bool & unwrap, bool & normalize );
+	static std::shared_ptr < abstraction::OperationAbstraction > getCastAbstraction ( std::string target, std::string param );
+	static std::shared_ptr < abstraction::OperationAbstraction > getImmediateAbstraction ( std::string result, std::string value );
+	static std::shared_ptr < abstraction::OperationAbstraction > getNormalizeAbstraction ( std::string param );
+	static std::shared_ptr < abstraction::OperationAbstraction > getDowncastAbstraction ( std::string concrete, std::string base );
+	static std::shared_ptr < abstraction::OperationAbstraction > getValuePrinterAbstraction ( std::string param );
+	static std::shared_ptr < abstraction::OperationAbstraction > getXmlFileWriterAbstraction ( std::string param, std::string filename );
+	static std::shared_ptr < abstraction::OperationAbstraction > getXmlParserAbstraction ( std::string typeName, std::deque < sax::Token > tokens );
+};
+
+} /* namespace abstraction */
+
+#endif /* _REGISTRY_H_ */
+
diff --git a/alib2common/src/abstraction/ResultClassSelector.hpp b/alib2common/src/abstraction/ResultClassSelector.hpp
new file mode 100644
index 0000000000..b7a2813252
--- /dev/null
+++ b/alib2common/src/abstraction/ResultClassSelector.hpp
@@ -0,0 +1,29 @@
+/*
+ * ResultClassSelector.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _RESULT_CLASS_SELECTOR_H_
+#define _RESULT_CLASS_SELECTOR_H_
+
+#include <abstraction/VoidOperationAbstraction.hpp>
+#include <abstraction/ValueOperationAbstraction.hpp>
+#include <tuple>
+
+namespace abstraction {
+
+template < class ReturnType >
+struct ResultClassSelector {
+	typedef ValueOperationAbstraction < ReturnType > OutputClass;
+};
+
+template < >
+struct ResultClassSelector < void > {
+	typedef VoidOperationAbstraction OutputClass;
+};
+
+} /* namespace abstraction */
+
+#endif /* _RESULT_CLASS_SELECTOR_H_ */
diff --git a/alib2common/src/abstraction/UnaryOperationAbstraction.hpp b/alib2common/src/abstraction/UnaryOperationAbstraction.hpp
new file mode 100644
index 0000000000..6b443e2087
--- /dev/null
+++ b/alib2common/src/abstraction/UnaryOperationAbstraction.hpp
@@ -0,0 +1,91 @@
+/*
+ * UnaryOperationAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _UNARY_OPERATION_ABSTRACTION_HPP_
+#define _UNARY_OPERATION_ABSTRACTION_HPP_
+
+#include <abstraction/ResultClassSelector.hpp>
+#include <tuple>
+#include <abstraction/Registry.h>
+
+namespace abstraction {
+
+template < class ReturnType, class ParamType >
+class UnaryOperationAbstraction : public ResultClassSelector < ReturnType >::OutputClass {
+protected:
+	std::shared_ptr < ValueOperationAbstraction < typename std::decay < ParamType >::type > > m_param;
+
+private:
+	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index ) override {
+		if ( index != 0 )
+			throw exception::CommonException ( "Out of range index: " + std::to_string ( index ) + " max: " + std::to_string ( numberOfParams ( ) ) + "." );
+
+		std::shared_ptr < ValueOperationAbstraction < ParamType > > validData = std::dynamic_pointer_cast < ValueOperationAbstraction < ParamType > > ( input );
+		if ( validData ) {
+			m_param = validData;
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	virtual bool detachInput ( const std::shared_ptr < OperationAbstraction > & input ) override {
+		if ( m_param != input )
+			return false;
+
+		m_param = nullptr;
+		return true;
+	}
+
+public:
+	UnaryOperationAbstraction ( ) {
+	}
+
+	virtual bool inputsReady ( ) const override {
+		return m_param && m_param->isReady ( );
+	}
+
+	virtual bool inputsAttached ( ) const override {
+		return ( bool ) m_param;
+	}
+
+	virtual bool eval ( ) override {
+		if ( ! inputsAttached ( ) )
+			return false;
+
+		if ( this->cached ( ) )
+			return true;
+
+		this->m_param->eval ( );
+
+		return this->run ( );
+	}
+
+	virtual unsigned numberOfParams ( ) const override {
+		return 1;
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getImmediateValueFromParam ( unsigned index, const std::string & value ) const override {
+		if ( index != 0 )
+			throw std::out_of_range ( "Invalid input index" );
+
+		std::string paramType = std::type_name < ParamType > ( );
+		return Registry::getImmediateAbstraction ( std::move ( paramType ), value );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getXmlParserFromParam ( unsigned index, std::deque < sax::Token > tokens ) const override {
+		if ( index != 0 )
+			throw exception::CommonException ( "Out of range index: " + std::to_string ( index ) + " max: " + std::to_string ( numberOfParams ( ) ) + "." );
+
+		std::string paramType = std::type_name < ParamType > ( );
+		return Registry::getXmlParserAbstraction ( std::move ( paramType ), std::move ( tokens ) );
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _UNARY_OPERATION_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/ValueOperationAbstraction.hpp b/alib2common/src/abstraction/ValueOperationAbstraction.hpp
new file mode 100644
index 0000000000..85f5aa9c6a
--- /dev/null
+++ b/alib2common/src/abstraction/ValueOperationAbstraction.hpp
@@ -0,0 +1,91 @@
+/*
+ * ValueOperationAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _VALUE_OPERATION_ABSTRACTION_HPP_
+#define _VALUE_OPERATION_ABSTRACTION_HPP_
+
+#include <abstraction/OperationAbstraction.hpp>
+#include <tuple>
+#include <memory>
+#include <typeindex>
+#include <abstraction/Registry.h>
+
+namespace abstraction {
+
+template < class ReturnType >
+class ValueOperationAbstraction : public OperationAbstraction {
+protected:
+	std::unique_ptr < ReturnType > m_data;
+
+public:
+	typedef ReturnType return_type;
+
+	template < typename Callable, typename ... Ts, size_t ... Indexes >
+	inline void run_helper ( Callable callback, const std::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) {
+		if ( m_data == nullptr )
+			m_data = std::unique_ptr < ReturnType > ( callback ( std::get < Indexes > ( inputs )->getData ( ) ... ) );
+	}
+
+	template < typename Callable, typename T >
+	inline void run_helper ( Callable callback, const T & input ) const {
+		if ( m_data == nullptr )
+			m_data = std::unique_ptr < ReturnType > ( callback ( input->getData ( ) ) );
+	}
+
+	bool isReady ( ) const {
+		return m_data != nullptr;
+	}
+
+	ReturnType & getData ( ) const {
+		return * m_data;
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getXmlFileWriterFromResult ( const std::string & filename ) const override {
+		std::string param = std::type_name < ReturnType > ( );
+		return Registry::getXmlFileWriterAbstraction ( param, filename );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getValuePrinterFromResult ( ) const override {
+		std::string param = std::type_name < ReturnType > ( );
+		return Registry::getValuePrinterAbstraction ( param );
+}
+
+	virtual std::shared_ptr < OperationAbstraction > getCastFromResult ( const std::string & target ) const override {
+		std::string param = std::type_name < ReturnType > ( );
+		return Registry::getCastAbstraction ( target, param );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getNormalizeResult ( ) const override {
+		std::string param = std::type_name < ReturnType > ( );
+		return Registry::getNormalizeAbstraction ( param );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getDowncastResult ( ) const override {
+		std::string base = std::type_name < ReturnType > ( );
+		std::string concrete = std::type_name ( runtime_type ( ) );
+		return Registry::getDowncastAbstraction ( concrete, base );
+	}
+
+	virtual std::type_index type ( ) const override {
+		return std::type_index ( typeid ( ReturnType ) );
+	}
+
+	virtual std::type_index runtime_type ( ) const override {
+		if ( isReady ( ) )
+			return std::type_index ( typeid ( getData ( ) ) );
+		else
+			throw exception::CommonException ( "Runtime type unknown before evaluation." );
+	}
+
+	virtual bool cached ( ) const override {
+		return isReady ( );
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _VALUE_OPERATION_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/ValuePrinterAbstraction.hpp b/alib2common/src/abstraction/ValuePrinterAbstraction.hpp
new file mode 100644
index 0000000000..ed87b2412e
--- /dev/null
+++ b/alib2common/src/abstraction/ValuePrinterAbstraction.hpp
@@ -0,0 +1,33 @@
+/*
+ * ValuePrinterAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _VALUE_PRINTER_ABSTRACTION_HPP_
+#define _VALUE_PRINTER_ABSTRACTION_HPP_
+
+#include <abstraction/UnaryOperationAbstraction.hpp>
+#include <tuple>
+
+namespace abstraction {
+
+template < class ParamType >
+class ValuePrinterAbstraction : public UnaryOperationAbstraction < void, ParamType > {
+public:
+	ValuePrinterAbstraction ( ) {
+	}
+
+	virtual bool run ( ) override {
+		if ( ! this->inputsReady ( ) )
+			return false;
+
+		std::cout << this->m_param->getData ( );
+		return true;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _VALUE_PRINTER_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/ValuePrinterRegistry.hpp b/alib2common/src/abstraction/ValuePrinterRegistry.hpp
new file mode 100644
index 0000000000..e18ceb73ec
--- /dev/null
+++ b/alib2common/src/abstraction/ValuePrinterRegistry.hpp
@@ -0,0 +1,74 @@
+/*
+ * ValuePrinterRegistry.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _VALUE_PRINTER_REGISTRY_HPP_
+#define _VALUE_PRINTER_REGISTRY_HPP_
+
+#include <memory>
+#include <string>
+
+#include <exception/CommonException.h>
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class ValuePrinterRegistry {
+	class Entry {
+	public:
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0;
+
+	};
+
+	template < class Param >
+	class EntryImpl : public Entry {
+	public:
+		EntryImpl ( ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
+	};
+
+	static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) {
+		static std::map < std::string, std::unique_ptr < Entry > > fileWriters;
+		return fileWriters;
+	}
+
+public:
+	template < class ParamType >
+	static void registerValuePrinter ( std::string param ) {
+		getEntries ( ).insert ( std::make_pair ( param, std::unique_ptr < Entry > ( new EntryImpl < ParamType > ( ) ) ) );
+	}
+
+	template < class ParamType >
+	static void registerValuePrinter ( ) {
+		std::string param = std::type_name < ParamType > ( );
+		registerValuePrinter < ParamType > ( std::move ( param ) );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string param ) {
+		auto res = getEntries ( ).find ( param );
+		if ( res == getEntries ( ).end ( ) )
+			throw exception::CommonException ( "Entry " + param + " not available." );
+
+		return res->second->getAbstraction ( );
+	}
+};
+
+} /* namespace abstraction */
+
+#include <abstraction/ValuePrinterAbstraction.hpp>
+
+namespace abstraction {
+
+template < class Param >
+std::shared_ptr < abstraction::OperationAbstraction > ValuePrinterRegistry::EntryImpl < Param >::getAbstraction ( ) const {
+	return std::make_shared < abstraction::ValuePrinterAbstraction < Param > > ( );
+}
+
+} /* namespace abstraction */
+
+#endif /* _VALUE_PRINTER_REGISTRY_HPP_ */
diff --git a/alib2common/src/abstraction/VoidOperationAbstraction.hpp b/alib2common/src/abstraction/VoidOperationAbstraction.hpp
new file mode 100644
index 0000000000..2b479f01a2
--- /dev/null
+++ b/alib2common/src/abstraction/VoidOperationAbstraction.hpp
@@ -0,0 +1,63 @@
+/*
+ * VoidOperationAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _VOID_OPERATION_ABSTRACTION_HPP_
+#define _VOID_OPERATION_ABSTRACTION_HPP_
+
+#include <abstraction/OperationAbstraction.hpp>
+#include <tuple>
+
+namespace abstraction {
+
+class VoidOperationAbstraction : public OperationAbstraction {
+public:
+	template < typename Callable, typename ... Ts, size_t ... Indexes >
+	inline void run_helper ( Callable callback, const std::tuple < Ts ... > & inputs, std::index_sequence < Indexes ... > ) const {
+		callback ( std::get < Indexes > ( inputs )->getData ( ) ... );
+	}
+
+	template < typename Callable, typename T >
+	inline void run_helper ( Callable callback, const T & input ) const {
+		callback ( input->getData ( ) );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getXmlFileWriterFromResult ( const std::string & ) const override {
+		throw exception::CommonException ( "Void algorithm does not have a result." );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getValuePrinterFromResult ( ) const override {
+		throw exception::CommonException ( "Void algorithm does not have a result." );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getCastFromResult ( const std::string & ) const override {
+		throw exception::CommonException ( "Void algorithm does not have a result." );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getNormalizeResult ( ) const override {
+		throw exception::CommonException ( "Void algorithm does not have a result." );
+	}
+
+	virtual std::shared_ptr < OperationAbstraction > getDowncastResult ( ) const override {
+		throw exception::CommonException ( "Void algorithm does not have a result." );
+	}
+
+	virtual std::type_index type ( ) const override {
+		return std::type_index ( typeid ( void ) );
+	}
+
+	virtual std::type_index runtime_type ( ) const override {
+		return std::type_index ( typeid ( void ) );
+	}
+
+	virtual bool cached ( ) const override {
+		return false;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _VOID_OPERATION_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp b/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp
new file mode 100644
index 0000000000..9fb60ef3ec
--- /dev/null
+++ b/alib2common/src/abstraction/XmlFileWriterAbstraction.hpp
@@ -0,0 +1,35 @@
+/*
+ * XmlFileWriterAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _XML_FILE_WRITER_ABSTRACTION_HPP_
+#define _XML_FILE_WRITER_ABSTRACTION_HPP_
+
+#include <abstraction/UnaryOperationAbstraction.hpp>
+#include <tuple>
+
+namespace abstraction {
+
+template < class ParamType >
+class XmlFileWriterAbstraction : public UnaryOperationAbstraction < void, ParamType > {
+	std::string m_filename;
+
+public:
+	XmlFileWriterAbstraction ( std::string filename ) : m_filename ( filename ) {
+	}
+
+	virtual bool run ( ) override {
+		if ( ! this->inputsReady ( ) )
+			return false;
+
+		alib::XmlDataFactory::toFile ( this->m_param->getData ( ), m_filename );
+		return true;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _XML_FILE_WRITER_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/XmlFileWriterRegistry.hpp b/alib2common/src/abstraction/XmlFileWriterRegistry.hpp
new file mode 100644
index 0000000000..26ab05b9a5
--- /dev/null
+++ b/alib2common/src/abstraction/XmlFileWriterRegistry.hpp
@@ -0,0 +1,75 @@
+/*
+ * XmlFileWriterRegistry.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _XML_FILE_WRITER_REGISTRY_HPP_
+#define _XML_FILE_WRITER_REGISTRY_HPP_
+
+#include <memory>
+#include <string>
+
+#include <exception/CommonException.h>
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class XmlFileWriterRegistry {
+	class Entry {
+	public:
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string filename ) const = 0;
+
+	};
+
+	template < class Param >
+	class EntryImpl : public Entry {
+	public:
+		EntryImpl ( ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string filename ) const override;
+	};
+
+	static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) {
+		static std::map < std::string, std::unique_ptr < Entry > > fileWriters;
+		return fileWriters;
+	}
+
+public:
+	template < class ParamType >
+	static void registerXmlFileWriter ( std::string param ) {
+		getEntries ( ).insert ( std::make_pair ( param, std::unique_ptr < Entry > ( new EntryImpl < ParamType > ( ) ) ) );
+	}
+
+	template < class ParamType >
+	static void registerXmlFileWriter ( ) {
+		std::string param = std::type_name < ParamType > ( );
+		registerXmlFileWriter < ParamType > ( std::move ( param ) );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string param, std::string filename ) {
+		auto res = getEntries ( ).find ( param );
+		if ( res == getEntries ( ).end ( ) )
+			throw exception::CommonException ( "Entry " + param + " not available." );
+
+		return res->second->getAbstraction ( std::move ( filename ) );
+	}
+};
+
+} /* namespace abstraction */
+
+#include <abstraction/XmlFileWriterAbstraction.hpp>
+
+namespace abstraction {
+
+template < class Param >
+std::shared_ptr < abstraction::OperationAbstraction > XmlFileWriterRegistry::EntryImpl < Param >::getAbstraction ( std::string filename ) const {
+	return std::make_shared < abstraction::XmlFileWriterAbstraction < Param > > ( std::move ( filename ) );
+}
+
+
+} /* namespace abstraction */
+
+#endif /* _XML_FILE_WRITER_REGISTRY_HPP_ */
diff --git a/alib2common/src/abstraction/XmlParserAbstraction.hpp b/alib2common/src/abstraction/XmlParserAbstraction.hpp
new file mode 100644
index 0000000000..a0191f2e1b
--- /dev/null
+++ b/alib2common/src/abstraction/XmlParserAbstraction.hpp
@@ -0,0 +1,36 @@
+/*
+ * XmlParserAbstraction.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _XML_PARSER_ABSTRACTION_HPP_
+#define _XML_PARSER_ABSTRACTION_HPP_
+
+#include <abstraction/NullaryOperationAbstraction.hpp>
+#include <tuple>
+
+namespace abstraction {
+
+template < class ReturnType >
+class XmlParserAbstraction : public NullaryOperationAbstraction < ReturnType > {
+	std::deque < sax::Token > m_tokens;
+
+public:
+	XmlParserAbstraction ( std::deque < sax::Token > tokens ) : m_tokens ( std::move ( tokens ) ) {
+	}
+
+	virtual bool run ( ) override {
+		if ( this->m_data != nullptr )
+			return true;
+
+		ReturnType res = alib::XmlDataFactory::fromTokens ( std::move ( m_tokens ) );
+		this->m_data = std::unique_ptr < ReturnType > ( static_cast < ReturnType * > ( std::move ( res ).plunder ( ) ) );
+		return true;
+	}
+};
+
+} /* namespace abstraction */
+
+#endif /* _XML_PARSER_ABSTRACTION_HPP_ */
diff --git a/alib2common/src/abstraction/XmlParserRegistry.hpp b/alib2common/src/abstraction/XmlParserRegistry.hpp
new file mode 100644
index 0000000000..d71bda9166
--- /dev/null
+++ b/alib2common/src/abstraction/XmlParserRegistry.hpp
@@ -0,0 +1,70 @@
+/*
+ * XmlParserRegistry.hpp
+ *
+ *  Created on: 11. 7. 2017
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef _XML_PARSER_REGISTRY_HPP_
+#define _XML_PARSER_REGISTRY_HPP_
+
+#include <memory>
+#include <string>
+
+#include <exception/CommonException.h>
+#include <abstraction/OperationAbstraction.hpp>
+
+namespace abstraction {
+
+class XmlParserRegistry {
+	class Entry {
+	public:
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::deque < sax::Token > data ) const = 0;
+
+	};
+
+	template < class Return >
+	class EntryImpl : public Entry {
+	public:
+		EntryImpl ( ) {
+		}
+
+		virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::deque < sax::Token > data ) const override;
+	};
+
+	static std::map < std::string, std::unique_ptr < Entry > > & getEntries ( ) {
+		static std::map < std::string, std::unique_ptr < Entry > > parsers;
+		return parsers;
+	}
+
+public:
+	template < class ReturnType >
+	static void registerXmlParser ( ) {
+		std::string ret = alib::xmlApi < ReturnType >::xmlTagName ( );
+
+		getEntries ( ).insert ( std::make_pair ( ret, std::unique_ptr < Entry > ( new EntryImpl < ReturnType > ( ) ) ) );
+	}
+
+	static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( std::string typeName, std::deque < sax::Token > tokens ) {
+		auto type = getEntries ( ).find ( typeName );
+		if ( type == getEntries ( ).end ( ) )
+			throw exception::CommonException ( "Entry " + typeName + " not available." );
+
+		return type->second->getAbstraction ( std::move ( tokens ) );
+	}
+};
+
+} /* namespace abstraction */
+
+#include <abstraction/XmlParserAbstraction.hpp>
+
+namespace abstraction {
+
+template < class Return >
+std::shared_ptr < abstraction::OperationAbstraction > XmlParserRegistry::EntryImpl < Return >::getAbstraction ( std::deque < sax::Token > data ) const {
+	return std::make_shared < abstraction::XmlParserAbstraction < Return > > ( std::move ( data ) );
+}
+
+} /* namespace abstraction */
+
+#endif /* _XML_PARSER_REGISTRY_HPP_ */
-- 
GitLab