Index: trunk/nv/lua/lua_state.hh
===================================================================
--- trunk/nv/lua/lua_state.hh	(revision 76)
+++ trunk/nv/lua/lua_state.hh	(revision 77)
@@ -72,8 +72,11 @@
 			void log_stack();
 			lua_State* get_raw();
+			reference register_object( object * o );
+			void unregister_object( object * o );
 			~state();
 		private:
 			int do_current( const std::string& name );
 			bool push( const std::string& path, bool global = true );
+			void deep_pointer_copy( int index, void* obj );
 		private:
 			bool m_owner;
Index: trunk/nv/object.hh
===================================================================
--- trunk/nv/object.hh	(revision 76)
+++ trunk/nv/object.hh	(revision 77)
@@ -34,5 +34,5 @@
 		 * Object constructor
 		 */
-		object( root* aroot, const string& aid, uid auid );
+		object( root* aroot, const string& aid );
 
 		/**
@@ -132,4 +132,11 @@
 
 		/**
+		 * Returns the root object of this object.
+		 *
+		 * @returns root object of current object
+		 */
+		virtual root* get_root() const { return (root*)m_root; }
+
+		/**
 		 * Returns object UID
 		 */
Index: trunk/nv/types.hh
===================================================================
--- trunk/nv/types.hh	(revision 76)
+++ trunk/nv/types.hh	(revision 77)
@@ -10,4 +10,6 @@
 #include <nv/object.hh>
 #include <type_traits>
+#include <typeinfo>
+#include <typeindex>
 #include <utility>
 #include <unordered_map>
@@ -363,4 +365,6 @@
     };
 
+	// TODO: we don't need the get_type_name template? Can we just base on typeid now, and 
+	//       pass type name on creation?
     class type_database
     {
@@ -384,8 +388,9 @@
 			i_type->destructor  = DestructObject<TYPE>;
 
-			m_types[name] = i_type;
+			m_types[name]             = i_type;
+			m_idx_types[typeid(TYPE)] = i_type;
 			return *i_type;
 		}
-
+		// TODO: delete?
         type_entry* get_type( hash_string name )
 		{
@@ -397,7 +402,24 @@
 			return nullptr;
 		}
+		type_entry* get_type( const type_info& t )
+		{
+			type_info_map::iterator it = m_idx_types.find( std::type_index(t) );
+			if ( it != m_idx_types.end() ) 
+			{
+				return it->second;
+			}
+			return nullptr;
+		}
     private:
-        typedef std::unordered_map<hash_string, type_entry*> type_map;
-        type_map m_types;
+		struct compare_type_info {
+			bool operator ()(const type_info* a, const type_info* b) const {
+				return a->before(*b);
+			}
+		};
+
+        typedef std::unordered_map<hash_string, type_entry*>     type_map;
+		typedef std::unordered_map<std::type_index, type_entry*> type_info_map;
+        type_map      m_types;
+		type_info_map m_idx_types;
 	};
 
Index: trunk/src/gui/gui_element.cc
===================================================================
--- trunk/src/gui/gui_element.cc	(revision 76)
+++ trunk/src/gui/gui_element.cc	(revision 77)
@@ -13,5 +13,5 @@
 
 element::element( root* aroot, const rectangle r ) 
-	: object( aroot, "", 0 ), m_class(""), m_relative( r ), m_absolute( r ), m_enabled( true ), m_visible( true ), m_dirty( true )
+	: object( aroot, "" ), m_class(""), m_relative( r ), m_absolute( r ), m_enabled( true ), m_visible( true ), m_dirty( true )
 {
 
Index: trunk/src/lua/lua_state.cc
===================================================================
--- trunk/src/lua/lua_state.cc	(revision 76)
+++ trunk/src/lua/lua_state.cc	(revision 77)
@@ -10,4 +10,6 @@
 #include "nv/logging.hh"
 #include "nv/string.hh"
+#include "nv/root.hh"
+#include "nv/types.hh"
 
 using namespace nv;
@@ -286,3 +288,67 @@
 }
 
-
+lua::reference lua::state::register_object( object * o )
+{
+	if (!o) return ref_none;
+	type_database *db = o->get_root()->get_type_database();
+	if (!db) return ref_none;
+	type_entry* t = db->get_type(typeid(o));
+	if (!t) return ref_none;
+	stack_guard guard( this );
+	lua_getglobal( L, t->name.text );
+	if ( lua_isnil( L, -1 ) )
+	{
+		NV_THROW( runtime_error, std::string( t->name.text ) + " type not registered!" );
+	}
+	deep_pointer_copy( -1, o );
+    return luaL_ref( L, LUA_REGISTRYINDEX );
+}
+
+void lua::state::unregister_object( object * o )
+{
+	if (!o) return;
+	stack_guard guard( this );
+	lua_rawgeti( L, LUA_REGISTRYINDEX, o->get_lua_index() );
+	lua_pushstring( L, "__ptr" );
+	lua_pushboolean( L, false );
+	lua_rawset( L, -3 );
+	lua_pop( L, 1 );
+	luaL_unref( L, LUA_REGISTRYINDEX, o->get_lua_index() );
+}
+
+void lua::state::deep_pointer_copy( int index, void* obj )
+{
+	index = lua_absindex( L, index );
+	lua_newtable( L );
+	lua_pushnil( L );
+	bool has_functions = false;
+	bool has_metatable = false;
+
+	while ( lua_next( L, index ) != 0 )
+	{
+		if ( lua_isfunction( L, -1 ) ) 
+			has_functions = true;
+		else if ( lua_istable( L, -1 ) )
+		{
+			deep_pointer_copy( -1, obj );
+			lua_insert( L, -2 );
+			lua_pop( L, 1 );
+		}
+		lua_pushvalue( L, -2 );
+		lua_insert( L, -2 );
+		lua_settable( L, -4 );
+	}
+
+	if ( lua_getmetatable( L, -2 ) )
+	{
+		lua_setmetatable( L, -2 );
+		has_metatable = true;
+	}
+
+	if ( has_functions || has_metatable )
+	{
+		lua_pushstring( L, "__ptr" );
+		lua_pushlightuserdata( L, obj );
+		lua_rawset( L, -3 );
+	}
+}
Index: trunk/src/object.cc
===================================================================
--- trunk/src/object.cc	(revision 76)
+++ trunk/src/object.cc	(revision 77)
@@ -9,4 +9,6 @@
 #include "nv/root.hh"
 #include "nv/types.hh"
+#include "nv/lua/lua_state.hh"
+#include "nv/uid.hh"
 
 using namespace nv;
@@ -19,8 +21,21 @@
 }
 
-object::object( root* aroot, const string& aid, uid auid )
-	: m_root( aroot ), m_id(aid), m_name(), m_uid( auid ), m_lua_index(-2), m_parent( nullptr ), m_children(), m_child_count(0)
+object::object( root* aroot, const string& aid )
+	: m_root( aroot ), m_id(aid), m_name(), m_uid( 0 ), m_lua_index(-2), m_parent( nullptr ), m_children(), m_child_count(0)
 {
-	//	uid_store::register_object( this, auid );
+	if ( m_root )
+	{
+		uid_store*  store = get_root()->get_uid_store();
+		lua::state* state = get_root()->get_lua_state();
+		if (store)
+		{
+			m_uid = store->insert( this );
+		}
+		if (state)
+		{
+			m_lua_index = state->register_object( this );
+		}
+	}
+
 }
 
@@ -77,9 +92,14 @@
 object::~object()
 {
-// 	if ( m_lua_index != lua::ref_none )
-// 	{
-// 		lua::state::get()->unregister_object( this );
-// 	}
-// 	uid_store::unregister_object( m_uid );
+ 	if ( m_lua_index != lua::ref_none )
+ 	{
+		lua::state* state = get_root()->get_lua_state();
+ 		state->unregister_object( this );
+ 	}
+	if ( m_uid != 0 && m_root )
+	{
+		uid_store* store = get_root()->get_uid_store();
+		if (store) store->remove( m_uid );
+	}
 	detach();
 	destroy_children();
