/*
 * $Id: LuaState.java,v 1.2 2008/11/07 20:07:54 anaef Exp $
 * See LICENSE.txt for license terms.
 */

package com.naef.jnlua;

// Lua 5.2
// bitlib
// setfenv/getfenv -> deprecated
// lua_equal, lua_lessthan -> deprecated, lua_compare new
// remove GLOBALSINDEX
// __pairs, __ipairs support as metamethods, see Java Reflector and Java Module
// gc: new opcode
// LUA_ERRGCMM
// lua_yieldk, lua_pcallk

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import com.naef.jnlua.JavaReflector.Metamethod;

/**
 * JNLua core class representing a Lua instance.
 * 
 * <p>
 * The class performs extensive checking on all arguments and its state.
 * Specifically, the following exceptions are thrown under the indicated
 * conditions:
 * </p>
 * 
 * <table class="doc">
 * <tr>
 * <th>Exception</th>
 * <th>When</th>
 * </tr>
 * <tr>
 * <td>{@link java.lang.NullPointerException}</td>
 * <td>if an argument is <code>null</code> and the API does not explicitly
 * specify that the argument may be <code>null</code></td>
 * </tr>
 * <tr>
 * <td>{@link java.lang.IllegalStateException}</td>
 * <td>if the Lua state is closed and the API does not explicitly specify that
 * the method may be invoked on a closed Lua state</td>
 * </tr>
 * <tr>
 * <td>{@link java.lang.IllegalArgumentException}</td>
 * <td>if a stack index refers to an undefined stack location and the API does
 * not explicitly specify that the stack index may be undefined</td>
 * </tr>
 * <tr>
 * <td>{@link java.lang.IllegalArgumentException}</td>
 * <td>if a stack index refers to an stack location with value type that is
 * different from the value type explicitly specified in the API</td>
 * </tr>
 * <tr>
 * <td>{@link java.lang.IllegalArgumentException}</td>
 * <td>if a count is negative or out of range and the API does not explicitly
 * specify that the count may be negative or out of range</td>
 * </tr>
 * <tr>
 * <td>{@link com.naef.jnlua.LuaRuntimeException}</td>
 * <td>if a Lua runtime error occurs</td>
 * </tr>
 * <tr>
 * <td>{@link com.naef.jnlua.LuaSyntaxException}</td>
 * <td>if a the syntax of a Lua chunk is incorrect</td>
 * </tr>
 * <tr>
 * <td>{@link com.naef.jnlua.LuaMemoryAllocationException}</td>
 * <td>if the Lua memory allocator runs out of memory or if a JNI allocation
 * fails</td>
 * </tr>
 * </table>
 */
public class LuaState {
	// -- Static
	/**
	 * Registry pseudo-index.
	 */
	public static final int REGISTRYINDEX = -10000;

	/**
	 * Environment pseudo-index.
	 */
	public static final int ENVIRONINDEX = -10001;

	/**
	 * Globals pseudo-index.
	 */
	public static final int GLOBALSINDEX = -10002;

	/**
	 * Multiple returns pseudo return value count.
	 */
	public static final int MULTRET = -1;

	/**
	 * Status indicating that a thread is suspended.
	 */
	public static final int YIELD = 1;

	/**
	 * The JNLua version. The format is &lt;major&gt;.&lt;minor&gt;.
	 */
	public static final String VERSION = "0.9";

	/**
	 * The Lua version. The format is &lt;major&gt;.&lt;minor&gt;.
	 */
	public static final String LUA_VERSION;

	static {
		NativeSupport.getInstance().getLoader().load();
		LUA_VERSION = lua_version();
	}

	/**
	 * The API version.
	 */
	private static final int APIVERSION = 1;

	// -- State
	/**
	 * The <code>lua_State</code> pointer on the JNI side. <code>0</code>
	 * implies that this Lua state is closed. The field is modified exclusively
	 * on the JNI side and must not be touched on the Java side.
	 */
	private long luaState;

	/**
	 * The <code>lua_State</code> pointer on the JNI side for the running
	 * coroutine. This field is modified exclusively on the JNI side and must
	 * not be touched on the Java side.
	 */
	private long luaThread;

	/**
	 * Ensures proper finalization of this Lua state.
	 */
	private Object finalizeGuardian;

	/**
	 * The class loader for dynamically loading classes.
	 */
	private ClassLoader classLoader;

	/**
	 * Reflects Java objects.
	 */
	private JavaReflector javaReflector;

	/**
	 * Converts between Lua types and Java types.
	 */
	private Converter converter;

	/**
	 * Set of Lua proxy phantom references for pre-mortem cleanup.
	 */
	private Set<LuaValueProxyRef> proxySet = new HashSet<LuaValueProxyRef>();

	/**
	 * Reference queue for pre-mortem cleanup.
	 */
	private ReferenceQueue<LuaValueProxyImpl> proxyQueue = new ReferenceQueue<LuaValueProxyImpl>();

	// -- Construction
	/**
	 * Creates a new instance. The class loader of this Lua state is set to the
	 * context class loader of the calling thread. The Java reflector and the
	 * converter are initialized with the default implementations.
	 * 
	 * @see #getClassLoader()
	 * @see #setClassLoader(ClassLoader)
	 * @see #getJavaReflector()
	 * @see #setJavaReflector(JavaReflector)
	 * @see #getConverter()
	 * @see #setConverter(Converter)
	 */
	public LuaState() {
		synchronized (getClass()) {
			lua_newstate(APIVERSION);
		}
		check();

		// Create a finalize guardian
		finalizeGuardian = new Object() {
			@Override
			public void finalize() {
				synchronized (LuaState.this) {
					closeInternal();
				}
			}
		};

		// Add metamethods
		for (int i = 0; i < JavaReflector.Metamethod.values().length; i++) {
			final JavaReflector.Metamethod metamethod = JavaReflector.Metamethod
					.values()[i];
			lua_pushjavafunction(new JavaFunction() {
				@Override
				public int invoke(LuaState luaState) {
					JavaFunction javaFunction = getMetamethod(luaState
							.toJavaObjectRaw(1), metamethod);
					if (javaFunction != null) {
						return javaFunction.invoke(LuaState.this);
					} else {
						throw new UnsupportedOperationException(metamethod
								.getMetamethodName());
					}
				}
			});
			lua_setfield(-2, metamethod.getMetamethodName());
		}
		lua_pop(1);

		// Set fields
		classLoader = Thread.currentThread().getContextClassLoader();
		javaReflector = DefaultJavaReflector.getInstance();
		converter = DefaultConverter.getInstance();
	}

	// -- Properties
	/**
	 * Returns the class loader of this Lua state. The class loader is used for
	 * dynamically loading classes.
	 * 
	 * <p>
	 * The method may be invoked on a closed Lua state.
	 * </p>
	 * 
	 * @return the class loader
	 */
	public synchronized ClassLoader getClassLoader() {
		return classLoader;
	}

	/**
	 * Sets the class loader of this Lua state. The class loader is used for
	 * dynamically loading classes.
	 * 
	 * <p>
	 * The method may be invoked on a closed Lua state.
	 * </p>
	 * 
	 * @param classLoader
	 *            the class loader to set
	 */
	public synchronized void setClassLoader(ClassLoader classLoader) {
		if (classLoader == null) {
			throw new NullPointerException();
		}
		this.classLoader = classLoader;
	}

	/**
	 * Returns the Java reflector of this Lua state.
	 * 
	 * <p>
	 * The method may be invoked on a closed Lua state.
	 * </p>
	 * 
	 * @return the Java reflector converter
	 */
	public synchronized JavaReflector getJavaReflector() {
		return javaReflector;
	}

	/**
	 * Sets the Java reflector of this Lua state.
	 * 
	 * <p>
	 * The method may be invoked on a closed Lua state.
	 * </p>
	 * 
	 * @param javaReflector
	 *            the Java reflector
	 */
	public synchronized void setJavaReflector(JavaReflector javaReflector) {
		if (converter == null) {
			throw new NullPointerException();
		}
		this.javaReflector = javaReflector;
	}

	/**
	 * Returns a metamethod for a specified object. If the object implements the
	 * {@link com.naef.jnlua.JavaReflector} interface, the metamethod is first
	 * queried from the object. If the object provides the requested metamethod,
	 * that metamethod is returned. Otherwise, the method returns the metamethod
	 * provided by the Java reflector configured in this Lua state.
	 * 
	 * <p>
	 * Clients requiring access to metamethods should go by this method to
	 * ensure consistent class-by-class overriding of the Java reflector.
	 * </p>
	 * 
	 * @param obj
	 *            the object, or <code>null</code>
	 * @return the Java reflector
	 */
	public synchronized JavaFunction getMetamethod(Object obj,
			Metamethod metamethod) {
		if (obj != null && obj instanceof JavaReflector) {
			JavaFunction javaFunction = ((JavaReflector) obj)
					.getMetamethod(metamethod);
			if (javaFunction != null) {
				return javaFunction;
			}
		}
		return javaReflector.getMetamethod(metamethod);
	}

	/**
	 * Returns the converter of this Lua state.
	 * 
	 * <p>
	 * The method may be invoked on a closed Lua state.
	 * </p>
	 * 
	 * @return the converter
	 */
	public synchronized Converter getConverter() {
		return converter;
	}

	/**
	 * Sets the converter of this Lua state.
	 * 
	 * <p>
	 * The method may be invoked on a closed Lua state.
	 * </p>
	 * 
	 * @param converter
	 *            the converter
	 */
	public synchronized void setConverter(Converter converter) {
		if (converter == null) {
			throw new NullPointerException();
		}
		this.converter = converter;
	}

	/**
	 * Returns whether this Lua state is open.
	 * 
	 * <p>
	 * The method may be invoked on a closed Lua state.
	 * </p>
	 * 
	 * @return whether this Lua state is open
	 */
	public final synchronized boolean isOpen() {
		return isOpenInternal();
	}

	// -- Life cycle
	/**
	 * Closes this Lua state and releases all resources.
	 * 
	 * <p>
	 * The method may be invoked on a closed Lua state and has no effect in that
	 * case.
	 * </p>
	 */
	public synchronized void close() {
		closeInternal();
	}

	/**
	 * Performs a garbage collection operation.
	 * 
	 * @param what
	 *            the operation to perform
	 * @param data
	 *            the argument required by some operations (see Lua Reference
	 *            Manual)
	 * @return a return value depending on the GC operation performed (see Lua
	 *         Reference Manual)
	 */
	public synchronized int gc(GcAction what, int data) {
		check();
		return lua_gc(what.ordinal(), data);
	}

	// -- Registration
	/**
	 * Opens the specified library in this Lua state.
	 * 
	 * @param library
	 *            the library
	 */
	public synchronized void openLib(Library library) {
		check();
		library.open(this);
	}

	/**
	 * Opens the Lua standard libraries and the JNLua Java module in this Lua
	 * state.
	 * 
	 * <p>
	 * The method opens all libraries defined by the {@link Library}
	 * enumeration.
	 * </p>
	 */
	public synchronized void openLibs() {
		check();
		for (Library library : Library.values()) {
			library.open(this);
		}
	}

	/**
	 * Registers a named Java function as a global variable.
	 * 
	 * @param namedJavaFunction
	 *            the Java function to register
	 */
	public synchronized void register(NamedJavaFunction namedJavaFunction) {
		check();
		String name = namedJavaFunction.getName();
		if (name == null) {
			throw new IllegalArgumentException("Anonymous function");
		}
		pushJavaFunction(namedJavaFunction);
		setGlobal(name);
	}

	/**
	 * Registers a module and pushes the module on the stack. The module name is
	 * allowed to contain dots to define module hierarchies.
	 * 
	 * @param moduleName
	 *            the module name
	 * @param namedJavaFunctions
	 *            the Java functions of the module
	 */
	public synchronized void register(String moduleName,
			NamedJavaFunction[] namedJavaFunctions) {
		check();
		/*
		 * The following code corresponds to luaL_openlib() and must be kept in
		 * sync. The original code cannot be called due to the necessity of
		 * pushing each C function with an individual closure.
		 */
		lua_findtable(REGISTRYINDEX, "_LOADED", 1);
		getField(-1, moduleName);
		if (!isTable(-1)) {
			pop(1);
			String conflict = lua_findtable(GLOBALSINDEX, moduleName,
					namedJavaFunctions.length);
			if (conflict != null) {
				throw new IllegalArgumentException(String.format(
						"naming conflict for module name '%s' at '%s'",
						moduleName, conflict));
			}
			pushValue(-1);
			setField(-3, moduleName);
		}
		remove(-2);
		for (int i = 0; i < namedJavaFunctions.length; i++) {
			String name = namedJavaFunctions[i].getName();
			if (name == null) {
				throw new IllegalArgumentException(String.format(
						"anonymous function at index %d", i));
			}
			pushJavaFunction(namedJavaFunctions[i]);
			setField(-2, name);
		}
	}

	// -- Load and dump
	/**
	 * Loads a Lua chunk from an input stream and pushes it on the stack as a
	 * function. The Lua chunk must be either a UTF-8 encoded source chunk or a
	 * pre-compiled binary chunk.
	 * 
	 * @param inputStream
	 *            the input stream
	 * @param chunkName
	 *            the name of the chunk for use in error messages
	 * @throws IOException
	 *             if an IO error occurs
	 */
	public synchronized void load(InputStream inputStream, String chunkName)
			throws IOException {
		if (chunkName == null) {
			throw new NullPointerException();
		}
		check();
		lua_load(inputStream, "=" + chunkName);
	}

	/**
	 * Loads a Lua chunk from a string and pushes it on the stack as a function.
	 * The string must contain a source chunk.
	 * 
	 * @param chunk
	 *            the Lua source chunk
	 * @param chunkName
	 *            the name of the chunk for use in error messages
	 */
	public synchronized void load(String chunk, String chunkName) {
		try {
			load(new ByteArrayInputStream(chunk.getBytes("UTF-8")), chunkName);
		} catch (IOException e) {
			throw new LuaMemoryAllocationException(e.getMessage());
		}
	}

	/**
	 * Dumps the function on top of the stack as a pre-compiled binary chunk
	 * into an output stream.
	 * 
	 * @param outputStream
	 *            the output stream
	 * @throws IOException
	 *             if an IO error occurs
	 */
	public synchronized void dump(OutputStream outputStream) throws IOException {
		check();
		lua_dump(outputStream);
	}

	// -- Call
	/**
	 * Calls a Lua function. The function to call and the specified number of
	 * arguments are on the stack. After the call, the specified number of
	 * returns values are on stack. If the number of return values has been
	 * specified as {@link #MULTRET}, the number of values on the stack
	 * corresponds the to number of values actually returned by the called
	 * function.
	 * 
	 * @param argCount
	 *            the number of arguments
	 * @param returnCount
	 *            the number of return values, or {@link #MULTRET} to accept all
	 *            values returned by the function
	 */
	public synchronized void call(int argCount, int returnCount) {
		check();
		lua_pcall(argCount, returnCount);
	}

	// -- Global
	/**
	 * Pushes the value of a global variable on the stack.
	 * 
	 * @param name
	 *            the global variable name
	 */
	public synchronized void getGlobal(String name) {
		check();
		lua_getglobal(name);
	}

	/**
	 * Sets the value on top of the stack as a global variable and pops the
	 * value from the stack.
	 * 
	 * @param name
	 *            the global variable name
	 */
	public synchronized void setGlobal(String name)
			throws LuaMemoryAllocationException, LuaRuntimeException {
		check();
		lua_setglobal(name);
	}

	// -- Stack push
	/**
	 * Pushes a boolean value on the stack.
	 * 
	 * @param b
	 *            the boolean value to push
	 */
	public synchronized void pushBoolean(boolean b) {
		check();
		lua_pushboolean(b ? 1 : 0);
	}

	/**
	 * Pushes an integer value as a number value on the stack.
	 * 
	 * @param n
	 *            the integer value to push
	 */
	public synchronized void pushInteger(int n) {
		check();
		lua_pushinteger(n);
	}

	/**
	 * Pushes a Java function on the stack.
	 * 
	 * @param javaFunction
	 *            the function to push
	 */
	public synchronized void pushJavaFunction(JavaFunction javaFunction) {
		check();
		lua_pushjavafunction(javaFunction);
	}

	/**
	 * Pushes a Java object on the stack. The object is pushed "as is", i.e.
	 * without conversion.
	 * 
	 * <p>
	 * If you require to push a Lua value that represents the Java object, then
	 * invoke <code>pushJavaObject(object)</code>.
	 * </p>
	 * 
	 * <p>
	 * You cannot push <code>null</code> without conversion since
	 * <code>null</code> is not a Java object. The converter converts
	 * <code>null</code> to <code>nil</code>.
	 * </p>
	 * 
	 * @param object
	 *            the Java object
	 * @see #pushJavaObject(Object)
	 */
	public synchronized void pushJavaObjectRaw(Object object) {
		check();
		lua_pushjavaobject(object);
	}

	/**
	 * Pushes a Java object on the stack with conversion. The object is
	 * processed the by the configured converter.
	 * 
	 * @param object
	 *            the Java object
	 * @see #getConverter()
	 * @see #setConverter(Converter)
	 */
	public synchronized void pushJavaObject(Object object) {
		check();
		getConverter().convertJavaObject(this, object);
	}

	/**
	 * Pushes a nil value on the stack.
	 */
	public synchronized void pushNil() {
		check();
		lua_pushnil();
	}

	/**
	 * Pushes a number value on the stack.
	 * 
	 * @param n
	 *            the number to push
	 */
	public synchronized void pushNumber(double n) {
		check();
		lua_pushnumber(n);
	}

	/**
	 * Pushes a string value on the stack.
	 * 
	 * @param s
	 *            the string value to push
	 */
	public synchronized void pushString(String s) {
		check();
		lua_pushstring(s);
	}

	// -- Stack type test
	/**
	 * Returns whether the value at the specified stack index is a boolean.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a boolean
	 */
	public synchronized boolean isBoolean(int index) {
		check();
		return lua_isboolean(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is a C function.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a function
	 */
	public synchronized boolean isCFunction(int index) {
		check();
		return lua_iscfunction(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is a function
	 * (either a C function, a Java function or a Lua function.)
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a function
	 */
	public synchronized boolean isFunction(int index) {
		check();
		return lua_isfunction(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is a Java
	 * function.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a function
	 */
	public synchronized boolean isJavaFunction(int index) {
		check();
		return lua_isjavafunction(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is a Java object.
	 * 
	 * <p>
	 * Note that the method does not perform conversion. If you want to check if
	 * a value <i>is convertible to</i> a Java object, then invoke <code>
	 * isJavaObject(index, Object.class)</code>
	 * .
	 * </p>
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a Java object
	 * @see #isJavaObject(int, Class)
	 */
	public synchronized boolean isJavaObjectRaw(int index) {
		check();
		return lua_isjavaobject(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is convertible to
	 * a Java object of the specified type. The conversion is checked by the
	 * configured converter.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is convertible to a Java object of the
	 *         specified type
	 * @see #setConverter(Converter)
	 * @see #getConverter()
	 */
	public synchronized boolean isJavaObject(int index, Class<?> type) {
		check();
		return converter.getTypeDistance(this, index, type) != Integer.MAX_VALUE;
	}

	/**
	 * Returns whether the value at the specified stack index is
	 * <code>nil</code>.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is <code>nil</code>
	 */
	public synchronized boolean isNil(int index) {
		check();
		return lua_isnil(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is undefined.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is undefined
	 */
	public synchronized boolean isNone(int index) {
		check();
		return lua_isnone(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is undefined or
	 * <code>nil</code>.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is undefined
	 */
	public synchronized boolean isNoneOrNil(int index) {
		check();
		return lua_isnoneornil(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is a number or a
	 * string convertible to a number.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a number or a string convertible to a number
	 */
	public synchronized boolean isNumber(int index) {
		check();
		return lua_isnumber(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is a string or a
	 * number (which is always convertible to a string.)
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a string or a number
	 */
	public synchronized boolean isString(int index) {
		check();
		return lua_isstring(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is a table.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a table
	 */
	public synchronized boolean isTable(int index) {
		check();
		return lua_istable(index) != 0;
	}

	/**
	 * Returns whether the value at the specified stack index is a thread.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return whether the value is a thread
	 */
	public synchronized boolean isThread(int index) {
		check();
		return lua_isthread(index) != 0;
	}

	// -- Stack query
	/**
	 * Returns whether the values at two specified stack indexes are equal
	 * according to Lua semantics.
	 * 
	 * @param index1
	 *            the first stack index
	 * @param index2
	 *            the second stack index
	 * @return whether the values are equal
	 */
	public synchronized boolean equal(int index1, int index2) {
		check();
		return lua_equal(index1, index2) != 0;
	}

	/**
	 * Returns whether a value at a first stack index is less than the value at
	 * a second stack index according to Lua semantics.
	 * 
	 * @param index1
	 *            the first stack index
	 * @param index2
	 *            the second stack index
	 * @return whether the value at the first index is less than the value at
	 *         the second index
	 */
	public synchronized boolean lessThan(int index1, int index2)
			throws LuaMemoryAllocationException, LuaRuntimeException {
		check();
		return lua_lessthan(index1, index2) != 0;
	}

	/**
	 * Returns the length of the value at the specified stack index. The
	 * definition of the length depends on the type of the value. For strings,
	 * it is the length of the string, for tables it is the result of the length
	 * operator. For other types, the return value is undefined.
	 * 
	 * @param index
	 *            the stack index
	 * @return the length
	 */
	public synchronized int length(int index) {
		check();
		return lua_objlen(index);
	}

	/**
	 * Bypassing metatable logic, returns whether the values at two specified
	 * stack indexes are equal according to Lua semantics.
	 * 
	 * @param index1
	 *            the first stack index
	 * @param index2
	 *            the second stack index
	 * @return whether the values are equal
	 */
	public synchronized boolean rawEqual(int index1, int index2) {
		check();
		return lua_rawequal(index1, index2) != 0;
	}

	/**
	 * Returns the boolean representation of the value at the specified stack
	 * index. The boolean representation is <code>true</code> for all values
	 * except <code>false</code> and <code>nil</code>.
	 * 
	 * @param index
	 *            the stack index
	 * @return the boolean representation of the value
	 */
	public synchronized boolean toBoolean(int index) {
		check();
		return lua_toboolean(index) != 0;
	}

	/**
	 * Returns the integer representation of the value at the specified stack
	 * index. The value must be a number or a string convertible to a number.
	 * Otherwise, the method returns <code>0</code>.
	 * 
	 * @param index
	 *            the stack index
	 * @return the integer representation, or <code>0</code>
	 */
	public synchronized int toInteger(int index) {
		check();
		return lua_tointeger(index);
	}

	/**
	 * Returns the Java function of the value at the specified stack index. If
	 * the value is not a Java function, the method returns <code>null</code>.
	 * 
	 * @param index
	 *            the stack index
	 * @return the Java function, or <code>null</code>
	 */
	public synchronized JavaFunction toJavaFunction(int index) {
		check();
		return lua_tojavafunction(index);
	}

	/**
	 * Returns the Java object of the value at the specified stack index. If the
	 * value is not a Java object, the method returns <code>null</code>.
	 * 
	 * <p>
	 * Note that the method does not convert values to Java objects. If you
	 * require <i>any</i> Java object that represents the value at the specified
	 * index, then invoke <code>toJavaObject(index, Object.class)</code>.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return the Java object, or <code>null</code>
	 * @see #toJavaObject(int, Class)
	 */
	public synchronized Object toJavaObjectRaw(int index) {
		check();
		return lua_tojavaobject(index);
	}

	/**
	 * Returns a Java object of the specified type representing the value at the
	 * specified stack index. The value must be convertible to a Java object of
	 * the specified type. The conversion is executed by the configured
	 * converter.
	 * 
	 * @param index
	 *            the stack index
	 * @param type
	 *            the Java type to convert to
	 * @return the object
	 * @throws ClassCastException
	 *             if the conversion is not supported by the converter
	 * @see #getConverter()
	 * @see #setConverter(Converter)
	 */
	public synchronized <T> T toJavaObject(int index, Class<T> type) {
		check();
		return converter.convertLuaValue(this, index, type);
	}

	/**
	 * Returns the number representation of the value at the specified stack
	 * index. The value must be a number or a string convertible to a number.
	 * Otherwise, the method returns <code>0.0</code>.
	 * 
	 * @param index
	 *            the stack index
	 * @return the number representation, or <code>0.0</code>
	 */
	public synchronized double toNumber(int index) {
		check();
		return lua_tonumber(index);
	}

	/**
	 * Returns the pointer representation of the value at the specified stack
	 * index. The value must be a table, thread, function or userdata (such as a
	 * Java object.) Otherwise, the method returns <code>0L</code>. Different
	 * values return different pointers. Other than that, the returned value has
	 * no portable significance.
	 * 
	 * @param index
	 *            the stack index
	 * @return the pointer representation, or <code>0L</code> if none
	 */
	public synchronized long toPointer(int index) {
		check();
		return lua_topointer(index);
	}

	/**
	 * Returns the string representation of the value at the specified stack
	 * index. The value must be a string or a number. If the value is a number,
	 * it is in place converted to a string. Otherwise, the method returns
	 * <code>null</code>.
	 * 
	 * @param index
	 *            the stack index
	 * @return the string representation, or <code>null</code>
	 */
	public synchronized String toString(int index) {
		check();
		return lua_tostring(index);
	}

	/**
	 * Returns the type of the value at the specified stack index.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the stack index
	 * @return the type, or <code>null</code> if the stack index is undefined
	 */
	public synchronized LuaType type(int index) {
		check();
		int type = lua_type(index);
		return type >= 0 ? LuaType.values()[type] : null;
	}

	/**
	 * Returns the name of the type at the specified stack index. The type name
	 * is the display text for the Lua type except for Java objects where the
	 * type name is the canonical class name.
	 * 
	 * <p>
	 * The stack index may be undefined.
	 * </p>
	 * 
	 * @param index
	 *            the index
	 * @return the type name
	 * @see LuaType#displayText()
	 * @see Class#getCanonicalName()
	 */
	public synchronized String typeName(int index) {
		check();
		LuaType type = type(index);
		if (type == null) {
			return "no value";
		}
		switch (type) {
		case USERDATA:
			if (isJavaObjectRaw(index)) {
				Object object = toJavaObjectRaw(index);
				Class<?> clazz;
				if (object instanceof Class<?>) {
					clazz = (Class<?>) object;
				} else {
					clazz = object.getClass();
				}
				return clazz.getCanonicalName();
			}
			break;
		}
		return type.displayText();
	}

	// -- Stack operation
	/**
	 * Concatenates the specified number values on top of the stack and replaces
	 * them with the concatenated value.
	 * 
	 * @param n
	 *            the number of values to concatenate
	 */
	public synchronized void concat(int n) {
		check();
		lua_concat(n);
	}

	/**
	 * Returns the number of values on the stack.
	 * 
	 * @return the number of values on the tack
	 */
	public synchronized int getTop() {
		check();
		return lua_gettop();
	}

	/**
	 * Pops the value on top of the stack inserting it at the specified index
	 * and moving up elements above that index.
	 * 
	 * @param index
	 *            the stack index
	 */
	public synchronized void insert(int index) {
		check();
		lua_insert(index);
	}

	/**
	 * Pops values from the stack.
	 * 
	 * @param count
	 *            the number of values to pop
	 */
	public synchronized void pop(int count) {
		check();
		lua_pop(count);
	}

	/**
	 * Pushes the value at the specified index on top of the stack.
	 * 
	 * @param index
	 *            the stack index
	 */
	public synchronized void pushValue(int index) {
		check();
		lua_pushvalue(index);
	}

	/**
	 * Removes the value at the specified stack index moving down elements above
	 * that index.
	 * 
	 * @param index
	 *            the stack index
	 */
	public synchronized void remove(int index) {
		check();
		lua_remove(index);
	}

	/**
	 * Replaces the value at the specified index with the value popped from the
	 * top of the stack.
	 * 
	 * @param index
	 *            the stack index
	 */
	public synchronized void replace(int index) {
		check();
		lua_replace(index);
	}

	/**
	 * Sets the specified index as the new top of the stack.
	 * 
	 * <p>
	 * The new top of the stack may be above the current top of the stack. In
	 * this case, new values are set to <code>nil</code>.
	 * </p>
	 * 
	 * @param index
	 *            the index of the new top of the stack
	 */
	public synchronized void setTop(int index) {
		check();
		lua_settop(index);
	}

	// -- Table
	/**
	 * Pushes on the stack the value indexed by the key on top of the stack in
	 * the table at the specified index. The key is replaced by the value from
	 * the table.
	 * 
	 * @param index
	 *            the stack index containing the table
	 */
	public synchronized void getTable(int index) {
		check();
		lua_gettable(index);
	}

	/**
	 * Pushes on the stack the value indexed by the specified string key in the
	 * table at the specified index.
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @param key
	 *            the string key
	 */
	public synchronized void getField(int index, String key) {
		check();
		lua_getfield(index, key);
	}

	/**
	 * Creates a new table and pushes it on the stack.
	 */
	public synchronized void newTable() {
		check();
		lua_newtable();
	}

	/**
	 * Creates a new table with pre-allocated space for a number of array
	 * elements and record elements and pushes it on the stack.
	 * 
	 * @param arrayCount
	 *            the number of array elements
	 * @param recordCount
	 *            the number of record elements
	 */
	public synchronized void newTable(int arrayCount, int recordCount) {
		check();
		lua_createtable(arrayCount, recordCount);
	}

	/**
	 * Pops a key from the stack and pushes on the stack the next key and its
	 * value in the table at the specified index. If there is no next key, the
	 * key is popped but nothing is pushed. The method returns whether there is
	 * a next key.
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @return whether there is a next key
	 */
	public synchronized boolean next(int index) {
		check();
		return lua_next(index) != 0;
	}

	/**
	 * Bypassing metatable logic, pushes on the stack the value indexed by the
	 * key on top of the stack in the table at the specified index. The key is
	 * replaced by the value from the table.
	 * 
	 * @param index
	 *            the stack index containing the table
	 */
	public synchronized void rawGet(int index) {
		check();
		lua_rawget(index);
	}

	/**
	 * Bypassing metatable logic, pushes on the stack the value indexed by the
	 * specified integer key in the table at the specified index.
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @param key
	 *            the integer key
	 */
	public synchronized void rawGet(int index, int key) {
		check();
		lua_rawgeti(index, key);
	}

	/**
	 * Bypassing metatable logic, sets the value on top of the stack in the
	 * table at the specified index using the value on the second highest stack
	 * position as the key. Both the value and the key are popped from the
	 * stack.
	 * 
	 * @param index
	 *            the stack index containing the table
	 */
	public synchronized void rawSet(int index) {
		check();
		lua_rawset(index);
	}

	/**
	 * Bypassing metatable logic, sets the value on top of the stack in the
	 * table at the specified index using the specified integer key. The value
	 * is popped from the stack.
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @param key
	 *            the integer key
	 */
	public synchronized void rawSet(int index, int key) {
		check();
		lua_rawseti(index, key);
	}

	/**
	 * Sets the value on top of the stack in the table at the specified index
	 * using the value on the second highest stack position as the key. Both the
	 * value and the key are popped from the stack.
	 * 
	 * @param index
	 *            the stack index containing the table
	 */
	public synchronized void setTable(int index) {
		check();
		lua_settable(index);
	}

	/**
	 * Sets the value on top of the stack in the table at the specified index
	 * using the specified string key. The value is popped from the stack.
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @param key
	 *            the string key
	 */
	public synchronized void setField(int index, String key) {
		check();
		lua_setfield(index, key);
	}

	// -- Metatable
	/**
	 * Pushes on the stack the value of the named field in the metatable of the
	 * value at the specified index and returns <code>true</code>. If the value
	 * does not have a metatable or if the metatable does not contain the named
	 * field, nothing is pushed and the method returns <code>false</code>.
	 * 
	 * @param index
	 *            the stack index containing the value to get the metafield from
	 * @param key
	 *            the string key
	 * @return whether the metafield was pushed on the stack
	 */
	public synchronized boolean getMetafield(int index, String key) {
		check();
		return lua_getmetafield(index, key) != 0;
	}

	/**
	 * Pushes on the stack the metatable of the value at the specified index. If
	 * the value does not have a metatable, the method returns
	 * <code>false</code> and nothing is pushed.
	 * 
	 * @param index
	 *            the stack index containing the value to get the metatable from
	 * @return whether the metatable was pushed on the stack
	 */
	public synchronized boolean getMetatable(int index) {
		check();
		return lua_getmetatable(index) != 0;
	}

	/**
	 * Sets the value on top of the stack as the metatable of the value at the
	 * specified index. The metatable to be set is popped from the stack
	 * regardless whether it can be set or not.
	 * 
	 * @param index
	 *            the stack index containing the value to set the metatable for
	 * @return whether the metatable was set
	 */
	public synchronized boolean setMetatable(int index) {
		check();
		return lua_setmetatable(index) != 0;
	}

	// -- Environment table
	/**
	 * Pushes on the stack the environment table of the value at the specified
	 * index. If the value does not have an environment table, <code>nil</code>
	 * is pushed on the stack.
	 * 
	 * @param index
	 *            the stack index containing the value to get the environment
	 *            table from
	 */
	public synchronized void getFEnv(int index) {
		check();
		lua_getfenv(index);
	}

	/**
	 * Sets the value on top of the stack as the environment table of the value
	 * at the specified index. The environment table to be set is popped from
	 * the stack regardless whether it can be set or not.
	 * 
	 * @param index
	 *            the stack index containing the value to set the environment
	 *            table for
	 * @return whether the environment table was set
	 */
	public synchronized boolean setFEnv(int index) {
		check();
		return lua_setfenv(index) != 0;
	}

	// -- Thread
	/**
	 * Pops the start function of a new Lua thread from the stack and creates
	 * the new thread with that start function. The new thread is pushed on the
	 * stack.
	 */
	public synchronized void newThread() {
		check();
		lua_newthread();
	}

	/**
	 * Resumes the thread at the specified stack index, popping the specified
	 * number of arguments from the top of the stack and passing them to the
	 * resumed thread. The method returns the number of values pushed on the
	 * stack as the return values of the resumed thread.
	 * 
	 * @param index
	 *            the stack index containing the thread
	 * @param argCount
	 *            the number of arguments to pass
	 * @return the number of values returned by the thread
	 */
	public synchronized int resume(int index, int argCount) {
		check();
		return lua_resume(index, argCount);
	}

	/**
	 * Returns the status of the thread at the specified stack index. If the
	 * thread is in initial state of has finished its execution, the method
	 * returns <code>0</code>. If the thread has yielded, the method returns
	 * {@link #YIELD}. Other return values indicate errors for which an
	 * exception has been thrown.
	 * 
	 * @param index
	 *            the index
	 * @return the status
	 */
	public synchronized int status(int index) {
		check();
		return lua_status(index);
	}

	/**
	 * Yields the running thread, popping the specified number of values from
	 * the top of the stack and passing them as return values to the thread
	 * which has resumed the running thread. The method must be used exclusively
	 * at the exit point of Java functions, i.e.
	 * <code>return luaState.yield(n)</code>.
	 * 
	 * @param returnCount
	 *            the number of results to pass
	 * @return the return value of the Java function
	 */
	public synchronized int yield(int returnCount) {
		check();
		return lua_yield(returnCount);
	}

	// -- Reference
	/**
	 * Stores the value on top of the stack in the table at the specified index
	 * and returns the integer key of the value in that table as a reference.
	 * The value is popped from the stack.
	 * 
	 * @param index
	 *            the stack index containing the table where to store the value
	 * @return the reference integer key
	 * @see #unref(int, int)
	 */
	public synchronized int ref(int index) {
		check();
		return lua_ref(index);

	}

	/**
	 * Removes a previously created reference from the table at the specified
	 * index. The value is removed from the table and its integer key of the
	 * reference is freed for reuse.
	 * 
	 * @param index
	 *            the stack index containing the table where the value was
	 *            stored
	 * @param reference
	 *            the reference integer key
	 * @see #ref(int)
	 */
	public synchronized void unref(int index, int reference) {
		check();
		lua_unref(index, reference);
	}

	// -- Optimization
	/**
	 * Counts the number of entries in a table.
	 * 
	 * <p>
	 * The method provides optimized performance over a Java implementation of
	 * the same functionality due to the reduced number of JNI transitions.
	 * </p>
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @return the number of entries in the table
	 */
	public synchronized int tableSize(int index) {
		check();
		return lua_tablesize(index);
	}

	/**
	 * Moves the specified number of sequential elements in a table used as an
	 * array from one index to another.
	 * 
	 * <p>
	 * The method provides optimized performance over a Java implementation of
	 * the same functionality due to the reduced number of JNI transitions.
	 * </p>
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @param from
	 *            the index to move from
	 * @param to
	 *            the index to move to
	 * @param count
	 *            the number of elements to move
	 */
	public synchronized void tableMove(int index, int from, int to, int count) {
		check();
		lua_tablemove(index, from, to, count);
	}

	// -- Argument checking
	/**
	 * Checks if a condition is true for the specified function argument. If
	 * not, the method throws a Lua runtime exception with the specified error
	 * message.
	 * 
	 * @param index
	 *            the argument index
	 * @param condition
	 *            the condition
	 * @param msg
	 *            the error message
	 */
	public synchronized void checkArg(int index, boolean condition, String msg) {
		check();
		if (condition) {
			return;
		}
		throw getArgException(index, msg);
	}

	/**
	 * Checks if the value of the specified function argument is a boolean. If
	 * so, the argument value is returned as a boolean. Otherwise, the method
	 * throws a Lua runtime exception with a descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @return the boolean value, or the default value
	 */
	public synchronized boolean checkBoolean(int index) {
		check();
		if (!isBoolean(index)) {
			throw getArgTypeException(index, LuaType.BOOLEAN);
		}
		return toBoolean(index);
	}

	/**
	 * Checks if the value of the specified function argument is a boolean. If
	 * so, the argument value is returned as a boolean. If the value of the
	 * specified argument is undefined or <code>nil</code>, the method returns
	 * the specified default value. Otherwise, the method throws a Lua runtime
	 * exception with a descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @param d
	 *            the default value
	 * @return the boolean value
	 */
	public synchronized boolean checkBoolean(int index, boolean d) {
		check();
		if (isNoneOrNil(index)) {
			return d;
		}
		return checkBoolean(index);
	}

	/**
	 * Checks if the value of the specified function argument is a number or a
	 * string convertible to a number. If so, the argument value is returned as
	 * an integer. Otherwise, the method throws a Lua runtime exception with a
	 * descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @return the integer value
	 */
	public synchronized int checkInteger(int index) {
		check();
		if (!isNumber(index)) {
			throw getArgTypeException(index, LuaType.NUMBER);
		}
		return toInteger(index);
	}

	/**
	 * Checks if the value of the specified function argument is a number or a
	 * string convertible to a number. If so, the argument value is returned as
	 * an integer. If the value of the specified argument is undefined or
	 * <code>nil</code>, the method returns the specified default value.
	 * Otherwise, the method throws a Lua runtime exception with a descriptive
	 * error message.
	 * 
	 * @param index
	 *            the argument index
	 * @param d
	 *            the default value
	 * @return the integer value, or the default value
	 */
	public synchronized int checkInteger(int index, int d) {
		check();
		if (isNoneOrNil(index)) {
			return d;
		}
		return checkInteger(index);
	}

	/**
	 * Checks if the value of the specified function argument is a number or a
	 * string convertible to a number. If so, the argument value is returned as
	 * a number. Otherwise, the method throws a Lua runtime exception with a
	 * descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @return the number value
	 */
	public synchronized double checkNumber(int index) {
		check();
		if (!isNumber(index)) {
			throw getArgTypeException(index, LuaType.NUMBER);
		}
		return toNumber(index);
	}

	/**
	 * Checks if the value of the specified function argument is a number or a
	 * string convertible to a number. If so, the argument value is returned as
	 * a number. If the value of the specified argument is undefined or
	 * <code>nil</code>, the method returns the specified default value.
	 * Otherwise, the method throws a Lua runtime exception with a descriptive
	 * error message.
	 * 
	 * @param index
	 *            the argument index
	 * @param d
	 *            the default value
	 * @return the number value, or the default value
	 */
	public synchronized double checkNumber(int index, double d) {
		check();
		if (isNoneOrNil(index)) {
			return d;
		}
		return checkNumber(index);
	}

	/**
	 * Checks if the value of the specified function argument is convertible to
	 * a Java object of the specified type. If so, the argument value is
	 * returned as a Java object of the specified type. Otherwise, the method
	 * throws a Lua runtime exception with a descriptive error message.
	 * 
	 * <p>
	 * Note that the converter converts <code>nil</code> to <code>null</code>.
	 * Therefore, the method may return <code>null</code> if the value is
	 * <code>nil</code>.
	 * </p>
	 * 
	 * @param index
	 *            the argument index
	 * @param clazz
	 *            the expected type
	 * @return the Java object, or <code>null</code>
	 */
	public synchronized <T> T checkJavaObject(int index, Class<T> clazz) {
		check();
		if (!isJavaObject(index, clazz)) {
			throw getArgException(index, String.format("exptected %s, got %s",
					clazz.getCanonicalName(), typeName(index)));
		}
		return toJavaObject(index, clazz);
	}

	/**
	 * Checks if the value of the specified function argument is convertible to
	 * a Java object of the specified type. If so, the argument value is
	 * returned as a Java object of the specified type. If the value of the
	 * specified argument is undefined or <code>nil</code>, the method returns
	 * the specified default value. Otherwise, the method throws a Lua runtime
	 * exception with a descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @param clazz
	 *            the expected class
	 * @param d
	 *            the default value
	 * @return the Java object, or the default value
	 */
	public synchronized <T> T checkJavaObject(int index, Class<T> clazz, T d) {
		check();
		if (isNoneOrNil(index)) {
			return d;
		}
		return checkJavaObject(index, clazz);
	}

	/**
	 * Checks if the value of the specified function argument is a string or a
	 * number matching one of the specified options. If so, the argument value
	 * is returned as a string. Otherwise, the method throws a Lua runtime
	 * exception with a descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @param options
	 *            the options
	 * @return the string value
	 */
	public synchronized String checkOption(int index, String[] options) {
		check();
		String s = checkString(index);
		for (int i = 0; i < options.length; i++) {
			if (s.equals(options[i])) {
				return s;
			}
		}
		throw getArgException(index, String.format(
				"expected one of %s, got %s", Arrays.asList(options), s));
	}

	/**
	 * Checks if the value of the specified function argument is a string or a
	 * number matching one of the specified options. If so, argument value is
	 * returned as a string. If the value of the specified argument is undefined
	 * or <code>nil</code>, the method returns the specified default value.
	 * Otherwise, the method throws a Lua runtime exception with a descriptive
	 * error message.
	 * 
	 * @param index
	 *            the argument index
	 * @param options
	 *            the options
	 * @param d
	 *            the default value
	 * @return the string value, or the default value
	 */
	public synchronized String checkOption(int index, String[] options, String d) {
		check();
		if (isNoneOrNil(index)) {
			return d;
		}
		return checkOption(index, options);
	}

	/**
	 * Checks if the value of the specified function argument is a string or a
	 * number. If so, the argument value is returned as a string. Otherwise, the
	 * method throws a Lua runtime exception with a descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @return the string value
	 */
	public synchronized String checkString(int index) {
		check();
		if (!isString(index)) {
			throw getArgTypeException(index, LuaType.STRING);
		}
		return toString(index);
	}

	/**
	 * Checks if the value of the specified function argument is a string or a
	 * number. If so, the argument value is returned as a string. If the value
	 * of the specified argument is undefined or <code>nil</code>, the method
	 * returns the specified default value. Otherwise, the method throws a Lua
	 * runtime exception with a descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @param d
	 *            the default value
	 * @return the string value, or the default value
	 */
	public synchronized String checkString(int index, String d) {
		check();
		if (isNoneOrNil(index)) {
			return d;
		}
		return checkString(index);
	}

	/**
	 * Checks if the value of the specified function argument is of the
	 * specified type. If not, the method throws a Lua runtime exception with a
	 * descriptive error message.
	 * 
	 * @param index
	 *            the argument index
	 * @param type
	 *            the type
	 */
	public synchronized void checkType(int index, LuaType type) {
		check();
		if (type(index) != type) {
			throw getArgTypeException(index, type);
		}
	}

	// -- Proxy
	/**
	 * Returns a proxy object for the Lua value at the specified index.
	 * 
	 * @param index
	 *            the stack index containing the Lua value
	 * @return the Lua value proxy
	 */
	public synchronized LuaValueProxy getProxy(int index) {
		pushValue(index);
		return new LuaValueProxyImpl(ref(REGISTRYINDEX));
	}

	/**
	 * Returns a proxy object implementing the specified interface in Lua. The
	 * table at the specified stack index contains the method names from the
	 * interface as keys and the Lua functions implementing the interface
	 * methods as values. The returned object always implements the
	 * {@link LuaValueProxy} interface in addition to the specified interface.
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @param interfaze
	 *            the interface
	 * @return the proxy object
	 */
	@SuppressWarnings("unchecked")
	public synchronized <T> T getProxy(int index, Class<T> interfaze) {
		return (T) getProxy(index, new Class<?>[] { interfaze });
	}

	/**
	 * Returns a proxy object implementing the specified list of interfaces in
	 * Lua. The table at the specified stack index contains the method names
	 * from the interfaces as keys and the Lua functions implementing the
	 * interface methods as values. The returned object always implements the
	 * {@link LuaValueProxy} interface in addition to the specified interfaces.
	 * 
	 * @param index
	 *            the stack index containing the table
	 * @param interfaces
	 *            the interfaces
	 * @return the proxy object
	 */
	public synchronized LuaValueProxy getProxy(int index, Class<?>[] interfaces) {
		pushValue(index);
		if (!isTable(index)) {
			throw new IllegalArgumentException(String.format(
					"index %d is not a table", index));
		}
		Class<?>[] allInterfaces = new Class<?>[interfaces.length + 1];
		System.arraycopy(interfaces, 0, allInterfaces, 0, interfaces.length);
		allInterfaces[allInterfaces.length - 1] = LuaValueProxy.class;
		int reference = ref(REGISTRYINDEX);
		try {
			Object proxy = Proxy.newProxyInstance(classLoader, allInterfaces,
					new LuaInvocationHandler(reference));
			reference = -1;
			return (LuaValueProxy) proxy;
		} finally {
			if (reference >= 0) {
				unref(REGISTRYINDEX, reference);
			}
		}
	}

	// -- Private methods
	/**
	 * Returns whether this Lua state is open.
	 */
	private boolean isOpenInternal() {
		return luaState != 0L;
	}

	/**
	 * Closes this Lua state.
	 */
	private void closeInternal() {
		if (isOpenInternal()) {
			lua_close();
			if (isOpenInternal()) {
				throw new IllegalStateException("cannot close");
			}
		}
	}

	/**
	 * Checks this Lua state.
	 */
	private void check() {
		// Check open
		if (!isOpenInternal()) {
			throw new IllegalStateException("Lua state is closed");
		}

		// Check proxy queue
		LuaValueProxyRef luaValueProxyRef;
		while ((luaValueProxyRef = (LuaValueProxyRef) proxyQueue.poll()) != null) {
			proxySet.remove(luaValueProxyRef);
			lua_unref(REGISTRYINDEX, luaValueProxyRef.getReference());
		}
	}

	/**
	 * Creates a Lua runtime exception to indicate an argument type error.
	 */
	private LuaRuntimeException getArgTypeException(int index, LuaType type) {
		return getArgException(index, String
				.format("expected %s, got %s", type.toString().toLowerCase(),
						type(index).toString().toLowerCase()));
	}

	/**
	 * Creates a Lua runtime exception to indicate an argument error.
	 * 
	 * @param extraMsg
	 * @return
	 */
	private LuaRuntimeException getArgException(int index, String extraMsg) {
		check();
		String funcName = lua_funcname();
		index = lua_narg(index);
		String msg;
		String argument = index > 0 ? String.format("argument #%d", index)
				: "self argument";
		if (funcName != null) {
			msg = String.format("bad %s to '%s' (%s)", argument, funcName,
					extraMsg);
		} else {
			msg = String.format("bad %s (%s)", argument, extraMsg);
		}
		return new LuaRuntimeException(msg);
	}

	// -- Native methods
	private static native String lua_version();

	private native void lua_newstate(int apiversion);

	private native void lua_close();

	private native int lua_gc(int what, int data);

	private native void lua_openlib(int lib);

	private native void lua_load(InputStream inputStream, String chunkname)
			throws IOException;

	private native void lua_dump(OutputStream outputStream) throws IOException;

	private native void lua_pcall(int nargs, int nresults);

	private native void lua_getglobal(String name);

	private native void lua_setglobal(String name);

	private native void lua_pushboolean(int b);

	private native void lua_pushinteger(int n);

	private native void lua_pushjavafunction(JavaFunction f);

	private native void lua_pushjavaobject(Object object);

	private native void lua_pushnil();

	private native void lua_pushnumber(double n);

	private native void lua_pushstring(String s);

	private native int lua_isboolean(int index);

	private native int lua_iscfunction(int index);

	private native int lua_isfunction(int index);

	private native int lua_isjavafunction(int index);

	private native int lua_isjavaobject(int index);

	private native int lua_isnil(int index);

	private native int lua_isnone(int index);

	private native int lua_isnoneornil(int index);

	private native int lua_isnumber(int index);

	private native int lua_isstring(int index);

	private native int lua_istable(int index);

	private native int lua_isthread(int index);

	private native int lua_equal(int index1, int index2);

	private native int lua_lessthan(int index1, int index2);

	private native int lua_objlen(int index);

	private native int lua_rawequal(int index1, int index2);

	private native int lua_toboolean(int index);

	private native int lua_tointeger(int index);

	private native JavaFunction lua_tojavafunction(int index);

	private native Object lua_tojavaobject(int index);

	private native double lua_tonumber(int index);

	private native long lua_topointer(int index);

	private native String lua_tostring(int index);

	private native void lua_concat(int n);

	private native int lua_gettop();

	private native void lua_insert(int index);

	private native void lua_pop(int n);

	private native void lua_pushvalue(int index);

	private native void lua_remove(int index);

	private native void lua_replace(int index);

	private native void lua_settop(int index);

	private native int lua_type(int index);

	private native void lua_createtable(int narr, int nrec);

	private native String lua_findtable(int idx, String fname, int szhint);

	private native void lua_gettable(int index);

	private native void lua_getfield(int index, String k);

	private native void lua_newtable();

	private native int lua_next(int index);

	private native void lua_rawget(int index);

	private native void lua_rawgeti(int index, int n);

	private native void lua_rawset(int index);

	private native void lua_rawseti(int index, int n);

	private native void lua_settable(int index);

	private native void lua_setfield(int index, String k);

	private native int lua_getmetatable(int index);

	private native int lua_setmetatable(int index);

	private native int lua_getmetafield(int index, String k);

	private native void lua_getfenv(int index);

	private native int lua_setfenv(int index);

	private native void lua_newthread();

	private native int lua_resume(int index, int nargs);

	private native int lua_status(int index);

	private native int lua_yield(int nresults);

	private native int lua_ref(int index);

	private native void lua_unref(int index, int ref);

	private native int lua_tablesize(int index);

	private native void lua_tablemove(int index, int from, int to, int count);

	private native String lua_funcname();

	private native int lua_narg(int narg);

	// -- Enumerated types
	/**
	 * Represents a Lua library.
	 */
	public enum Library {
		/**
		 * The base library, including the coroutine functions.
		 */
		BASE,

		/**
		 * The table library.
		 */
		TABLE,

		/**
		 * The IO library.
		 */
		IO,

		/**
		 * The OS library.
		 */
		OS,

		/**
		 * The string library.
		 */
		STRING,

		/**
		 * The math library.
		 */
		MATH,

		/**
		 * The debug library.
		 */
		DEBUG,

		/**
		 * The package library.
		 */
		PACKAGE,

		/**
		 * The Java library.
		 */
		JAVA {
			@Override
			void open(LuaState luaState) {
				JavaModule.getInstance().open(luaState);
			}
		};

		// -- Methods
		/**
		 * Opens this library.
		 */
		void open(LuaState luaState) {
			luaState.lua_openlib(ordinal());
		}
	}

	/**
	 * Represents a Lua garbage collector action. See the Lua Reference Manual
	 * for an explanation of these actions.
	 */
	public enum GcAction {
		/**
		 * Stop.
		 */
		STOP,

		/**
		 * Restart.
		 */
		RESTART,

		/**
		 * Collect.
		 */
		COLLECT,

		/**
		 * Count memory in kilobytes.
		 */
		COUNT,

		/**
		 * Count reminder in bytes.
		 */
		COUNTB,

		/**
		 * Step.
		 */
		STEP,

		/**
		 * Set pause.
		 */
		SETPAUSE,

		/**
		 * Set step multiplier.
		 */
		SETSTEPMUL
	}

	// -- Nested types
	/**
	 * Phantom reference to a Lua value proxy for pre-mortem cleanup.
	 */
	private static class LuaValueProxyRef extends
			PhantomReference<LuaValueProxyImpl> {
		// -- State
		private int reference;

		// --Construction
		/**
		 * Creates a new instance.
		 */
		public LuaValueProxyRef(LuaValueProxyImpl luaProxyImpl, int reference) {
			super(luaProxyImpl, luaProxyImpl.getLuaState().proxyQueue);
			this.reference = reference;
		}

		// -- Properties
		/**
		 * Returns the reference.
		 */
		public int getReference() {
			return reference;
		}
	}

	/**
	 * Lua value proxy implementation.
	 */
	private class LuaValueProxyImpl implements LuaValueProxy {
		// -- State
		private int reference;

		// -- Construction
		/**
		 * Creates a new instance.
		 */
		public LuaValueProxyImpl(int reference) {
			this.reference = reference;
			proxySet.add(new LuaValueProxyRef(this, reference));
		}

		// -- LuaProxy methods
		@Override
		public LuaState getLuaState() {
			return LuaState.this;
		}

		@Override
		public void pushValue() {
			synchronized (LuaState.this) {
				rawGet(REGISTRYINDEX, reference);
			}
		}
	}

	/**
	 * Invocation handler for implementing Java interfaces in Lua.
	 */
	private class LuaInvocationHandler extends LuaValueProxyImpl implements
			InvocationHandler {
		// -- Construction
		/**
		 * Creates a new instance.
		 */
		public LuaInvocationHandler(int reference) {
			super(reference);
		}

		// -- InvocationHandler methods
		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			// Handle LuaProxy methods
			if (method.getDeclaringClass() == LuaValueProxy.class) {
				return method.invoke(this, args);
			}

			// Handle Lua calls
			synchronized (LuaState.this) {
				pushValue();
				getField(-1, method.getName());
				if (!isFunction(-1)) {
					pop(2);
					throw new UnsupportedOperationException(method.getName());
				}
				insert(-2);
				int argCount = args != null ? args.length : 0;
				for (int i = 0; i < argCount; i++) {
					pushJavaObject(args[i]);
				}
				int retCount = method.getReturnType() != Void.TYPE ? 1 : 0;
				call(argCount + 1, retCount);
				try {
					return retCount == 1 ? LuaState.this.toJavaObject(-1,
							method.getReturnType()) : null;
				} finally {
					if (retCount == 1) {
						pop(1);
					}
				}
			}
		}
	}
}