context: namespace LuaInterface 
  {
  	using System;
  	using System.IO;
  	using System.Collections;
  	using System.Reflection;
      using System.Collections.Generic;
      using System.Diagnostics;
  
  	/*
  	 * Passes objects from the CLR to Lua and vice-versa
  	 * 
  	 * Author: Fabio Mascarenhas
  	 * Version: 1.0
  	 */
  	public class ObjectTranslator 
  	{
  		internal CheckType typeChecker;
  
          // object # to object (FIXME - it should be possible to get object address as an object #)
          public readonly Dictionary<int, object> objects = new Dictionary<int, object>();
          // object to object #
          public readonly Dictionary<object, int> objectsBackMap = new Dictionary<object, int>();
          internal Lua interpreter;
  		private MetaFunctions metaFunctions;
  		private ArrayList assemblies;
  		private LuaCSFunction registerTableFunction,unregisterTableFunction,getMethodSigFunction,
  			getConstructorSigFunction,importTypeFunction,loadAssemblyFunction;
  
          internal EventHandlerContainer pendingEvents = new EventHandlerContainer();
  
  		public ObjectTranslator(Lua interpreter,IntPtr luaState) 
  		{
  			this.interpreter=interpreter;
  			typeChecker=new CheckType(this);
  			metaFunctions=new MetaFunctions(this);
  			assemblies=new ArrayList();
  
  			importTypeFunction=new LuaCSFunction(this.importType);
  			loadAssemblyFunction=new LuaCSFunction(this.loadAssembly);
  			registerTableFunction=new LuaCSFunction(this.registerTable);
  			unregisterTableFunction=new LuaCSFunction(this.unregisterTable);
  			getMethodSigFunction=new LuaCSFunction(this.getMethodSignature);
  			getConstructorSigFunction=new LuaCSFunction(this.getConstructorSignature);
  
  			createLuaObjectList(luaState);
  			createIndexingMetaFunction(luaState);
  			createBaseClassMetatable(luaState);
  			createClassMetatable(luaState);
  			createFunctionMetatable(luaState);
  			setGlobalFunctions(luaState);
  		}
  
  		/*
  		 * Sets up the list of objects in the Lua side
  		 */
  		private void createLuaObjectList(IntPtr luaState) 
  		{
  			LuaDLL.lua_pushstring(luaState,"luaNet_objects");
  			LuaDLL.lua_newtable(luaState);
  			LuaDLL.lua_newtable(luaState);
  			LuaDLL.lua_pushstring(luaState,"__mode");
  			LuaDLL.lua_pushstring(luaState,"v");
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_setmetatable(luaState,-2);
  			LuaDLL.lua_settable(luaState,LuaIndexes.LUA_REGISTRYINDEX);
  		}
  		/*
  		 * Registers the indexing function of CLR objects
  		 * passed to Lua
  		 */
  		private void createIndexingMetaFunction(IntPtr luaState) 
  		{
  			LuaDLL.lua_pushstring(luaState,"luaNet_indexfunction");
  			LuaDLL.luaL_dostring(luaState,MetaFunctions.luaIndexFunction);	// steffenj: lua_dostring renamed to luaL_dostring
  			//LuaDLL.lua_pushstdcallcfunction(luaState,indexFunction);
  			LuaDLL.lua_rawset(luaState,LuaIndexes.LUA_REGISTRYINDEX);
  		}
  		/*
  		 * Creates the metatable for superclasses (the base
  		 * field of registered tables)
  		 */
  		private void createBaseClassMetatable(IntPtr luaState) 
  		{
  			LuaDLL.luaL_newmetatable(luaState,"luaNet_searchbase");
  			LuaDLL.lua_pushstring(luaState,"__gc");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_pushstring(luaState,"__tostring");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_pushstring(luaState,"__index");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.baseIndexFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_pushstring(luaState,"__newindex");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_settop(luaState,-2);
  		}
  		/*
  		 * Creates the metatable for type references
  		 */
  		private void createClassMetatable(IntPtr luaState) 
  		{
  			LuaDLL.luaL_newmetatable(luaState,"luaNet_class");
  			LuaDLL.lua_pushstring(luaState,"__gc");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_pushstring(luaState,"__tostring");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_pushstring(luaState,"__index");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.classIndexFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_pushstring(luaState,"__newindex");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.classNewindexFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_pushstring(luaState,"__call");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.callConstructorFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_settop(luaState,-2);
  		}
  		/*
  		 * Registers the global functions used by LuaInterface
  		 */
  		private void setGlobalFunctions(IntPtr luaState)
  		{
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.indexFunction);
  			LuaDLL.lua_setglobal(luaState,"get_object_member");
  			LuaDLL.lua_pushstdcallcfunction(luaState,importTypeFunction);
  			LuaDLL.lua_setglobal(luaState,"import_type");
  			LuaDLL.lua_pushstdcallcfunction(luaState,loadAssemblyFunction);
  			LuaDLL.lua_setglobal(luaState,"load_assembly");
  			LuaDLL.lua_pushstdcallcfunction(luaState,registerTableFunction);
  			LuaDLL.lua_setglobal(luaState,"make_object");
  			LuaDLL.lua_pushstdcallcfunction(luaState,unregisterTableFunction);
  			LuaDLL.lua_setglobal(luaState,"free_object");
  			LuaDLL.lua_pushstdcallcfunction(luaState,getMethodSigFunction);
  			LuaDLL.lua_setglobal(luaState,"get_method_bysig");
  			LuaDLL.lua_pushstdcallcfunction(luaState,getConstructorSigFunction);
  			LuaDLL.lua_setglobal(luaState,"get_constructor_bysig");
  		}
  		/*
  		 * Creates the metatable for delegates
  		 */
  		private void createFunctionMetatable(IntPtr luaState) 
  		{
  			LuaDLL.luaL_newmetatable(luaState,"luaNet_function");
  			LuaDLL.lua_pushstring(luaState,"__gc");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_pushstring(luaState,"__call");
  			LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.execDelegateFunction);
  			LuaDLL.lua_settable(luaState,-3);
  			LuaDLL.lua_settop(luaState,-2);
  		}
  		/*
  		 * Passes errors (argument e) to the Lua interpreter
  		 */
  		internal void throwError(IntPtr luaState,object e) 
  		{
  			push(luaState,e);
  			LuaDLL.lua_error(luaState);
  		}
  		/*
  		 * Implementation of load_assembly. Throws an error
  		 * if the assembly is not found.
  		 */
  		private int loadAssembly(IntPtr luaState) 
  		{
  			string assemblyName=LuaDLL.lua_tostring(luaState,1);
  			try 
  			{
  				Assembly assembly=Assembly.LoadWithPartialName(assemblyName);
  
                  try
                  {
                      // If we couldn't find it based on a name, see if we can use it as a filename and find it
                      if (assembly == null)
                          assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName));
                  }
                  catch (Exception)
                  {
                      // ignore - it might not even be a filename
                  }
  
  				if(assembly!=null && assemblies.IndexOf(assembly)==-1)
  					assemblies.Add(assembly);
  			} 
  			catch(Exception e) 
  			{
  				throwError(luaState,e);
  			}
  			return 0;
  		}
          
          internal Type FindType(string className)
          {
  			foreach(Assembly assembly in assemblies) 
  			{
  				Type klass=assembly.GetType(className);
  				if(klass!=null) 
  				{
  					return klass;
  				}
  			}
              return null;
          }
              
  		/*
  		 * Implementation of import_type. Returns nil if the
  		 * type is not found.
  		 */
  		private int importType(IntPtr luaState) 
  		{
  			string className=LuaDLL.lua_tostring(luaState,1);
              Type klass=FindType(className);
              if(klass!=null)
  				pushType(luaState,klass);
              else
      			LuaDLL.lua_pushnil(luaState);
              return 1;
          }
  		/*
  		 * Implementation of make_object. Registers a table (first
  		 * argument in the stack) as an object subclassing the
  		 * type passed as second argument in the stack.
  		 */
  		private int registerTable(IntPtr luaState) 
  		{
  			if(LuaDLL.lua_type(luaState,1)==LuaTypes.LUA_TTABLE) 
  			{
  				LuaTable luaTable=getTable(luaState,1);
                  string superclassName = LuaDLL.lua_tostring(luaState, 2);
                  if (superclassName != null)
                  {
                      Type klass = FindType(superclassName);
                      if (klass != null)
                      {
                          // Creates and pushes the object in the stack, setting
                          // it as the  metatable of the first argument
                          object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable);
                          pushObject(luaState, obj, "luaNet_metatable");
                          LuaDLL.lua_newtable(luaState);
                          LuaDLL.lua_pushstring(luaState, "__index");
                          LuaDLL.lua_pushvalue(luaState, -3);
                          LuaDLL.lua_settable(luaState, -3);
                          LuaDLL.lua_pushstring(luaState, "__newindex");
                          LuaDLL.lua_pushvalue(luaState, -3);
                          LuaDLL.lua_settable(luaState, -3);
                          LuaDLL.lua_setmetatable(luaState, 1);
                          // Pushes the object again, this time as the base field
                          // of the table and with the luaNet_searchbase metatable
                          LuaDLL.lua_pushstring(luaState, "base");
                          int index = addObject(obj);
                          pushNewObject(luaState, obj, index, "luaNet_searchbase");
                          LuaDLL.lua_rawset(luaState, 1);
                      }
                      else
                          throwError(luaState, "register_table: can not find superclass '" + superclassName + "'");
                  }
                  else
                      throwError(luaState, "register_table: superclass name can not be null");
  			} 
  			else throwError(luaState,"register_table: first arg is not a table");
  			return 0;
  		}
  		/*
  		 * Implementation of free_object. Clears the metatable and the
  		 * base field, freeing the created object for garbage-collection
  		 */
  		private int unregisterTable(IntPtr luaState) 
  		{
  			try 
  			{
  				if(LuaDLL.lua_getmetatable(luaState,1)!=0) 
  				{
  					LuaDLL.lua_pushstring(luaState,"__index");
  					LuaDLL.lua_gettable(luaState,-2);
  					object obj=getRawNetObject(luaState,-1);
  					if(obj==null) throwError(luaState,"unregister_table: arg is not valid table");
  					FieldInfo luaTableField=obj.GetType().GetField("__luaInterface_luaTable");
  					if(luaTableField==null) throwError(luaState,"unregister_table: arg is not valid table");
  					luaTableField.SetValue(obj,null);
  					LuaDLL.lua_pushnil(luaState);
  					LuaDLL.lua_setmetatable(luaState,1);
  					LuaDLL.lua_pushstring(luaState,"base");
  					LuaDLL.lua_pushnil(luaState);
  					LuaDLL.lua_settable(luaState,1);
  				} 
  				else throwError(luaState,"unregister_table: arg is not valid table");
  			} 
  			catch(Exception e) 
  			{
  				throwError(luaState,e.Message);
  			}
  			return 0;
  		}
  		/*
  		 * Implementation of get_method_bysig. Returns nil
  		 * if no matching method is not found.
  		 */
  		private int getMethodSignature(IntPtr luaState) 
  		{
  			IReflect klass; object target;
  			int udata=LuaDLL.luanet_checkudata(luaState,1,"luaNet_class");
  			if(udata!=-1) 
  			{
  				klass=(IReflect)objects[udata];
  				target=null;
  			}
  			else 
  			{
  				target=getRawNetObject(luaState,1);
  				if(target==null) 
  				{
  					throwError(luaState,"get_method_bysig: first arg is not type or object reference");
  					LuaDLL.lua_pushnil(luaState);
  					return 1;
  				}
  				klass=target.GetType();
  			}
  			string methodName=LuaDLL.lua_tostring(luaState,2);
  			Type[] signature=new Type[LuaDLL.lua_gettop(luaState)-2];
  			for(int i=0;i<signature.Length;i++)
  				signature[i]=FindType(LuaDLL.lua_tostring(luaState,i+3));
  			try 
  			{
  				MethodInfo method=klass.GetMethod(methodName,BindingFlags.Public | BindingFlags.Static |
                      BindingFlags.Instance | BindingFlags.FlattenHierarchy,null,signature,null);
  				pushFunction(luaState,new LuaCSFunction((new LuaMethodWrapper(this,target,klass,method)).call));
  			} 
  			catch(Exception e) 
  			{
  				throwError(luaState,e);
  				LuaDLL.lua_pushnil(luaState);
  			}
  			return 1;
  		}
  		/*
  		 * Implementation of get_constructor_bysig. Returns nil
  		 * if no matching constructor is found.
  		 */
  		private int getConstructorSignature(IntPtr luaState) 
  		{
  			IReflect klass=null;
  			int udata=LuaDLL.luanet_checkudata(luaState,1,"luaNet_class");
  			if(udata!=-1) 
  			{
  				klass=(IReflect)objects[udata];
  			}
  			if(klass==null) 
  			{
  				throwError(luaState,"get_constructor_bysig: first arg is invalid type reference");
  			}
  			Type[] signature=new Type[LuaDLL.lua_gettop(luaState)-1];
  			for(int i=0;i<signature.Length;i++)
  				signature[i]=FindType(LuaDLL.lua_tostring(luaState,i+2));
  			try 
  			{
  				ConstructorInfo constructor=klass.UnderlyingSystemType.GetConstructor(signature);
  				pushFunction(luaState,new LuaCSFunction((new LuaMethodWrapper(this,null,klass,constructor)).call));
  			} 
  			catch(Exception e) 
  			{
  				throwError(luaState,e);
  				LuaDLL.lua_pushnil(luaState);
  			}
  			return 1;
  		}
  		/*
  		 * Pushes a type reference into the stack
  		 */
  		internal void pushType(IntPtr luaState, Type t) 
  		{
  			pushObject(luaState,new ProxyType(t),"luaNet_class");
  		}
  		/*
  		 * Pushes a delegate into the stack
  		 */
  		internal void pushFunction(IntPtr luaState, LuaCSFunction func) 
  		{
  			pushObject(luaState,func,"luaNet_function");
  		}
  		/*
  		 * Pushes a CLR object into the Lua stack as an userdata
  		 * with the provided metatable
  		 */
  		internal void pushObject(IntPtr luaState, object o, string metatable) 
  		{
  			int index = -1;
  			// Pushes nil
  			if(o==null) 
  			{
  				LuaDLL.lua_pushnil(luaState);
  				return;
  			}
  
  			// Object already in the list of Lua objects? Push the stored reference.
              bool found = objectsBackMap.TryGetValue(o, out index);
  			if(found) 
  			{
  				LuaDLL.luaL_getmetatable(luaState,"luaNet_objects");
  				LuaDLL.lua_rawgeti(luaState,-1,index);
  
                  // Note: starting with lua5.1 the garbage collector may remove weak reference items (such as our luaNet_objects values) when the initial GC sweep 
                  // occurs, but the actual call of the __gc finalizer for that object may not happen until a little while later.  During that window we might call
                  // this routine and find the element missing from luaNet_objects, but collectObject() has not yet been called.  In that case, we go ahead and call collect
                  // object here
                  // did we find a non nil object in our table? if not, we need to call collect object
                  LuaTypes type = LuaDLL.lua_type(luaState, -1);
                  if (type != LuaTypes.LUA_TNIL)
                  {
                      LuaDLL.lua_remove(luaState, -2);     // drop the metatable - we're going to leave our object on the stack
  
                      return;
                  }
  
                  // MetaFunctions.dumpStack(this, luaState);
                  LuaDLL.lua_remove(luaState, -1);    // remove the nil object value
                  LuaDLL.lua_remove(luaState, -1);    // remove the metatable
  
                  collectObject(o, index);            // Remove from both our tables and fall out to get a new ID
  			}
              index = addObject(o);
  
  			pushNewObject(luaState,o,index,metatable);
  		}
  
  
  		/*
  		 * Pushes a new object into the Lua stack with the provided
  		 * metatable
  		 */
  		private void pushNewObject(IntPtr luaState,object o,int index,string metatable) 
  		{
  			if(metatable=="luaNet_metatable") 
  			{
  				// Gets or creates the metatable for the object's type
  				LuaDLL.luaL_getmetatable(luaState,o.GetType().AssemblyQualifiedName);
  
  				if(LuaDLL.lua_isnil(luaState,-1))
  				{
  					LuaDLL.lua_settop(luaState,-2);
  					LuaDLL.luaL_newmetatable(luaState,o.GetType().AssemblyQualifiedName);
  					LuaDLL.lua_pushstring(luaState,"cache");
  					LuaDLL.lua_newtable(luaState);
  					LuaDLL.lua_rawset(luaState,-3);
  					LuaDLL.lua_pushlightuserdata(luaState,LuaDLL.luanet_gettag());
  					LuaDLL.lua_pushnumber(luaState,1);
  					LuaDLL.lua_rawset(luaState,-3);
  					LuaDLL.lua_pushstring(luaState,"__index");
  					LuaDLL.lua_pushstring(luaState,"luaNet_indexfunction");
  					LuaDLL.lua_rawget(luaState,LuaIndexes.LUA_REGISTRYINDEX);
  					LuaDLL.lua_rawset(luaState,-3);
  					LuaDLL.lua_pushstring(luaState,"__gc");
  					LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction);
  					LuaDLL.lua_rawset(luaState,-3);
  					LuaDLL.lua_pushstring(luaState,"__tostring");
  					LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction);
  					LuaDLL.lua_rawset(luaState,-3);
  					LuaDLL.lua_pushstring(luaState,"__newindex");
  					LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction);
  					LuaDLL.lua_rawset(luaState,-3);
  				}
  			}
  			else
  			{
  				LuaDLL.luaL_getmetatable(luaState,metatable);
  			}
  
  			// Stores the object index in the Lua list and pushes the
  			// index into the Lua stack
  			LuaDLL.luaL_getmetatable(luaState,"luaNet_objects");
  			LuaDLL.luanet_newudata(luaState,index);
  			LuaDLL.lua_pushvalue(luaState,-3);
  			LuaDLL.lua_remove(luaState,-4);
  			LuaDLL.lua_setmetatable(luaState,-2);
  			LuaDLL.lua_pushvalue(luaState,-1);
  			LuaDLL.lua_rawseti(luaState,-3,index);
  			LuaDLL.lua_remove(luaState,-2);
  		}
  		/*
  		 * Gets an object from the Lua stack with the desired type, if it matches, otherwise
  		 * returns null.
  		 */
  		internal object getAsType(IntPtr luaState,int stackPos,Type paramType) 
  		{
  			ExtractValue extractor=typeChecker.checkType(luaState,stackPos,paramType);
  			if(extractor!=null) return extractor(luaState,stackPos);
  			return null;
  		}
  
  
          /// <summary>
          /// Given the Lua int ID for an object remove it from our maps
          /// </summary>
          /// <param name="udata"></param>
  		internal void collectObject(int udata) 
  		{
  			object o;
              bool found = objects.TryGetValue(udata, out o);
  
              // The other variant of collectObject might have gotten here first, in that case we will silently ignore the missing entry
              if (found)
              {
                  // Debug.WriteLine("Removing " + o.ToString() + " @ " + udata);
  
                  objects.Remove(udata);
                  objectsBackMap.Remove(o);
              }
  		}
  
  
          /// <summary>
          /// Given an object reference, remove it from our maps
          /// </summary>
          /// <param name="udata"></param>
          void collectObject(object o, int udata)
          {
              // Debug.WriteLine("Removing " + o.ToString() + " @ " + udata);
  
              objects.Remove(udata);
              objectsBackMap.Remove(o);
          }
  
  
          /// <summary>
          /// We want to ensure that objects always have a unique ID
          /// </summary>
          int nextObj = 0;
  
          int addObject(object obj)
          {
              // New object: inserts it in the list
              int index = nextObj++;
  
              // Debug.WriteLine("Adding " + obj.ToString() + " @ " + index);
  
              objects[index] = obj;
              objectsBackMap[obj] = index;
  
              return index;
          }
  
  
  
  		/*
  		 * Gets an object from the Lua stack according to its Lua type.
  		 */
  		internal object getObject(IntPtr luaState,int index) 
  		{
  			LuaTypes type=LuaDLL.lua_type(luaState,index);
  			switch(type) 
  			{
  				case LuaTypes.LUA_TNUMBER:
  				{
  					return LuaDLL.lua_tonumber(luaState,index);
  				} 
  				case LuaTypes.LUA_TSTRING: 
  				{
  					return LuaDLL.lua_tostring(luaState,index);
  				} 
  				case LuaTypes.LUA_TBOOLEAN:
  				{
  					return LuaDLL.lua_toboolean(luaState,index);
  				} 
  				case LuaTypes.LUA_TTABLE: 
  				{
  					return getTable(luaState,index);
  				} 
  				case LuaTypes.LUA_TFUNCTION:
  				{
  					return getFunction(luaState,index);
  				} 
  				case LuaTypes.LUA_TUSERDATA:
  				{
  					int udata=LuaDLL.luanet_tonetobject(luaState,index);
  					if(udata!=-1)
  						return objects[udata];
  					else
  						return getUserData(luaState,index);
  				}
  				default:
  					return null;
  			}
  		}
  		/*
  		 * Gets the table in the index positon of the Lua stack.
  		 */
  		internal LuaTable getTable(IntPtr luaState,int index) 
  		{
  			LuaDLL.lua_pushvalue(luaState,index);
  			return new LuaTable(LuaDLL.lua_ref(luaState,1),interpreter);
  		}
  		/*
  		 * Gets the userdata in the index positon of the Lua stack.
  		 */
  		internal LuaUserData getUserData(IntPtr luaState,int index) 
  		{
  			LuaDLL.lua_pushvalue(luaState,index);
  			return new LuaUserData(LuaDLL.lua_ref(luaState,1),interpreter);
  		}
  		/*
  		 * Gets the function in the index positon of the Lua stack.
  		 */
  		internal LuaFunction getFunction(IntPtr luaState,int index) 
  		{
  			LuaDLL.lua_pushvalue(luaState,index);
  			return new LuaFunction(LuaDLL.lua_ref(luaState,1),interpreter);
  		}
  		/*
  		 * Gets the CLR object in the index positon of the Lua stack. Returns
  		 * delegates as Lua functions.
  		 */
  		internal object getNetObject(IntPtr luaState,int index) 
  		{
  			int idx=LuaDLL.luanet_tonetobject(luaState,index);
  			if(idx!=-1)
  				return objects[idx];
  			else
  				return null;
  		}
  		/*
  		 * Gets the CLR object in the index positon of the Lua stack. Returns
  		 * delegates as is.
  		 */
  		internal object getRawNetObject(IntPtr luaState,int index) 
  		{
  			int udata=LuaDLL.luanet_rawnetobj(luaState,index);
  			if(udata!=-1) 
  			{
  				return objects[udata];
  			}
  			return null;
  		}
  		/*
  		 * Pushes the entire array into the Lua stack and returns the number
  		 * of elements pushed.
  		 */
  		internal int returnValues(IntPtr luaState, object[] returnValues) 
  		{
  			if(LuaDLL.lua_checkstack(luaState,returnValues.Length+5)) 
  			{
  				for(int i=0;i<returnValues.Length;i++) 
  				{
  					push(luaState,returnValues[i]);
  				}
  				return returnValues.Length;
  			} else
  				return 0;
  		}
  		/*
  		 * Gets the values from the provided index to
  		 * the top of the stack and returns them in an array.
  		 */
  
gt: 		internal object[] popValues(IntPtr luaState,int oldTop) 