From c2016069d644bad5b59a1f8082746995bc2ddf8a Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 30 Jan 2019 08:10:32 +0100
Subject: [PATCH] full implementation of unregister functionality

---
 .../src/registration/AlgoRegistration.hpp     | 27 +++++++--
 .../src/registration/CastRegistration.hpp     |  8 ++-
 .../registration/ComponentRegistration.hpp    |  4 ++
 .../NormalizationRegistration.hpp             |  8 ++-
 .../src/registration/SetRegistration.hpp      |  4 ++
 .../registration/ValuePrinterRegistration.hpp |  4 ++
 .../src/registry/AlgorithmRegistry.cpp        |  2 +
 alib2cli/src/command/UnloadCommand.h          | 26 +++++++++
 alib2cli/src/common/LibraryLoader.cpp         |  7 ++-
 alib2cli/src/common/LibraryLoader.h           |  2 +
 alib2cli/src/parser/Parser.cpp                |  7 +++
 alib2common/src/PrimitiveRegistrator.cpp      | 55 +++++++++++++++++++
 alib2data/src/PrimitiveRegistrator.cpp        | 25 ++++++---
 alib2raw/src/registration/RawRegistration.hpp | 10 ++++
 .../src/registration/StringRegistration.hpp   | 29 +++++++++-
 alib2xml/src/PrimitiveRegistrator.cpp         | 35 +++++++++---
 alib2xml/src/registration/XmlRegistration.hpp | 14 +++++
 17 files changed, 239 insertions(+), 28 deletions(-)
 create mode 100644 alib2cli/src/command/UnloadCommand.h

diff --git a/alib2abstraction/src/registration/AlgoRegistration.hpp b/alib2abstraction/src/registration/AlgoRegistration.hpp
index f58f6d07e0..7ffc757299 100644
--- a/alib2abstraction/src/registration/AlgoRegistration.hpp
+++ b/alib2abstraction/src/registration/AlgoRegistration.hpp
@@ -21,11 +21,13 @@ protected:
 
 template < class Algorithm, class ReturnType, class ... ParameterTypes >
 class AbstractRegister : public AlgoRegister {
+	abstraction::AlgorithmCategories::AlgorithmCategory m_category;
+
+	registration::NormalizationRegister < ReturnType > normalize;
+
 public:
 	template < class ... ParamNames >
-	AbstractRegister ( ReturnType ( * callback ) ( ParameterTypes ... ), abstraction::AlgorithmCategories::AlgorithmCategory category, ParamNames ... paramNames ) {
-		registration::NormalizationRegister < ReturnType > ( );
-
+	AbstractRegister ( ReturnType ( * callback ) ( ParameterTypes ... ), abstraction::AlgorithmCategories::AlgorithmCategory category, ParamNames ... paramNames ) : m_category ( category ) {
 		std::array < std::string, sizeof ... ( ParameterTypes ) > parameterNames = generateNames < sizeof ... ( ParameterTypes ) > ( paramNames ... );
 
 		abstraction::AlgorithmRegistry::registerAlgorithm < Algorithm, ReturnType, ParameterTypes ... > ( callback, category, std::move ( parameterNames ) );
@@ -34,6 +36,10 @@ public:
 	template < class ... ParamNames >
 	AbstractRegister ( ReturnType ( * callback ) ( ParameterTypes ... ) ) : AbstractRegister ( callback, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT ) {
 	}
+
+	~AbstractRegister ( ) {
+		abstraction::AlgorithmRegistry::unregisterAlgorithm < Algorithm, ParameterTypes ... > ( m_category );
+	}
 };
 
 template < class Algorithm, class ReturnType, class ... ParameterTypes >
@@ -46,20 +52,29 @@ public:
 		abstraction::AlgorithmRegistry::registerWrapper < Algorithm, ReturnType, ParameterTypes ... > ( callback, std::move ( parameterNames ) );
 	}
 
+	~WrapperRegister ( ) {
+		abstraction::AlgorithmRegistry::unregisterWrapper < Algorithm, ParameterTypes ... > ( );
+	}
 };
 
 template < class Algorithm, class ReturnType, class ObjectType, class ... ParameterTypes >
 class MethodRegister : public AlgoRegister {
+	std::string m_methodName;
+
+	registration::NormalizationRegister < ReturnType > normalize;
+
 public:
 	template < class ... ParamNames >
-	MethodRegister ( ReturnType ( ObjectType::* callback ) ( ParameterTypes ... ), std::string methodName, ParamNames ... paramNames ) {
-		registration::NormalizationRegister < ReturnType > ( );
-
+	MethodRegister ( ReturnType ( ObjectType::* callback ) ( ParameterTypes ... ), std::string methodName, ParamNames ... paramNames ) : m_methodName ( methodName ) {
 		std::array < std::string, sizeof ... ( ParameterTypes ) > parameterNames = generateNames < sizeof ... ( ParameterTypes ) > ( paramNames ... );
 
 		abstraction::AlgorithmRegistry::registerMethod < Algorithm > ( callback, methodName, std::move ( parameterNames ) );
 	}
 
+	~MethodRegister ( ) {
+		abstraction::AlgorithmRegistry::unregisterMethod < Algorithm, ObjectType, ParameterTypes ... > ( m_methodName );
+	}
+
 };
 
 } /* namespace registration */
diff --git a/alib2abstraction/src/registration/CastRegistration.hpp b/alib2abstraction/src/registration/CastRegistration.hpp
index e65a651a98..abf8fa8eb6 100644
--- a/alib2abstraction/src/registration/CastRegistration.hpp
+++ b/alib2abstraction/src/registration/CastRegistration.hpp
@@ -9,16 +9,20 @@ namespace registration {
 
 template < class To, class From >
 class CastRegister {
+	registration::NormalizationRegister < To > normalize;
+
 public:
 	CastRegister ( ) {
-		registration::NormalizationRegister < To > ( );
 		abstraction::CastRegistry::registerCast < To, From > ( );
 	}
 
 	CastRegister ( To ( * castFunction ) ( const From & ) ) {
-		registration::NormalizationRegister < To > ( );
 		abstraction::CastRegistry::registerCastAlgorithm < To, From > ( castFunction );
 	}
+
+	~CastRegister ( ) {
+		abstraction::CastRegistry::unregisterCast < To, From > ( );
+	}
 };
 
 } /* namespace registration */
diff --git a/alib2abstraction/src/registration/ComponentRegistration.hpp b/alib2abstraction/src/registration/ComponentRegistration.hpp
index 0482c7f716..68d555c232 100644
--- a/alib2abstraction/src/registration/ComponentRegistration.hpp
+++ b/alib2abstraction/src/registration/ComponentRegistration.hpp
@@ -10,6 +10,10 @@ public:
 		ObjectType::registerComponent ( );
 	}
 
+	~ComponentRegister ( ) {
+		ObjectType::unregisterComponent ( );
+	}
+
 };
 
 } /* namespace registration */
diff --git a/alib2abstraction/src/registration/NormalizationRegistration.hpp b/alib2abstraction/src/registration/NormalizationRegistration.hpp
index 78a4144222..b4806357f5 100644
--- a/alib2abstraction/src/registration/NormalizationRegistration.hpp
+++ b/alib2abstraction/src/registration/NormalizationRegistration.hpp
@@ -18,9 +18,15 @@ public:
 
 template < class ReturnType >
 class NormalizationRegister < ReturnType, typename std::enable_if < ! std::is_same < ReturnType, core::normalizationResult < ReturnType > >::value >::type > {
+	std::list < std::unique_ptr < abstraction::NormalizeRegistry::Entry > >::const_iterator iter;
+
 public:
 	NormalizationRegister ( ) {
-		abstraction::NormalizeRegistry::registerNormalize < ReturnType > ( );
+		iter = abstraction::NormalizeRegistry::registerNormalize < ReturnType > ( );
+	}
+
+	~NormalizationRegister ( ) {
+		abstraction::NormalizeRegistry::unregisterNormalize < ReturnType > ( iter );
 	}
 
 	bool requireNormalization ( ) const {
diff --git a/alib2abstraction/src/registration/SetRegistration.hpp b/alib2abstraction/src/registration/SetRegistration.hpp
index 67a83b0d31..ce0c120ba6 100644
--- a/alib2abstraction/src/registration/SetRegistration.hpp
+++ b/alib2abstraction/src/registration/SetRegistration.hpp
@@ -13,6 +13,10 @@ public:
 	SetRegister ( ) {
 		abstraction::ContainerRegistry::registerSet < Param > ( );
 	}
+
+	~SetRegister ( ) {
+		abstraction::ContainerRegistry::unregisterSet < Param > ( );
+	}
 };
 
 } /* namespace registration */
diff --git a/alib2abstraction/src/registration/ValuePrinterRegistration.hpp b/alib2abstraction/src/registration/ValuePrinterRegistration.hpp
index 676f44f0d7..799987f8d8 100644
--- a/alib2abstraction/src/registration/ValuePrinterRegistration.hpp
+++ b/alib2abstraction/src/registration/ValuePrinterRegistration.hpp
@@ -11,6 +11,10 @@ public:
 	ValuePrinterRegister ( ) {
 		abstraction::ValuePrinterRegistry::registerValuePrinter < Type > ( );
 	}
+
+	~ValuePrinterRegister ( ) {
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < Type > ( );
+	}
 };
 
 } /* namespace registration */
diff --git a/alib2abstraction/src/registry/AlgorithmRegistry.cpp b/alib2abstraction/src/registry/AlgorithmRegistry.cpp
index 364236583e..a951d6ad2a 100644
--- a/alib2abstraction/src/registry/AlgorithmRegistry.cpp
+++ b/alib2abstraction/src/registry/AlgorithmRegistry.cpp
@@ -60,6 +60,8 @@ void AlgorithmRegistry::unregisterInternal ( std::string algorithm, ext::vector
 			throw std::invalid_argument ( "Templated entry " + algorithm + " < " + ext::to_string ( templateParams ) + " > with parameters " + ext::to_string ( params ) + " not registered." );
 	}
 	group.erase ( iter );
+	if ( group.size ( ) == 0 )
+		getEntries ( ).erase ( ext::make_pair ( algorithm, templateParams ) );
 }
 
 ext::map < ext::pair < std::string, ext::vector < std::string > >, ext::list < ext::tuple < AlgorithmCategories::AlgorithmCategory, ext::vector < ext::tuple < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier >, std::string > >, ext::pair < ext::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > >, std::shared_ptr < AlgorithmRegistry::Entry > > > > >::const_iterator AlgorithmRegistry::findAbstractionGroup ( const std::string & name, const ext::vector < std::string > & templateParams ) {
diff --git a/alib2cli/src/command/UnloadCommand.h b/alib2cli/src/command/UnloadCommand.h
new file mode 100644
index 0000000000..a33107a736
--- /dev/null
+++ b/alib2cli/src/command/UnloadCommand.h
@@ -0,0 +1,26 @@
+#ifndef _CLI_UNLOAD_COMMAND_H_
+#define _CLI_UNLOAD_COMMAND_H_
+
+#include <command/Command.h>
+#include <environment/Environment.h>
+
+#include <common/LibraryLoader.h>
+
+namespace cli {
+
+class UnloadCommand : public Command {
+	std::string m_libraryName;
+
+public:
+	UnloadCommand ( std::string libraryName ) : m_libraryName ( std::move ( libraryName ) ) {
+	}
+
+	virtual Command::Result run ( Environment & ) const override {
+		cli::LibraryLoader::unload ( m_libraryName );
+		return Command::Result::OK;
+	}
+};
+
+} /* namespace cli */
+
+#endif /* _CLI_UNLOAD_COMMAND_H_ */
diff --git a/alib2cli/src/common/LibraryLoader.cpp b/alib2cli/src/common/LibraryLoader.cpp
index 0b0ba38f81..be7bf83a92 100644
--- a/alib2cli/src/common/LibraryLoader.cpp
+++ b/alib2cli/src/common/LibraryLoader.cpp
@@ -17,7 +17,12 @@ void LibraryLoader::load ( const std::string & name ) {
 	std::list < LibraryLoader::Library >::iterator iter = find ( name );
 	if ( iter == libraries.end ( ) )
 		iter = libraries.emplace ( libraries.end ( ), std::move ( name ) );
-	iter->load ( );
+}
+
+void LibraryLoader::unload ( const std::string & name ) {
+	std::list < LibraryLoader::Library >::iterator iter = find ( name );
+	if ( iter != libraries.end ( ) )
+		libraries.erase ( iter );
 }
 
 } /* namespace cli */
diff --git a/alib2cli/src/common/LibraryLoader.h b/alib2cli/src/common/LibraryLoader.h
index fbcfded963..1a4c1ff827 100644
--- a/alib2cli/src/common/LibraryLoader.h
+++ b/alib2cli/src/common/LibraryLoader.h
@@ -20,6 +20,7 @@ class LibraryLoader {
 
 	public:
 		Library ( const std::string & path ) : m_path ( path ), m_handle ( NULL ) {
+			load ( );
 		}
 
 		Library ( const Library & ) = delete;
@@ -65,6 +66,7 @@ class LibraryLoader {
 
 public:
 	static void load ( const std::string & name );
+	static void unload ( const std::string & name );
 };
 
 } /* namespace cli */
diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp
index 3d83c5c5fa..58f2426749 100644
--- a/alib2cli/src/parser/Parser.cpp
+++ b/alib2cli/src/parser/Parser.cpp
@@ -24,6 +24,7 @@
 #include <command/CastsIntrospectionCommand.h>
 #include <command/SetCommand.h>
 #include <command/LoadCommand.h>
+#include <command/UnloadCommand.h>
 
 namespace cli {
 
@@ -364,6 +365,12 @@ std::unique_ptr < Command > Parser::parse ( ) {
 		match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING );
 		match ( cli::Lexer::TokenType::EOS );
 		return std::make_unique < LoadCommand > ( std::move ( libraryName ) );
+	} else if ( check_nonreserved_kw ( "unload" ) ) {
+		match_nonreserved_kw ( "unload" );
+		std::string libraryName = getTokenValue ( );
+		match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING );
+		match ( cli::Lexer::TokenType::EOS );
+		return std::make_unique < UnloadCommand > ( std::move ( libraryName ) );
 	} else if ( check ( cli::Lexer::TokenType::EOT ) ) {
 		return std::make_unique < QuitCommand > ( nullptr );
 	} else {
diff --git a/alib2common/src/PrimitiveRegistrator.cpp b/alib2common/src/PrimitiveRegistrator.cpp
index 3b416e9bbf..43bba9d747 100644
--- a/alib2common/src/PrimitiveRegistrator.cpp
+++ b/alib2common/src/PrimitiveRegistrator.cpp
@@ -72,6 +72,61 @@ public:
 		abstraction::ValuePrinterRegistry::registerValuePrinter < ext::map < ext::pair < object::Object, object::Object >, ext::map < ext::pair < object::Object, object::Object >, long > > > ( );
 		abstraction::ContainerRegistry::registerSet < object::Object > ( );
 	}
+
+	~PrimitiveRegistrator ( ) {
+		abstraction::CastRegistry::unregisterCast < double, int > ( );
+		abstraction::CastRegistry::unregisterCast < int, double > ( );
+
+		abstraction::CastRegistry::unregisterCast < std::string, int > ( );
+		abstraction::CastRegistry::unregisterCast < int, std::string > ( );
+
+		abstraction::CastRegistry::unregisterCast < bool, int > ( );
+		abstraction::CastRegistry::unregisterCast < bool, std::string > ( );
+		abstraction::CastRegistry::unregisterCast ( "unsigned", ext::to_string < std::string > ( ) );
+		abstraction::CastRegistry::unregisterCast < double, std::string > ( );
+
+		abstraction::CastRegistry::unregisterCast ( "size_t", ext::to_string < int > ( ) );
+		abstraction::CastRegistry::unregisterCast < size_t, int > ( );
+		abstraction::CastRegistry::unregisterCast < int, size_t > ( );
+		abstraction::CastRegistry::unregisterCast < unsigned, int > ( );
+
+		abstraction::CastRegistry::unregisterCast ( "long", ext::to_string < int > ( ) );
+
+		abstraction::ContainerRegistry::unregisterSet < int > ( );
+
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < int > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < unsigned > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < double > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < std::string > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < void > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < bool > ( );
+
+		abstraction::ImmediateRegistry::unregisterImmediate < int > ( );
+		abstraction::ImmediateRegistry::unregisterImmediate < std::string > ( );
+
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < object::Object > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::set < object::Object > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::trie < object::Object, bool > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::set < unsigned > > ( );
+
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::vector < object::Object > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::vector < unsigned > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::vector < ext::pair < object::Object, object::Object > > > ( );
+
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::pair < ext::vector < object::Object >, double > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::pair < ext::vector < object::Object >, int > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::pair < ext::vector < object::Object >, long > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::pair < ext::vector < ext::pair < object::Object, object::Object > >, double > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::pair < ext::vector < ext::pair < object::Object, object::Object > >, int > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::pair < ext::vector < ext::pair < object::Object, object::Object > >, long > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::map < object::Object, ext::map < object::Object, double > > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::map < object::Object, ext::map < object::Object, int > > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::map < object::Object, ext::map < object::Object, long > > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::map < ext::pair < object::Object, object::Object >, ext::map < ext::pair < object::Object, object::Object >, double > > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::map < ext::pair < object::Object, object::Object >, ext::map < ext::pair < object::Object, object::Object >, int > > > ( );
+		abstraction::ValuePrinterRegistry::unregisterValuePrinter < ext::map < ext::pair < object::Object, object::Object >, ext::map < ext::pair < object::Object, object::Object >, long > > > ( );
+		abstraction::ContainerRegistry::unregisterSet < object::Object > ( );
+	}
 };
 
 auto primitiveRegistrator = PrimitiveRegistrator ( );
diff --git a/alib2data/src/PrimitiveRegistrator.cpp b/alib2data/src/PrimitiveRegistrator.cpp
index a72f94cb60..06ea49f938 100644
--- a/alib2data/src/PrimitiveRegistrator.cpp
+++ b/alib2data/src/PrimitiveRegistrator.cpp
@@ -28,24 +28,35 @@
 namespace {
 
 class PrimitiveRegistrator {
+	registration::XmlWriterRegister < ext::set < common::ranked_symbol < object::Object, unsigned > > > member1;
+	registration::XmlWriterRegister < ext::vector < ext::map < std::pair < object::Object, object::Object >, ext::map < object::Object, object::Object > > > > member2;
+	registration::XmlWriterRegister < ext::vector < ext::vector < ext::set < object::Object > > > > member3;
+	registration::XmlWriterRegister < ext::map < common::ranked_symbol < object::Object, unsigned >, size_t > > member4;
+	registration::XmlWriterRegister < ext::set < string::LinearString < > > > member5;
+	registration::XmlWriterRegister < ext::trie < DefaultSymbolType, bool > > member6;
+
 public:
 	PrimitiveRegistrator ( ) {
 		abstraction::ContainerRegistry::registerSet < common::ranked_symbol < object::Object, unsigned > > ( "RankedSymbol" );
 		abstraction::XmlContainerParserRegistry::registerSet < common::ranked_symbol < object::Object, unsigned > > ( "RankedSymbol" );
 
-		registration::XmlWriterRegister < ext::set < common::ranked_symbol < object::Object, unsigned > > > ( );
-		registration::XmlWriterRegister < ext::vector < ext::map < std::pair < object::Object, object::Object >, ext::map < object::Object, object::Object > > > > ( );
-		registration::XmlWriterRegister < ext::vector < ext::vector < ext::set < object::Object > > > > ( );
-		registration::XmlWriterRegister < ext::map < common::ranked_symbol < object::Object, unsigned >, size_t > > ( );
-		registration::XmlWriterRegister < ext::set < string::LinearString < > > > ( );
-		registration::XmlWriterRegister < ext::trie < DefaultSymbolType, bool > > ( );
-
 		abstraction::XmlParserRegistry::registerXmlParser < object::Object > ( "DefaultStateType" );
 
 		core::xmlApi < object::Object >::template registerXmlWriter < ext::set < common::ranked_symbol < object::Object, unsigned > > > ( );
 		core::xmlApi < object::Object >::template registerXmlWriter < ext::pair < ext::set < ext::pair < object::Object, object::Object > >, ext::variant < string::Epsilon < object::Object >, object::Object > > > ( );
 		core::xmlApi < object::Object >::template registerXmlWriter < ext::pair < object::Object, ext::variant < string::Epsilon < object::Object >, object::Object > > > ( );
 	}
+
+	~PrimitiveRegistrator ( ) {
+		abstraction::ContainerRegistry::unregisterSet ( "RankedSymbol" );
+		abstraction::XmlContainerParserRegistry::unregisterSet ( "RankedSymbol" );
+
+		abstraction::XmlParserRegistry::unregisterXmlParser ( "DefaultStateType" );
+
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::set < common::ranked_symbol < object::Object, unsigned > > > ( );
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::pair < ext::set < ext::pair < object::Object, object::Object > >, ext::variant < string::Epsilon < object::Object >, object::Object > > > ( );
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::pair < object::Object, ext::variant < string::Epsilon < object::Object >, object::Object > > > ( );
+	}
 };
 
 auto primitiveRegistrator = PrimitiveRegistrator ( );
diff --git a/alib2raw/src/registration/RawRegistration.hpp b/alib2raw/src/registration/RawRegistration.hpp
index f72486a3bd..4cdb01f648 100644
--- a/alib2raw/src/registration/RawRegistration.hpp
+++ b/alib2raw/src/registration/RawRegistration.hpp
@@ -39,6 +39,11 @@ public:
 		abstraction::RawReaderRegistry::registerRawReader < Type > ( );
 		abstraction::AlgorithmRegistry::registerWrapper < raw::Parse < Type >, Type, const std::string & > ( raw::Parse < Type >::abstractionFromString, std::array < std::string, 1 > { { "arg0" } } );
 	}
+
+	~RawReaderRegister ( ) {
+		abstraction::RawReaderRegistry::unregisterRawReader < Type > ( );
+		abstraction::AlgorithmRegistry::unregisterWrapper < raw::Parse < Type >, const std::string & > ( );
+	}
 };
 
 template < class Type >
@@ -48,6 +53,11 @@ public:
 		abstraction::RawWriterRegistry::registerRawWriter < Type > ( );
 		abstraction::AlgorithmRegistry::registerWrapper < raw::Compose, std::string, const Type & > ( raw::Compose::abstractionFromType, std::array < std::string, 1 > { { "arg0" } } );
 	}
+
+	~RawWriterRegister ( ) {
+		abstraction::RawWriterRegistry::unregisterRawWriter < Type > ( );
+		abstraction::AlgorithmRegistry::unregisterWrapper < raw::Compose, const Type & > ( );
+	}
 };
 
 } /* namespace registration */
diff --git a/alib2str/src/registration/StringRegistration.hpp b/alib2str/src/registration/StringRegistration.hpp
index 38c645fb8f..b09428bbf2 100644
--- a/alib2str/src/registration/StringRegistration.hpp
+++ b/alib2str/src/registration/StringRegistration.hpp
@@ -34,9 +34,15 @@ namespace registration {
 
 template < class Group, class Type >
 class StringReaderRegister {
+	ext::list < std::pair < std::function < bool ( std::istream & ) >, std::unique_ptr < abstraction::StringReaderRegistry::Entry > > >::const_iterator iter;
+
 public:
 	StringReaderRegister ( ) {
-		abstraction::StringReaderRegistry::registerStringReader < Group, Type > ( );
+		iter = abstraction::StringReaderRegistry::registerStringReader < Group, Type > ( );
+	}
+
+	~StringReaderRegister ( ) {
+		abstraction::StringReaderRegistry::unregisterStringReader < Group > ( iter );
 	}
 };
 
@@ -46,6 +52,10 @@ public:
 	StringReaderGroupRegister ( ) {
 		abstraction::AlgorithmRegistry::registerWrapper < string::Parse < Group >, abstraction::UnspecifiedType, std::string && > ( string::Parse < Group >::abstractionFromString, std::array < std::string, 1 > { { "arg0" } } );
 	}
+
+	~StringReaderGroupRegister ( ) {
+		abstraction::AlgorithmRegistry::unregisterWrapper < string::Parse < Group >, std::string && > ( );
+	}
 };
 
 template < class Type >
@@ -55,13 +65,24 @@ public:
 		abstraction::StringWriterRegistry::registerStringWriter < Type > ( );
 		abstraction::AlgorithmRegistry::registerWrapper < string::Compose, std::string, const Type & > ( string::Compose::abstractionFromType, std::array < std::string, 1 > { { "arg0" } } );
 	}
+
+	~StringWriterRegister ( ) {
+		abstraction::StringWriterRegistry::unregisterStringWriter < Type > ( );
+		abstraction::AlgorithmRegistry::unregisterWrapper < string::Compose, const Type & > ( );
+	}
 };
 
 template < class Group, class Type >
 class StringReaderRegisterTypeInGroup {
+	typename ext::list < std::pair < std::function < bool ( std::istream & ) >, std::unique_ptr < typename core::stringApi < Group >::GroupReader > > >::const_iterator iter;
+
 public:
 	StringReaderRegisterTypeInGroup ( ) {
-		core::stringApi < Group >::template registerStringReader < Type > ( );
+		iter = core::stringApi < Group >::template registerStringReader < Type > ( );
+	}
+
+	~StringReaderRegisterTypeInGroup ( ) {
+		core::stringApi < Group >::template unregisterStringReader < Type > ( iter );
 	}
 };
 
@@ -71,6 +92,10 @@ public:
 	StringWriterRegisterTypeInGroup ( ) {
 		core::stringApi < Group >::template registerStringWriter < Type > ( );
 	}
+
+	~StringWriterRegisterTypeInGroup ( ) {
+		core::stringApi < Group >::template unregisterStringWriter < Type > ( );
+	}
 };
 
 } /* namespace registration */
diff --git a/alib2xml/src/PrimitiveRegistrator.cpp b/alib2xml/src/PrimitiveRegistrator.cpp
index cecb0dcae2..6e2d795e52 100644
--- a/alib2xml/src/PrimitiveRegistrator.cpp
+++ b/alib2xml/src/PrimitiveRegistrator.cpp
@@ -26,21 +26,21 @@
 namespace {
 
 class PrimitiveRegistrator {
+	registration::XmlWriterRegister < ext::vector < size_t > > member1;
+	registration::XmlWriterRegister < ext::vector < unsigned > > member2;
+	registration::XmlWriterRegister < ext::vector < int > > member3;
+	registration::XmlWriterRegister < ext::set < size_t > > member4;
+	registration::XmlWriterRegister < ext::set < unsigned > > member5;
+	registration::XmlWriterRegister < ext::set < int > > member6;
+	registration::XmlWriterRegister < ext::map < object::Object, size_t > > member7;
+	registration::XmlWriterRegister < object::Object > member8;
+
 public:
 	PrimitiveRegistrator ( ) {
 		abstraction::XmlContainerParserRegistry::registerSet < int > ( );
 		abstraction::XmlParserRegistry::registerXmlParser < int > ( "int" );
 		abstraction::XmlParserRegistry::registerXmlParser < ext::set < ext::pair < object::Object, object::Object > > > ( "pair_set" );
 
-		registration::XmlWriterRegister < ext::vector < size_t > > ( );
-		registration::XmlWriterRegister < ext::vector < unsigned > > ( );
-		registration::XmlWriterRegister < ext::vector < int > > ( );
-		registration::XmlWriterRegister < ext::set < size_t > > ( );
-		registration::XmlWriterRegister < ext::set < unsigned > > ( );
-		registration::XmlWriterRegister < ext::set < int > > ( );
-		registration::XmlWriterRegister < ext::map < object::Object, size_t > > ( );
-		registration::XmlWriterRegister < object::Object > ( );
-
 		abstraction::ContainerRegistry::registerSet < object::Object > ( "Object" );
 		abstraction::XmlContainerParserRegistry::registerSet < object::Object > ( "Object" );
 		abstraction::XmlParserRegistry::registerXmlParser < object::Object > ( "Object" );
@@ -52,6 +52,23 @@ public:
 		core::xmlApi < object::Object >::template registerXmlWriter < ext::pair < object::Object, unsigned int > > ( );
 		core::xmlApi < object::Object >::template registerXmlWriter < ext::set < char > > ( );
 	}
+
+	~PrimitiveRegistrator ( ) {
+		abstraction::XmlContainerParserRegistry::unregisterSet < int > ( );
+		abstraction::XmlParserRegistry::unregisterXmlParser ( "int" );
+		abstraction::XmlParserRegistry::unregisterXmlParser ( "pair_set" );
+
+		abstraction::ContainerRegistry::unregisterSet ( "Object" );
+		abstraction::XmlContainerParserRegistry::unregisterSet ( "Object" );
+		abstraction::XmlParserRegistry::unregisterXmlParser ( "Object" );
+
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::set < ext::pair < object::Object, object::Object > > > ( );
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::pair < ext::set < ext::pair < object::Object, object::Object > >, object::Object > > ( );
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::vector < ext::variant < object::Object, object::Object > > > ( );
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::pair < unsigned int, unsigned int > > ( );
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::pair < object::Object, unsigned int > > ( );
+		core::xmlApi < object::Object >::template unregisterXmlWriter < ext::set < char > > ( );
+	}
 };
 
 auto primitiveRegistrator = PrimitiveRegistrator ( );
diff --git a/alib2xml/src/registration/XmlRegistration.hpp b/alib2xml/src/registration/XmlRegistration.hpp
index 8fc8b9836a..9e159c9109 100644
--- a/alib2xml/src/registration/XmlRegistration.hpp
+++ b/alib2xml/src/registration/XmlRegistration.hpp
@@ -38,6 +38,10 @@ public:
 	XmlReaderRegister ( ) {
 		abstraction::XmlParserRegistry::registerXmlParser < Type > ( );
 	}
+
+	~XmlReaderRegister ( ) {
+		abstraction::XmlParserRegistry::unregisterXmlParser < Type > ( );
+	}
 };
 
 template < class Type >
@@ -47,6 +51,11 @@ public:
 		abstraction::XmlComposerRegistry::registerXmlComposer < Type > ( );
 		abstraction::AlgorithmRegistry::registerWrapper < xml::Compose, ext::deque < sax::Token >, const Type & > ( xml::Compose::abstractionFromType, std::array < std::string, 1 > { { "arg0" } } );
 	}
+
+	~XmlWriterRegister ( ) {
+		abstraction::XmlComposerRegistry::unregisterXmlComposer < Type > ( );
+		abstraction::AlgorithmRegistry::unregisterWrapper < xml::Compose, const Type & > ( );
+	}
 };
 
 template < class Group, class Type >
@@ -56,6 +65,11 @@ public:
 		core::xmlApi < Group >::template registerXmlReader < Type > ( );
 		core::xmlApi < Group >::template registerXmlWriter < Type > ( );
 	}
+
+	~XmlRegisterTypeInGroup ( ) {
+		core::xmlApi < Group >::template unregisterXmlReader < Type > ( );
+		core::xmlApi < Group >::template unregisterXmlWriter < Type > ( );
+	}
 };
 
 } /* namespace registration */
-- 
GitLab