Index: trunk/src/lua/lua_state.cc
===================================================================
--- trunk/src/lua/lua_state.cc	(revision 340)
+++ trunk/src/lua/lua_state.cc	(revision 341)
@@ -515,2 +515,53 @@
 }
 
+nv::lua::ref nv::lua::state::register_handle_component_impl( const std::string& id, bool empty )
+{
+	int args = empty ? 1 : 2;
+	NV_LUA_STACK_ASSERT( m_state, -args );
+
+	if ( lua_isnil( m_state, -1 ) || (!empty && lua_isnil( m_state, -2 )) )
+	{
+		lua_pop( m_state, args );
+		return ref();
+	}
+	if (empty)
+		lua_createtable( m_state, 0, 0 );
+	else
+		nlua_deepcopy( m_state, -2 );
+	lua_pushstring( m_state, id.c_str() );
+	lua_pushvalue( m_state, -2 );
+	lua_rawset( m_state, -4 );
+	lua_replace( m_state, -2 );
+	ref result = lua::ref( luaL_ref( m_state, LUA_REGISTRYINDEX ) );
+	if (!empty) lua_pop( m_state, 1 );
+	return result;
+}
+
+void nv::lua::state::unregister_handle_component_impl( const std::string& id )
+{
+	NV_LUA_STACK_ASSERT( m_state, -1 );
+
+	if ( lua_isnil( m_state, -1 ) )
+	{
+		lua_pop( m_state, 1 );
+		return;
+	}
+	lua_pushstring( m_state, id.c_str() );
+	lua_pushnil( m_state );
+	lua_rawset( m_state, -3 );
+	lua_pop( m_state, 1 );
+}
+
+void nv::lua::state::register_singleton( const char* name, void* o )
+{
+	if ( o == nullptr ) return;
+	stack_guard guard( this );
+	lua_getglobal( m_state, name );
+	if ( lua_isnil( m_state, -1 ) )
+	{
+		NV_THROW( runtime_error, std::string( name ) + " type not registered!" );
+	}
+	deep_pointer_copy( -1, o );
+	lua_setglobal( m_state, name );
+}
+
