Index: trunk/src/lua/lua_state.cc
===================================================================
--- trunk/src/lua/lua_state.cc	(revision 75)
+++ 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 );
+	}
+}
