Index: /bdm/user_info.h
===================================================================
--- /bdm/user_info.h (revision 345)
+++ /bdm/user_info.h (revision 351)
@@ -2,7 +2,4 @@
 #define UIBUILD
 
-#include <itpp/itbase.h>
-#include "stat/libBM.h"
-#include "libconfig/libconfig.h++"
 
 #include <sstream>
@@ -16,4 +13,10 @@
 #include <iostream>
 
+#include "libconfig/libconfig.h++"
+
+#include <itpp/itbase.h>
+
+#include "stat/libBM.h"
+
 using std::string;
 using namespace std;
@@ -26,4 +29,21 @@
 namespace bdm
 {
+class UI_File : public Config
+{
+private:
+	const string file_name;
+
+public:
+	//! attach new RootElement instance to a file (typically with an XML extension)
+	UI_File( const string &file_name );
+
+	//! loads root element from a file
+	void load();
+
+	//! save UserInfo to the file (typically with an XML extension)
+	void save();
+
+	operator Setting&();
+};
 
 /*!
@@ -49,22 +69,4 @@
 */
 
-class UI_File : public Config
-{
-private:
-	const string file_name;
-
-public:
-	//! attach new RootElement instance to a file (typically with an XML extension)
-	UI_File( const string &file_name );
-
-	//! loads root element from a file
-	void load();
-
-	//! save UserInfo to the file (typically with an XML extension)
-	void save();
-
-	operator Setting&();
-};
-
 
 /*!
@@ -89,50 +91,72 @@
 	//! The key property of this class is that it initilaized the internal map immediately
 	//! when it is used for a first time.
-	class Class_To_UI
+	class Mapped_UI
 	{
 	private:
 		//! Type definition of mapping which transforms type names to the related user infors
-		typedef map< const string, UI* > Class_To_UI_Map;
-
-		//! immediately initialized instance of type Class_To_UI_Map
-		static Class_To_UI_Map& private_map();
+		typedef map< const string, const UI* const > String_To_UI_Map;
+
+		//! Type definition of mapping which transforms type names to the related user infors
+		typedef map< const type_info * const, const string > Type_Info_To_String_Map;
+
+		//! immediately initialized instance of type String_To_UI_Map
+		static String_To_UI_Map& mapped_strings();
+
+		//! immediately initialized instance of type String_To_UI_Map
+		static Type_Info_To_String_Map& mapped_type_infos();
 
 	public:
 		//! add a pair key-userinfo into the internal map
-		static void add_class( const string &class_name, UI* ui );
+		static void add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui );
 
 		//! search for an userinfo related to the passed key within the internal map
-		static UI* retrieve_ui( const string &class_name );
+		static const UI& retrieve_ui( const string &class_name );
+
+		//! search for an userinfo related to the passed key within the internal map
+		static const string& retrieve_class_name( const type_info* const class_type_info );
 	};
-				
+
+	// vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem..
+	// do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny
+	class Link_Expander	
+	{
+	private:
+		UI_File *file;
+		const Setting *result;
+
+	public:
+
+		Link_Expander( const Setting &potential_link );
+		
+		~Link_Expander();
+		
+		const Setting& root() const;
+	};
+
+
 	//! internal method assembling a typeless instance from components obtained by the 'AssemblyComponentsFromSetting()' method
-	virtual bdmroot* new_instance() = 0;
+	virtual bdmroot* new_instance() const = 0;
 	
-	//! type name defined by user
-	const string class_name;
-
    	//! This methods tries to save an instance of type T (or some of its descendant types)
 	//! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name
 	//! and connecti it to the passed Setting as a new child node.
-	template<class T> static void to_setting( const T &instance, Setting &root )
-	{
-		const string &class_name = Particular_UI<T>::ui.class_name;
-			
-		// add attribute "class" 
-		Setting &type = root.add( "class", Setting::TypeString );
-		type = class_name;
-	
-		try
-		{
-			// instance disassembling 
-			instance.to_setting( root );
-		}
-		catch(SettingException xcptn)
-		{
-			it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." );
-		}	
-	}
-
-	template<class T> static T* from_setting( const Setting &element )
+	static const Setting* pointer_to_child_setting( const Setting &element, const int index );
+
+	static const Setting* pointer_to_child_setting( const Setting &element, const string &name );
+
+	static const Setting& reference_to_child_setting( const Setting &element, const int index );
+
+	static const Setting& reference_to_child_setting( const Setting &element, const string &name );
+
+
+	//! This methods tries to build a new double matrix 
+	static void from_setting( mat& matrix, const Setting &element );	
+	//! This methods tries to build a new integer vector
+	static void from_setting( ivec &vec, const Setting &element );
+	// jednak kvuli pretypovani, apak taky proto, ze na string nefunguje link_expander..
+	static void from_setting( string &str, const Setting &element );
+	//! This methods tries to build a new templated array 
+
+	template<class T> static void from_setting( T* &instance, const Setting &element )
 	{			
 		const Link_Expander link_expander( element );
@@ -147,14 +171,12 @@
 	
 		// and finally we find a UserInfo related to this type
-		UI* related_UI = Class_To_UI::retrieve_ui( class_name );
-		if( !related_UI)
-			it_error ( "UI error: class " + class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." );
-		
-		bdmroot* typeless_instance = related_UI->new_instance();
-
-		T* ui = NULL;
+		const UI& related_UI = Mapped_UI::retrieve_ui( class_name );
+		
+		bdmroot* typeless_instance = related_UI.new_instance();
+
+		instance = NULL;
 		try
 		{
-			ui = (T*) typeless_instance ;
+			instance = (T*) typeless_instance ;
 		}
 		catch(...)
@@ -165,6 +187,5 @@
 		try
 		{
-			// instance assembling 
-			ui->from_setting( root );
+			instance->from_setting( root );
 		}
 		catch(SettingException xcptn)
@@ -172,290 +193,29 @@
 			it_error ( "UI error: the method " + class_name + ".from_setting(Setting&) has thrown an exception when parsing the setting " + xcptn.getPath() + ". Try to correct this method." );
 		}
-		return ui;
 	}	
 
 
-	// vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem..
-	// do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny
-	class Link_Expander	
-	{
-	private:
-		UI_File *file;
-		const Setting *result;
-
-	public:
-
-		Link_Expander( const Setting &potential_link )
-		{
-			file = NULL;
-			result = &potential_link;
-
-			if( potential_link.getType() !=  Setting::TypeString )
-				return;
-
-			string link = (string) potential_link;
-			size_t aerobase = link.find('@');
-			if( aerobase != string::npos )
-			{
-				string file_name = link.substr( aerobase + 1, link.length() );
-				file = new UI_File( file_name );
-				file->load();
-				result = &(Setting&)(*file);
-				link = link.substr( 0, aerobase );
-			}
-			else
-				while ( !result->isRoot() ) 
-					result = &result->getParent();
-
-			if( !result->exists( link ) )
-				ui_error( "linked Setting was not found", potential_link );
-
-			result = &(*result)[link];
-		}
-
-		~Link_Expander()
-		{
-			if( file ) delete file;
-		}
-		
-		const Setting& root() const
-		{
-			return *result;
-		}
-	};
-
-		static const Setting* to_child_setting( const Setting &element, const int index )
-		{
-			if( !element.isAggregate())
-				return NULL;
-
-			if( element.getLength() <= index )
-				return NULL;
-
-			return &element[index];
-		}
-
-		static const Setting* to_child_setting( const Setting &element, const string &name )
-		{
-			if( !element.isGroup() )
-				return NULL;
-
-			if( !element.exists( name ) )
-				return NULL;
-
-			return &element[name];
-		}
-
-		static Setting& to_child_setting( Setting &element, const int index )
-		{
-			if( !element.isAggregate())
-				ui_error( "it is not possible to index non-agregate element by integers", element );
-
-			if( element.getLength() <= index )
-				ui_error( "there is not any child with index " + index, element );
-
-			return element[index];
-		}
-
-		static Setting& to_child_setting( Setting &element, const string &name )
-		{
-			ASSERT_UITYPE(element,TypeGroup);
-			if( !element.exists( name ) )
-				ui_error( "there is not any child named """ + name, element );
-			return element[name];
-		}
-
-	//! This methods tries to build a new double matrix 
-	static void from_setting( mat& matrix, const Setting &element )
+	//! This methods tries to build a new templated array , 
+	// efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme
+	template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element )
 	{
 		const Link_Expander link_expander( element );
 		const Setting &root = link_expander.root();
 
-		if( root.isNumber() )
-		{
-			matrix.set_size( 1, 1 );
-			matrix(0,0) = root;
-			return;
-		}
-
-		if( root.isList() )
-		{
-			if( root.getLength() != 3 )
-				ui_error( "the setting supposed to represent a matrix element has wrong syntax", root );
-
-			Setting &cols_setting = root[0];
-			Setting &rows_setting = root[1];
-			Setting &elements = root[2];
-
-			ASSERT_UITYPE(cols_setting,TypeInt);
-			ASSERT_UITYPE(rows_setting,TypeInt);
-			ASSERT_UITYPE(elements,TypeArray);
-
-			int cols = cols_setting;
-			int rows = rows_setting;
-						
-			if( cols < 0 | rows < 0 )
-				ui_error( "the dimensions of a matrix has to be non-negative", root );
-
-			if( elements.getLength() != cols * rows )
-				ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements );
-
-			matrix.set_size( rows, cols );
-
-			if( cols == 0 || rows == 0 )
-				return;
-
-			if( !elements[0].isNumber() )
-				ui_error( "matrix elements have to be numbers", elements[0] );
-
-			// build matrix row-wise
-			int k = 0;
-			for( int i=0;i<rows;i++ ) 
-				for( int j=0; j<cols; j++)
-					matrix(i,j) = elements[k++];
-			return;
-		}
-
-		ui_error( "only numeric types or TypeList are supported as matrix values", root );
-	}
-
-	//! This methods tries to save a double matrix 
-	static void to_setting( const mat &matrix, Setting &root )
-	{
-		Setting &cols = root.add( Setting::TypeInt );
-		cols = matrix.cols();
-
-		Setting &rows = root.add( Setting::TypeInt );
-		rows = matrix.rows();
-
-		Setting &elements = root.add( Setting::TypeArray );
-
-		// build matrix row-wise
-		for( int i=0; i<matrix.rows(); i++ ) 
-			for( int j=0; j<matrix.cols(); j++)
-			{
-				Setting &newField = elements.add(Setting::TypeFloat);
-				newField = matrix(i,j);
-			}
-	}
-
-	//! This methods tries to build a new integer vector
-	static void from_setting( ivec &vec, const Setting &element )
-	{
-		const Link_Expander link_expander( element );
-		const Setting &root = link_expander.root();
-
-		if( root.isNumber() )
-		{
-			ASSERT_UITYPE(root,TypeInt);
-			vec.set_length( 1 );
-			vec(0) = root;
-			return;
-		}
-
-		if( root.isList() )
-		{
-			if( root.getLength() != 3 )
-				ui_error( "the setting supposed to represent a matrix element has wrong syntax", root );
-
-			Setting &cols_setting = root[0];
-			Setting &rows_setting = root[1];
-			Setting &elements = root[2];
-
-			ASSERT_UITYPE(cols_setting,TypeInt);
-			ASSERT_UITYPE(rows_setting,TypeInt);
-			ASSERT_UITYPE(elements,TypeArray);
-
-			int cols = cols_setting;
-			int rows = rows_setting;
-			
-			if( cols < 0 | rows < 0)
-				ui_error( "the dimensions of a matrix has to be non-negative", root );
-
-			if( elements.getLength() != cols * rows )
-				ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements );
-
-			if( cols != 1 & rows !=1)
-				ui_error( "the vector length is invalid, it seems to be rather a matrix", elements );
-			
-			int len = rows * cols;
-			vec.set_length ( len );
-			if( len == 0 ) return;
-
-			ASSERT_UITYPE(elements[0],TypeInt);
-			for( int i=0; i<len; i++ ) 
-				vec(i) = elements[i];
-			return;
-		}
-
-		if( root.isArray() )
-		{	
-			int len = root.getLength();
-			vec.set_length( len );
-			if( len == 0 ) return;
-
-			ASSERT_UITYPE(root[0],TypeInt);
-			for( int i=0; i < len; i++ ) 
-				vec(i) = root[i];
-			return;
-		}
-
-		ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root );
-	}
-
-	//! This methods tries to save an integer vector
-	static void to_setting( const ivec &vec, Setting &root )
-	{
-		for( int i=0; i<vec.length(); i++ ) 
-		{
-			Setting &newField = root.add(Setting::TypeInt);
-			newField = vec(i);
-		}
-	}
-
-	//! This methods tries to build a new array of strings 
-	static void from_setting( Array<string> &string_array, const Setting &element )
-	{
-		const Link_Expander link_expander( element );
-		const Setting &root = link_expander.root();
-
-		if( root.getType() == Setting::TypeString )
-		{
-			string_array.set_length( 1 );
-			string_array(0) = (string)root;
-			return;
-		}
-
-		if( root.isArray() )
-		{
-			int len = root.getLength();
-			string_array.set_length( len );
-			if( len == 0 ) return;
-
-			ASSERT_UITYPE(root[0],TypeString);
-			for( int i=0; i < len; i++ ) 
-				string_array(i) = (string)root[i];
-			return;
-		}
-
-		ui_error( "only TypeString or TypeArray are supported as vector of string values", root );
-	}
-
-	//! This methods tries to save an array of strings
-	static void to_setting( const Array<string> &string_array, Setting &root )
-	{
-		for( int i=0; i<string_array.length(); i++ ) 
-		{
-			Setting &newField = root.add(Setting::TypeString);
-			newField = string_array(i);
-		}
+		ASSERT_UITYPE(root,TypeList);
+
+		int len = root.getLength();
+		array_to_load.set_length( len );
+		if( len == 0 ) return;
+		
+		for( int i=0; i < len; i++ ) 
+			from_setting( array_to_load(i), root[i] ); 
 	}
 
 protected:
-
 	//! default constructor 
-	UI( const string& class_name ) : class_name ( class_name )
+	UI( const string& class_name, const type_info * const class_type_info ) 
 	{	
-		Class_To_UI::add_class( class_name, this );
+		Mapped_UI::add_class( class_name, class_type_info, this );
 	}
 
@@ -463,6 +223,6 @@
 	virtual ~UI(){};
 
+
 public: 
-
 	static void ui_error( string message, const Setting &element )
 	{
@@ -477,101 +237,96 @@
 
 	//! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast.
-	template<class T> static T* build( Setting &element, const int index )
-	{
-		return from_setting<T>( to_child_setting( element, index ) );
-	}
-
-	template<class T> static T* build( Setting &element, const string &name )
+	template<class T> static T* build( const Setting &element, const int index )
+	{
+		T* instance;
+		from_setting<T>( reference_to_child_setting( element, index ) );
+		return instance;
+	}
+
+	template<class T> static T* build( const Setting &element, const string &name )
 	{			
-		return from_setting<T>( to_child_setting( element, name ) );
-	}
-
-   	//! This methods tries to save an instance of type T (or some of its descendant types)
-	//! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name
-	//! and connecti it to the passed Setting as a new child node.
-	template<class T> static void save( T &instance, Setting &element, const string &name = "")
+		T* instance;
+		from_setting<T>( instance, reference_to_child_setting( element, name ) );
+		return instance;
+	}
+
+	//! This methods tries to build a new double matrix 
+	template<class T> static bool get( T &instance, const Setting &element, const string &name )
+	{
+		const Setting *root = pointer_to_child_setting( element, name );
+		if( !root ) return false;				
+		from_setting( instance, *root );
+		return true;
+	}
+
+	//! This methods tries to build a new double matrix 
+	template<class T> static bool get( T &instance, const Setting &element, const int index )
+	{
+		const Setting *root = pointer_to_child_setting( element, index );
+		if( !root ) return false;				
+		from_setting( instance, *root );
+		return true;
+	}
+
+	//! This methods tries to build a new double matrix 
+	template<class T> static bool get( Array<T> &array_to_load, const Setting &element, const string &name )
+	{
+		const Setting *root = pointer_to_child_setting( element, name );
+		if( !root ) return false;				
+		from_setting( array_to_load, *root );
+		return true;
+	}
+
+	//! This methods tries to build a new double matrix 
+	template<class T> static bool get( Array<T> &array_to_load, const Setting &element, const int index )
+	{
+		const Setting *root = pointer_to_child_setting( element, index );
+		if( !root ) return false;				
+		from_setting( array_to_load, *root );
+		return true;
+	}
+
+	template< class T> static void save( const T * const instance, Setting &element, const string &name = "")
 	{
 		Setting &root = (name == "") ? element.add( Setting::TypeGroup )							
 									 : element.add( name, Setting::TypeGroup );		
-		to_setting( instance, root );
-	}
-
-	//! This methods tries to build a new double matrix 
-	static bool get( mat& matrix, const Setting &element, const string &name )
-	{
-		const Setting *root = to_child_setting( element, name );
-		if( !root ) return false;				
-		from_setting( matrix, *root );
-		return true;
-	}
-
-	//! This methods tries to build a new double matrix 
-	static bool get( mat& matrix, const Setting &element, const int index )
-	{
-		const Setting *root = to_child_setting( element, index );
-		if( !root ) return false;				
-		from_setting( matrix, *root );
-		return true;
-	}
+
+		const string &class_name = Mapped_UI::retrieve_class_name( &typeid(*instance) );
+			
+		// add attribute "class" 
+		Setting &type = root.add( "class", Setting::TypeString );
+		type = class_name;
+
+		try
+		{
+			instance->to_setting( root );
+		}
+		catch(SettingException xcptn)
+		{
+			it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." );
+		}	
+	}
+
+	//! This methods tries to save a double vec 
+	template<class T> static void save( const Array<T> &array_to_save, Setting &element, const string &name = "" )
+	{
+		ASSERT_UITYPE(element,TypeGroup);
+		Setting &list = (name == "") ? element.add( Setting::TypeList )							
+									 : element.add( name, Setting::TypeList );		
+		for( int i=0; i<array_to_save.length(); i++ ) 
+			save( array_to_save(i), list );
+	}
+
 
 	//! This methods tries to save a double matrix 
-	static void save( mat &matrix, Setting &element, const string &name = "" )
-	{
-		Setting &root = (name == "") ? element.add( Setting::TypeList )							
-									 : element.add( name, Setting::TypeList );		
-		to_setting( matrix, root );
-	}
-
-	//! This methods tries to build a new double vec 
-	static bool get( ivec& vec, const Setting &element, const string &name )
-	{
-		const Setting *root = to_child_setting( element, name );
-		if( !root ) return false;				
-		from_setting( vec, *root );
-		return true;
-	}
-
-	//! This methods tries to build a new double vec 
-	static bool get( ivec& vec, const Setting &element, const int index )
-	{
-		const Setting *root = to_child_setting( element, index );
-		if( !root ) return false;				
-		from_setting( vec, *root );
-		return true;
-	}
+	static void save( const mat &matrix, Setting &element, const string &name = "" );
 
 	//! This methods tries to save a double vec 
-	static void save( ivec &vec, Setting &element, const string &name = "" )
-	{
-		Setting &root = (name == "") ? element.add( Setting::TypeArray )							
-									 : element.add( name, Setting::TypeArray );		
-		to_setting( vec, root );
-	}
-
-	//! This methods tries to build a new double string_array 
-	static bool get( Array<string> &string_array, const Setting &element, const string &name )
-	{
-		const Setting *root = to_child_setting( element, name );
-		if( !root ) return false;				
-		from_setting( string_array, *root );
-		return true;
-	}
-
-	//! This methods tries to build a new double string_array 
-	static bool get( Array<string> &string_array, const Setting &element, const int index )
-	{
-		const Setting *root = to_child_setting( element, index );
-		if( !root ) return false;				
-		from_setting( string_array, *root );
-		return true;
-	}
-
-	//! This methods tries to save a double string_array 
-	static void save( Array<string> &string_array, Setting &element, const string &name = "" )
-	{
-		Setting &root = (name == "") ? element.add( Setting::TypeArray )							
-									 : element.add( name, Setting::TypeArray );		
-		to_setting( string_array, root );
-	}
+	static void save( const ivec &vec, Setting &element, const string &name = "" );
+	
+	private: 
+	//! This methods tries to save a double vec 
+	static void save( const string &str, Setting &element);	
+
 };
 
@@ -588,5 +343,5 @@
 
 	//! default constructor, which is intentionally declared as private
-	Particular_UI<T>( const string &class_name) : UI( class_name ) 
+	Particular_UI<T>( const string &class_name) : UI( class_name, &typeid(T) ) 
 	{	
 	};
@@ -596,9 +351,11 @@
 	static Particular_UI<T>& ui;	
 
-	bdmroot* new_instance()
+	bdmroot* new_instance() const
 	{
 		return new T();
 	}
 };
+
+
 
 
Index: /bdm/user_info.cpp
===================================================================
--- /bdm/user_info.cpp (revision 345)
+++ /bdm/user_info.cpp (revision 351)
@@ -15,23 +15,6 @@
 namespace bdm {
 
-UI::Class_To_UI::Class_To_UI_Map& UI::Class_To_UI::private_map()
-{
-	static Class_To_UI_Map var;
-	return var;
-}
-
-void UI::Class_To_UI::add_class( const string &class_name, UI* ui )
-{
-	private_map().insert( make_pair( class_name, ui ) );
-}
-
-UI* UI::Class_To_UI::retrieve_ui( const string &class_name )
-{
-	Class_To_UI_Map::const_iterator iter = private_map().find( class_name );
-	if( iter == private_map().end()) return NULL;
-	else return iter->second;
-}	
-
-//////////////////////////////////////////////////////////////////////
+
+///////////////////////// UI FILE /////////////////////////////////////////////
 
 
@@ -78,5 +61,303 @@
 	return getRoot();
 }
-
-}
-
+///////////////////////// INTERNAL MAPPED_UI /////////////////////////////////////////////
+
+UI::Mapped_UI::String_To_UI_Map& UI::Mapped_UI::mapped_strings()
+{
+	static String_To_UI_Map var;
+	return var;
+}
+
+UI::Mapped_UI::Type_Info_To_String_Map& UI::Mapped_UI::mapped_type_infos()
+{
+	static Type_Info_To_String_Map var;
+	return var;
+}
+
+void UI::Mapped_UI::add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui )
+{
+	pair< const string, const UI* const > new_pair = make_pair( class_name, ui );
+	mapped_strings().insert( new_pair );
+	mapped_type_infos().insert( make_pair( class_type_info, new_pair.first ) );
+}
+
+const UI& UI::Mapped_UI::retrieve_ui( const string &class_name )
+{
+	String_To_UI_Map::const_iterator iter = mapped_strings().find( class_name );
+	if( iter == mapped_strings().end()) 
+		it_error ( "UI error: class " + class_name + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." );
+	return *iter->second;
+}	
+
+const string& UI::Mapped_UI::retrieve_class_name( const type_info * const class_type_info )
+{
+	Type_Info_To_String_Map::const_iterator iter = mapped_type_infos().find( class_type_info );
+	if( iter == mapped_type_infos().end()) 
+		it_error ( "UI error: class with RTTI name " + string(class_type_info->name()) + " was not properly registered. Use the macro ""UIREGISTER([class name]);"" within your code." );
+	return iter->second;
+}	
+
+///////////////////////// INTERNAL LINK EXPANDER /////////////////////////////////////////////
+
+UI::Link_Expander::Link_Expander( const Setting &potential_link )
+{
+	file = NULL;
+	result = &potential_link;
+
+	if( potential_link.getType() !=  Setting::TypeString )
+		return;
+
+	string link = (string) potential_link;
+	size_t aerobase = link.find('@');
+	if( aerobase != string::npos )
+	{
+		string file_name = link.substr( aerobase + 1, link.length() );
+		file = new UI_File( file_name );
+		file->load();
+		result = &(Setting&)(*file);
+		link = link.substr( 0, aerobase );
+	}
+	else
+		while ( !result->isRoot() ) 
+			result = &result->getParent();
+
+	if( !result->exists( link ) )
+		ui_error( "linked Setting was not found", potential_link );
+
+	result = &(*result)[link];
+}
+
+UI::Link_Expander::~Link_Expander()
+{
+	if( file ) delete file;
+}
+
+const Setting& UI::Link_Expander::root() const
+{
+	return *result;
+}
+
+///////////////////////// UI /////////////////////////////////////////////
+
+
+
+//! This methods   - kvuli ukladani pole stringu, dat jen privatne?
+void UI::save( const string &str, Setting &element )
+{
+	Setting &root = element.add( Setting::TypeString );
+	root = str;
+}
+
+void UI::save( const mat &matrix, Setting &element, const string &name)
+{
+	
+	Setting &root = (name == "") ? element.add( Setting::TypeList )							
+								 : element.add( name, Setting::TypeList );		
+
+	Setting &cols = root.add( Setting::TypeInt );
+	cols = matrix.cols();
+
+	Setting &rows = root.add( Setting::TypeInt );
+	rows = matrix.rows();
+
+	Setting &elements = root.add( Setting::TypeArray );
+
+	// build matrix row-wise
+	for( int i=0; i<matrix.rows(); i++ ) 
+		for( int j=0; j<matrix.cols(); j++)
+		{
+			Setting &new_field = elements.add(Setting::TypeFloat);
+			new_field = matrix(i,j);
+		}
+}
+
+
+	//! This methods tries to save a double vec 
+void UI::save( const ivec &vec, Setting &element, const string &name)
+{
+	
+	Setting &root = (name == "") ? element.add( Setting::TypeArray )							
+								 : element.add( name, Setting::TypeArray );		
+	for( int i=0; i<vec.length(); i++ ) 
+	{
+		Setting &new_field = root.add(Setting::TypeInt);
+		new_field = vec(i);
+	}
+}
+
+
+//! This methods tries to build a new double matrix 
+
+void UI::from_setting( mat& matrix, const Setting &element )
+{
+	const Link_Expander link_expander( element );
+	const Setting &root = link_expander.root();
+
+	if( root.isNumber() )
+	{
+		matrix.set_size( 1, 1 );
+		matrix(0,0) = root;
+		return;
+	}
+
+	if( root.isList() )
+	{
+		if( root.getLength() != 3 )
+			ui_error( "the setting supposed to represent a matrix element has wrong syntax", root );
+
+		Setting &cols_setting = root[0];
+		Setting &rows_setting = root[1];
+		Setting &elements = root[2];
+
+		ASSERT_UITYPE(cols_setting,TypeInt);
+		ASSERT_UITYPE(rows_setting,TypeInt);
+		ASSERT_UITYPE(elements,TypeArray);
+
+		int cols = cols_setting;
+		int rows = rows_setting;
+					
+		if( cols < 0 | rows < 0 )
+			ui_error( "the dimensions of a matrix has to be non-negative", root );
+
+		if( elements.getLength() != cols * rows )
+			ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements );
+
+		matrix.set_size( rows, cols );
+
+		if( cols == 0 || rows == 0 )
+			return;
+
+		if( !elements[0].isNumber() )
+			ui_error( "matrix elements have to be numbers", elements[0] );
+
+		// build matrix row-wise
+		int k = 0;
+		for( int i=0;i<rows;i++ ) 
+			for( int j=0; j<cols; j++)
+				matrix(i,j) = elements[k++];
+		return;
+	}
+
+	ui_error( "only numeric types or TypeList are supported as matrix values", root );
+}
+
+//! This methods tries to build a new integer vector
+void UI::from_setting( ivec &vec, const Setting &element )
+{
+	const Link_Expander link_expander( element );
+	const Setting &root = link_expander.root();
+
+	if( root.isNumber() )
+	{
+		ASSERT_UITYPE(root,TypeInt);
+		vec.set_length( 1 );
+		vec(0) = root;
+		return;
+	}
+
+	if( root.isList() )
+	{
+		if( root.getLength() != 3 )
+			ui_error( "the setting supposed to represent a matrix element has wrong syntax", root );
+
+		Setting &cols_setting = root[0];
+		Setting &rows_setting = root[1];
+		Setting &elements = root[2];
+
+		ASSERT_UITYPE(cols_setting,TypeInt);
+		ASSERT_UITYPE(rows_setting,TypeInt);
+		ASSERT_UITYPE(elements,TypeArray);
+
+		int cols = cols_setting;
+		int rows = rows_setting;
+		
+		if( cols < 0 | rows < 0)
+			ui_error( "the dimensions of a matrix has to be non-negative", root );
+
+		if( elements.getLength() != cols * rows )
+			ui_error( "the count of the matrix elements is incompatible with matrix dimension", elements );
+
+		if( cols != 1 & rows !=1)
+			ui_error( "the vector length is invalid, it seems to be rather a matrix", elements );
+		
+		int len = rows * cols;
+		vec.set_length ( len );
+		if( len == 0 ) return;
+
+		ASSERT_UITYPE(elements[0],TypeInt);
+		for( int i=0; i<len; i++ ) 
+			vec(i) = elements[i];
+		return;
+	}
+
+	if( root.isArray() )
+	{	
+		int len = root.getLength();
+		vec.set_length( len );
+		if( len == 0 ) return;
+
+		ASSERT_UITYPE(root[0],TypeInt);
+		for( int i=0; i < len; i++ ) 
+			vec(i) = root[i];
+		return;
+	}
+
+	ui_error( "only numeric types, TypeArray or TypeList are supported as vector values", root );
+}
+
+
+void UI::from_setting( string &str, const Setting &element )
+{
+	ASSERT_UITYPE(element,TypeString);
+	str = (string) element;
+}
+
+
+///////////////////////// UI FILE /////////////////////////////////////////////
+   	//! This methods tries to save an instance of type T (or some of its descendant types)
+	//! and build DOM tree accordingly. Then, it creates a new DOMNode named according class_name
+	//! and connecti it to the passed Setting as a new child node.
+const Setting* UI::pointer_to_child_setting( const Setting &element, const int index )
+{
+	if( !element.isList())
+		return NULL;
+
+	if( element.getLength() <= index )
+		return NULL;
+
+	return &element[index];
+}
+
+const Setting* UI::pointer_to_child_setting( const Setting &element, const string &name )
+{
+	if( !element.isGroup() )
+		return NULL;
+
+	if( !element.exists( name ) )
+		return NULL;
+
+	return &element[name];
+}
+
+const Setting& UI::reference_to_child_setting( const Setting &element, const int index )
+{
+	if( !element.isList())
+		ui_error( "only TypeList elements could be indexed by integers", element );
+
+	if( element.getLength() <= index )
+		ui_error( "there is not any child with index " + index, element );
+
+	return element[index];
+}
+
+const Setting& UI::reference_to_child_setting( const Setting &element, const string &name )
+{
+	ASSERT_UITYPE(element,TypeGroup);
+	if( !element.exists( name ) )
+		ui_error( "there is not any child named """ + name, element );
+	return element[name];
+}
+
+
+}
+
Index: /bdm/stat/libBM.h
===================================================================
--- /bdm/stat/libBM.h (revision 347)
+++ /bdm/stat/libBM.h (revision 351)
@@ -14,8 +14,9 @@
 #define BM_H
 
+#include <map>
 
 #include "../itpp_ext.h"
 #include "../libconfig/libconfig.h++"
-#include <map>
+
 
 using namespace libconfig;
@@ -47,5 +48,5 @@
 
 	//! This method save all the instance properties into the Setting structure 
-	virtual void to_setting( Setting &root ) 
+	virtual void to_setting( Setting &root ) const
 	{	
 	}
Index: /tests/UI/testUI_in.cfg
===================================================================
--- /tests/UI/testUI_in.cfg (revision 351)
+++ /tests/UI/testUI_in.cfg (revision 351)
@@ -0,0 +1,31 @@
+pepikovo : 
+{
+  class = "Car";
+  year = 1998;
+  manufacturer = "audi";
+  kilometers = 25000;
+  passengers = ( 
+	{ class = "Human"; 
+	   name = "Karlos Novak"; }, 
+	{ class = "Robot"; 
+	   software = ( "CygWin", "Matlab", "Aimsun" ); }, 
+	{ class = "Human"; 
+	   name = "Karlosik Novacek"; } );
+};
+jardovo : 
+{
+  class = "Car";
+  year = 1992;
+  manufacturer = "liaz";
+  kilometers = 1555000;
+};
+ondrejovo : 
+{
+  class = "Bike";
+  year = 1996;
+  manufacturer = "author";
+  electricLights = true;
+  matr = ( 2, 2, [ 1.0, 0.0, 0.0, 1.0 ] );
+};
+elisky = "jardovo";
+kati = "skubankovo@testUI_ex.cfg";
Index: /tests/UI/testUI.cpp
===================================================================
--- /tests/UI/testUI.cpp (revision 345)
+++ /tests/UI/testUI.cpp (revision 351)
@@ -1,4 +1,6 @@
+
+#include <string>
+
 #include <user_info.h>
-#include <string>
 
 using std::string;
@@ -6,4 +8,80 @@
 using namespace bdm;
 
+class Passenger : public bdmroot
+{
+public:
+
+	Passenger()	
+	{
+	}
+};
+
+class Human : public Passenger
+{
+public:
+	string name;
+
+	Human()	
+	{
+		name = "none";
+	}
+
+	virtual void from_setting( const Setting &root )
+	{
+		root.lookupValue( "name", name );
+	}
+
+	virtual void to_setting( Setting &root ) const
+	{	
+		Setting &name_setting = root.add("name", Setting::TypeString );
+		name_setting = name;
+	}
+
+	string ToString()
+	{
+		return name;
+	}
+};
+
+UIREGISTER(Human);
+
+class Robot : public Passenger
+{
+public:
+	int number;
+	Array<string> software;
+
+	Robot()	: software()
+	{
+		number = -1;		
+	}
+
+	virtual void from_setting( const Setting &root )
+	{
+		root.lookupValue( "number", number );
+
+		UI::get( software, root, "software" );
+	}
+
+	virtual void to_setting( Setting &root ) const
+	{	
+		Setting &number_setting = root.add("number", Setting::TypeInt );
+		number_setting = number;
+
+		UI::save( software, root, "software" );
+	}
+
+	string ToString()
+	{
+		stringstream stream;
+		stream << number;
+		for( int i = 0; i<software.length(); i++)
+			stream << "_" + software(i);
+		return stream.str();
+	}
+};
+
+UIREGISTER(Robot);
+
 class Transport : public bdmroot
 {
@@ -29,5 +107,5 @@
 	}
 
-	virtual void to_setting( Setting &root ) 
+	virtual void to_setting( Setting &root ) const
 	{	
 		Setting &year_setting = root.add("year", Setting::TypeInt );
@@ -43,4 +121,5 @@
 public:
 	int kilometers;
+	Array<Passenger*> passengers;
 
 	Car() : Transport()		  
@@ -60,7 +139,9 @@
 
 		root.lookupValue( "kilometers", kilometers );
-	}
-
-	virtual void to_setting( Setting &root ) 
+
+		UI::get( passengers, root, "passengers" );
+	}
+
+	virtual void to_setting( Setting &root ) const
 	{	
 		Transport::to_setting( root );
@@ -68,4 +149,6 @@
 		Setting &kilometers_setting = root.add("kilometers", Setting::TypeInt );
 		kilometers_setting = kilometers;
+
+		UI::save( passengers, root, "passengers" );
 	}
 
@@ -73,5 +156,11 @@
 	{
 		stringstream stream;
-		stream << "a car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock.";
+		stream << "A car made in " << year << " by " << manufacturer << ", having " << kilometers << " kilometers on the clock.";
+		if( passengers.length() )
+		{
+			stream << "The names of passengers are as follows: ";
+			for( int i=0; i<passengers.length(); i++)
+				stream << passengers(i)->ToString() << " ";
+		}
 		return stream.str();
 	}
@@ -109,5 +198,5 @@
 	}
 
-	void to_setting( Setting &root ) 
+	void to_setting( Setting &root ) const
 	{	
 		Transport::to_setting( root );
@@ -132,34 +221,34 @@
 int main()
 {	
+	//////////////////////////////////// LOADING ////////////////////////////////
+	UI_File in("testUI_in.cfg");	
+	in.load();
+	Transport *pepikovo = UI::build<Transport>( in, "pepikovo");	
+	cout << "pepikovo: " << pepikovo->ToString() << endl;		
+	Transport *jardovo = UI::build<Transport>( in, "jardovo");	
+	cout << "jardovo: " << jardovo->ToString() << endl;		
+	Transport *ondrejovo = UI::build<Transport>( in, "ondrejovo");	
+	cout << "ondrejovo: " << ondrejovo->ToString() << endl;		
+	Transport *elisky = UI::build<Transport>( in, "elisky");	
+	cout << "elisky: " << elisky->ToString() << endl;		
+	Transport *kati = UI::build<Transport>( in, "kati");	
+	cout << "kati: " << kati->ToString() << endl;		
+	getchar(); 
+
 	/////////////////////////////////// SAVING //////////////////////////
-	/*
-	Car audi( 1998, "audi", 25000);
-	Car liaz( 1992, "liaz", 1555000);
-	Bike author( 1996, "author", true );
-
-	UI_File root("testUI.cfg");	
-	UI::save( audi, root, "pepikovo");
-	UI::save( liaz, root, "jardovo"); 
-	UI::save( author, root, "ondrejovo");
-	root.save();
+
+	Car audi( 1968, "zyl", 200);
+	Car liaz( 1989, "skoda", 1000);
+	Bike author( 2001, "noname", false );
+	UI_File out("testUI_out.cfg");	
+
+	UI::save( &audi, out, "marty");
+	UI::save( &liaz, out, "bohousovo"); 
+	UI::save( &author, out, "karlovo");
+	UI::save( pepikovo, out, "pepikovo");
+	out.save();
 
 	cout << "all the transport means were saved correctly" << endl;				
 	getchar();
-	*/
-	
-	//////////////////////////////////// LOADING ////////////////////////////////
-	UI_File root("testUI.cfg");	
-	root.load();
-	Transport *pepikovo = UI::build<Transport>( root, "pepikovo");	
-	cout << "pepikovo: " << pepikovo->ToString() << endl;		
-	Transport *jardovo = UI::build<Transport>( root, "jardovo");	
-	cout << "jardovo: " << jardovo->ToString() << endl;		
-	Transport *ondrejovo = UI::build<Transport>( root, "ondrejovo");	
-	cout << "ondrejovo: " << ondrejovo->ToString() << endl;		
-	Transport *elisky = UI::build<Transport>( root, "elisky");	
-	cout << "elisky: " << elisky->ToString() << endl;		
-	Transport *kati = UI::build<Transport>( root, "kati");	
-	cout << "kati: " << kati->ToString() << endl;		
-	getchar(); 
 	return 0;
 }
Index: /sts/UI/testUI.cfg
===================================================================
--- /tests/UI/testUI.cfg (revision 345)
+++  (revision )
@@ -1,25 +1,0 @@
-//test
-pepikovo : 
-{
-  class = "Car";
-  year = 1998;
-  manufacturer = "audi";
-  kilometers = 25000;
-};
-jardovo : 
-{
-  class = "Car";
-  year = 1992;
-  manufacturer = "liaz";
-  kilometers = 1555000;
-};
-ondrejovo : 
-{
-  class = "Bike";
-  year = 1996;
-  manufacturer = "author";
-  electricLights = true;
-  matr = ( 2, 2, [ 1.0, 0.0, 0.0, 1.0 ] );
-};
-elisky : "jardovo";
-kati : "skubankovo@testUI_ex.cfg";
