text:
namespace LuaInterface.Tests
{

    using System;
    using LuaInterface;
    using System.Threading;
    using System.Diagnostics;
    using System.Reflection;
    using SharpLua;

    /*
     * Delegates used for testing Lua function -> delegate translation
     */
    public delegate int TestDelegate1(int a, int b);
    public delegate int TestDelegate2(int a, out int b);
    public delegate void TestDelegate3(int a, ref int b);
    public delegate TestClass TestDelegate4(int a, int b);
    public delegate int TestDelegate5(TestClass a, TestClass b);
    public delegate int TestDelegate6(int a, out TestClass b);
    public delegate void TestDelegate7(int a, ref TestClass b);

    /*
     * Interface used for testing Lua table -> interface translation
     */
    public interface ITest
    {
        int intProp
        {
            get;
            set;
        }
        TestClass refProp
        {
            get;
            set;
        }
        int test1(int a, int b);
        int test2(int a, out int b);
        void test3(int a, ref int b);
        TestClass test4(int a, int b);
        int test5(TestClass a, TestClass b);
        int test6(int a, out TestClass b);
        void test7(int a, ref TestClass b);
    }

    public interface IFoo1
    {
        int foo();
    }

    public interface IFoo2
    {
        int foo();
    }

    class MyClass
    {
        public int Func1() { return 1; }
    }

    /// <summary>
    /// test structure passing
    /// </summary>
    public struct TestStruct
    {
        public TestStruct(float val)
        {
            v = val;
        }

        public float v;

        public float val
        {
            get { return v; }
            set { v = value; }
        }
    }

    /*
     * Sample class used in several test cases to check if
     * Lua scripts are accessing objects correctly
     */
    public class TestClass : IFoo1, IFoo2
    {
        public int val;
        private string strVal;
        public TestClass()
        {
            val = 0;
        }
        public TestClass(int val)
        {
            this.val = val;
        }
        public TestClass(string val)
        {
            this.strVal = val;
        }
        public static TestClass makeFromString(String str)
        {
            return new TestClass(str);
        }

        bool? nb2 = null;

        public bool? NullableBool
        {
            get { return nb2; }
            set { nb2 = value; }
        }

        TestStruct s = new TestStruct();

        public TestStruct Struct
        {
            get { return s; }
            set { s = (TestStruct)value; }
        }

        public int testval
        {
            get
            {
                return this.val;
            }
            set
            {
                this.val = value;
            }
        }
        public int this[int index]
        {
            get { return 1; }
            set { }
        }
        public int this[string index]
        {
            get { return 1; }
            set { }
        }
        public int sum(int x, int y)
        {
            return x + y;
        }
        public void setVal(int newVal)
        {
            val = newVal;
        }
        public void setVal(string newVal)
        {
            strVal = newVal;
        }
        public int getVal()
        {
            return val;
        }
        public string getStrVal()
        {
            return strVal;
        }
        public int outVal(out int val)
        {
            val = 5;
            return 3;
        }
        public int outVal(out int val, int val2)
        {
            val = 5;
            return val2;
        }
        public int outVal(int val, ref int val2)
        {
            val2 = val + val2;
            return val;
        }
        public int callDelegate1(TestDelegate1 del)
        {
            return del(2, 3);
        }
        public int callDelegate2(TestDelegate2 del)
        {
            int a = 3;
            int b = del(2, out a);
            return a + b;
        }
        public int callDelegate3(TestDelegate3 del)
        {
            int a = 3;
            del(2, ref a);
            //Console.WriteLine(a);
            return a;
        }
        public int callDelegate4(TestDelegate4 del)
        {
            return del(2, 3).testval;
        }
        public int callDelegate5(TestDelegate5 del)
        {
            return del(new TestClass(2), new TestClass(3));
        }
        public int callDelegate6(TestDelegate6 del)
        {
            TestClass test = new TestClass();
            int a = del(2, out test);
            return a + test.testval;
        }
        public int callDelegate7(TestDelegate7 del)
        {
            TestClass test = new TestClass(3);
            del(2, ref test);
            return test.testval;
        }
        public int callInterface1(ITest itest)
        {
            return itest.test1(2, 3);
        }
        public int callInterface2(ITest itest)
        {
            int a = 3;
            int b = itest.test2(2, out a);
            return a + b;
        }
        public int callInterface3(ITest itest)
        {
            int a = 3;
            itest.test3(2, ref a);
            //Console.WriteLine(a);
            return a;
        }
        public int callInterface4(ITest itest)
        {
            return itest.test4(2, 3).testval;
        }
        public int callInterface5(ITest itest)
        {
            return itest.test5(new TestClass(2), new TestClass(3));
        }
        public int callInterface6(ITest itest)
        {
            TestClass test = new TestClass();
            int a = itest.test6(2, out test);
            return a + test.testval;
        }
        public int callInterface7(ITest itest)
        {
            TestClass test = new TestClass(3);
            itest.test7(2, ref test);
            return test.testval;
        }
        public int callInterface8(ITest itest)
        {
            itest.intProp = 3;
            return itest.intProp;
        }
        public int callInterface9(ITest itest)
        {
            itest.refProp = new TestClass(3);
            return itest.refProp.testval;
        }
        public void exceptionMethod()
        {
            throw new Exception("exception test");
        }
        public virtual int overridableMethod(int x, int y)
        {
            return x + y;
        }
        public static int callOverridable(TestClass test, int x, int y)
        {
            return test.overridableMethod(x, y);
        }
        int IFoo1.foo()
        {
            return 3;
        }
        public int foo()
        {
            return 5;
        }
    }

    /*
     * Automated test cases for LuaInterface
     *
     * Author: Fabio Mascarenhas
     * Version: 1.0
     */
    public class TestLuaInterface
    {
        private LuaInterface lua;
        /*
         * Executed before each test case
         */
        public void Init()
        {
            lua = new LuaInterface();

            GC.Collect();  // runs GC to expose unprotected delegates
        }
        /*
         * Executed after each test case
         */
        public void Destroy()
        {
            lua = null;
        }

#if false
        // I've commented out the nunit based tests until they can run standalone - so that users don't need nunit to run TestLua

		/*
		 * Tests if DoString is correctly returning values
		 */
		[Test]
		public void DoString()
		{
			object[] res=lua.DoString("a=2\nreturn a,3");
			//Console.WriteLine("a="+res[0]+", b="+res[1]);
			Assertion.AssertEquals(res[0],2);
			Assertion.AssertEquals(res[1],3);
		}
		/*
		 * Tests getting of global numeric variables
		 */
		[Test]
		public void GetGlobalNumber()
		{
			lua.DoString("a=2");
			double num=lua.GetNumber("a");
			//Console.WriteLine("a="+num);
			Assertion.AssertEquals(num,2);
		}
		/*
		 * Tests setting of global numeric variables
		 */
		[Test]
		public void SetGlobalNumber()
		{
			lua.DoString("a=2");
			lua["a"]=3;
			double num=lua.GetNumber("a");
			//Console.WriteLine("a="+num);
			Assertion.AssertEquals(num,3);
		}
		/*
		 * Tests getting of numeric variables from tables
		 * by specifying variable path
		 */
		[Test]
		public void GetNumberInTable()
		{
			lua.DoString("a={b={c=2}}");
			double num=lua.GetNumber("a.b.c");
			//Console.WriteLine("a.b.c="+num);
			Assertion.AssertEquals(num,2);
		}
		/*
		 * Tests setting of numeric variables from tables
		 * by specifying variable path
		 */
		[Test]
		public void SetNumberInTable()
		{
			lua.DoString("a={b={c=2}}");
			lua["a.b.c"]=3;
			double num=lua.GetNumber("a.b.c");
			//Console.WriteLine("a.b.c="+num);
			Assertion.AssertEquals(num,3);
		}
		/*
		 * Tests getting of global string variables
		 */
		[Test]
		public void GetGlobalString()
		{
			lua.DoString("a=\"test\"");
			string str=lua.GetString("a");
			//Console.WriteLine("a="+str);
			Assertion.AssertEquals(str,"test");
		}
		/*
		 * Tests setting of global string variables
		 */
		[Test]
		public void SetGlobalString()
		{
			lua.DoString("a=\"test\"");
			lua["a"]="new test";
			string str=lua.GetString("a");
			//Console.WriteLine("a="+str);
			Assertion.AssertEquals(str,"new test");
		}
		/*
		 * Tests getting of string variables from tables
		 * by specifying variable path
		 */
		[Test]
		public void GetStringInTable()
		{
			lua.DoString("a={b={c=\"test\"}}");
			string str=lua.GetString("a.b.c");
			//Console.WriteLine("a.b.c="+str);
			Assertion.AssertEquals(str,"test");
		}
		/*
		 * Tests setting of string variables from tables
		 * by specifying variable path
		 */
		[Test]
		public void SetStringInTable()
		{
			lua.DoString("a={b={c=\"test\"}}");
			lua["a.b.c"]="new test";
			string str=lua.GetString("a.b.c");
			//Console.WriteLine("a.b.c="+str);
			Assertion.AssertEquals(str,"new test");
		}
		/*
		 * Tests getting and setting of global table variables
		 */
		[Test]
		public void GetAndSetTable()
		{
			lua.DoString("a={b={c=2}}\nb={c=3}");
			LuaTable tab=lua.GetTable("b");
			lua["a.b"]=tab;
			double num=lua.GetNumber("a.b.c");
			//Console.WriteLine("a.b.c="+num);
			Assertion.AssertEquals(num,3);
		}
		/*
		 * Tests getting of numeric field of a table
		 */
		[Test]
		public void GetTableNumericField1()
		{
			lua.DoString("a={b={c=2}}");
			LuaTable tab=lua.GetTable("a.b");
			double num=(double)tab["c"];
			//Console.WriteLine("a.b.c="+num);
			Assertion.AssertEquals(num,2);
		}
		/*
		 * Tests getting of numeric field of a table
		 * (the field is inside a subtable)
		 */
		[Test]
		public void GetTableNumericField2()
		{
			lua.DoString("a={b={c=2}}");
			LuaTable tab=lua.GetTable("a");
			double num=(double)tab["b.c"];
			//Console.WriteLine("a.b.c="+num);
			Assertion.AssertEquals(num,2);
		}
		/*
		 * Tests setting of numeric field of a table
		 */
		[Test]
		public void SetTableNumericField1()
		{
			lua.DoString("a={b={c=2}}");
			LuaTable tab=lua.GetTable("a.b");
			tab["c"]=3;
			double num=lua.GetNumber("a.b.c");
			//Console.WriteLine("a.b.c="+num);
			Assertion.AssertEquals(num,3);
		}
		/*
		 * Tests setting of numeric field of a table
		 * (the field is inside a subtable)
		 */
		[Test]
		public void SetTableNumericField2()
		{
			lua.DoString("a={b={c=2}}");
			LuaTable tab=lua.GetTable("a");
			tab["b.c"]=3;
			double num=lua.GetNumber("a.b.c");
			//Console.WriteLine("a.b.c="+num);
			Assertion.AssertEquals(num,3);
		}
		/*
		 * Tests getting of string field of a table
		 */
		[Test]
		public void GetTableStringField1()
		{
			lua.DoString("a={b={c=\"test\"}}");
			LuaTable tab=lua.GetTable("a.b");
			string str=(string)tab["c"];
			//Console.WriteLine("a.b.c="+str);
			Assertion.AssertEquals(str,"test");
		}
		/*
		 * Tests getting of string field of a table
		 * (the field is inside a subtable)
		 */
		[Test]
		public void GetTableStringField2()
		{
			lua.DoString("a={b={c=\"test\"}}");
			LuaTable tab=lua.GetTable("a");
			string str=(string)tab["b.c"];
			//Console.WriteLine("a.b.c="+str);
			Assertion.AssertEquals(str,"test");
		}
		/*
		 * Tests setting of string field of a table
		 */
		[Test]
		public void SetTableStringField1()
		{
			lua.DoString("a={b={c=\"test\"}}");
			LuaTable tab=lua.GetTable("a.b");
			tab["c"]="new test";
			string str=lua.GetString("a.b.c");
			//Console.WriteLine("a.b.c="+str);
			Assertion.AssertEquals(str,"new test");
		}
		/*
		 * Tests setting of string field of a table
		 * (the field is inside a subtable)
		 */
		[Test]
		public void SetTableStringField2()
		{
			lua.DoString("a={b={c=\"test\"}}");
			LuaTable tab=lua.GetTable("a");
			tab["b.c"]="new test";
			string str=lua.GetString("a.b.c");
			//Console.WriteLine("a.b.c="+str);
			Assertion.AssertEquals(str,"new test");
		}
		/*
		 * Tests calling of a global function with zero arguments
		 */
		[Test]
		public void CallGlobalFunctionNoArgs()
		{
			lua.DoString("a=2\nfunction f()\na=3\nend");
			lua.GetFunction("f").Call();
			double num=lua.GetNumber("a");
			//Console.WriteLine("a="+num);
			Assertion.AssertEquals(num,3);
		}
		/*
		 * Tests calling of a global function with one argument
		 */
		[Test]
		public void CallGlobalFunctionOneArg()
		{
			lua.DoString("a=2\nfunction f(x)\na=a+x\nend");
			lua.GetFunction("f").Call(1);
			double num=lua.GetNumber("a");
			//Console.WriteLine("a="+num);
			Assertion.AssertEquals(num,3);
		}
		/*
		 * Tests calling of a global function with two arguments
		 */
		[Test]
		public void CallGlobalFunctionTwoArgs()
		{
			lua.DoString("a=2\nfunction f(x,y)\na=x+y\nend");
			lua.GetFunction("f").Call(1,3);
			double num=lua.GetNumber("a");
			//Console.WriteLine("a="+num);
			Assertion.AssertEquals(num,4);
		}
		/*
		 * Tests calling of a global function that returns one value
		 */
		[Test]
		public void CallGlobalFunctionOneReturn()
		{
			lua.DoString("function f(x)\nreturn x+2\nend");
			object[] ret=lua.GetFunction("f").Call(3);
			//Console.WriteLine("ret="+ret[0]);
			Assertion.AssertEquals(1,ret.Length);
			Assertion.AssertEquals(5,ret[0]);
		}
		/*
		 * Tests calling of a global function that returns two values
		 */
		[Test]
		public void CallGlobalFunctionTwoReturns()
		{
			lua.DoString("function f(x,y)\nreturn x,x+y\nend");
			object[] ret=lua.GetFunction("f").Call(3,2);
			//Console.WriteLine("ret="+ret[0]+","+ret[1]);
			Assertion.AssertEquals(2,ret.Length);
			Assertion.AssertEquals(3,ret[0]);
			Assertion.AssertEquals(5,ret[1]);
		}
		/*
		 * Tests calling of a function inside a table
		 */
		[Test]
		public void CallTableFunctionTwoReturns()
		{
			lua.DoString("a={}\nfunction a.f(x,y)\nreturn x,x+y\nend");
			object[] ret=lua.GetFunction("a.f").Call(3,2);
			//Console.WriteLine("ret="+ret[0]+","+ret[1]);
			Assertion.AssertEquals(2,ret.Length);
			Assertion.AssertEquals(3,ret[0]);
			Assertion.AssertEquals(5,ret[1]);
		}
		/*
		 * Tests setting of a global variable to a CLR object value
		 */
		[Test]
		public void SetGlobalObject()
		{
			TestClass t1=new TestClass();
			t1.testval=4;
			lua["netobj"]=t1;
			object o=lua["netobj"];
			TestClass t2=(TestClass)lua["netobj"];
			Assertion.AssertEquals(t2.testval,4);
			Assertion.Assert(t1==t2);
		}
		/*
		 * Tests if CLR object is being correctly collected by Lua
		 */
		[Test]
		public void GarbageCollection()
		{
			TestClass t1=new TestClass();
			t1.testval=4;
			lua["netobj"]=t1;
			TestClass t2=(TestClass)lua["netobj"];
			Assertion.Assert(lua.translator.objects[0]!=null);
			lua.DoString("netobj=nil;collectgarbage();");
			Assertion.Assert(lua.translator.objects[0]==null);
		}
		/*
		 * Tests setting of a table field to a CLR object value
		 */
		[Test]
		public void SetTableObjectField1()
		{
			lua.DoString("a={b={c=\"test\"}}");
			LuaTable tab=lua.GetTable("a.b");
			TestClass t1=new TestClass();
			t1.testval=4;
			tab["c"]=t1;
			TestClass t2=(TestClass)lua["a.b.c"];
			//Console.WriteLine("a.b.c="+t2.testval);
			Assertion.AssertEquals(t2.testval,4);
			Assertion.Assert(t1==t2);
		}
		/*
		 * Tests reading and writing of an object's field
		 */
		[Test]
		public void AccessObjectField()
		{
			TestClass t1=new TestClass();
			t1.val=4;
			lua["netobj"]=t1;
			lua.DoString("var=netobj.val");
			double var=(double)lua["var"];
			//Console.WriteLine("value from Lua="+var);
			Assertion.AssertEquals(4,var);
			lua.DoString("netobj.val=3");
			Assertion.AssertEquals(3,t1.val);
			//Console.WriteLine("new val (from Lua)="+t1.val);
		}
		/*
		 * Tests reading and writing of an object's non-indexed
		 * property
		 */
		[Test]
		public void AccessObjectProperty()
		{
			TestClass t1=new TestClass();
			t1.testval=4;
			lua["netobj"]=t1;
			lua.DoString("var=netobj.testval");
			double var=(double)lua["var"];
			//Console.WriteLine("value from Lua="+var);
			Assertion.AssertEquals(4,var);
			lua.DoString("netobj.testval=3");
			Assertion.AssertEquals(3,t1.testval);
			//Console.WriteLine("new val (from Lua)="+t1.testval);
		}
		/*
		 * Tests calling of an object's method with no overloads
		 */
		[Test]
		public void CallObjectMethod()
		{
			TestClass t1=new TestClass();
			t1.testval=4;
			lua["netobj"]=t1;
			lua.DoString("netobj:setVal(3)");
			Assertion.AssertEquals(3,t1.testval);
			//Console.WriteLine("new val(from C#)="+t1.testval);
			lua.DoString("val=netobj:getVal()");
			int val=(int)lua.GetNumber("val");
			Assertion.AssertEquals(3,val);
			//Console.WriteLine("new val(from Lua)="+val);
		}
		/*
		 * Tests calling of an object's method with overloading
		 */
		[Test]
		public void CallObjectMethodByType()
		{
			TestClass t1=new TestClass();
			lua["netobj"]=t1;
			lua.DoString("netobj:setVal('str')");
			Assertion.AssertEquals("str",t1.getStrVal());
			//Console.WriteLine("new val(from C#)="+t1.getStrVal());
		}
		/*
		 * Tests calling of an object's method with no overloading
		 * and out parameters
		 */
		[Test]
		public void CallObjectMethodOutParam()
		{
			TestClass t1=new TestClass();
			lua["netobj"]=t1;
			lua.DoString("a,b=netobj:outVal()");
			int a=(int)lua.GetNumber("a");
			int b=(int)lua.GetNumber("b");
			Assertion.AssertEquals(3,a);
			Assertion.AssertEquals(5,b);
			//Console.WriteLine("function returned (from lua)="+a+","+b);
		}
		/*
		 * Tests calling of an object's method with overloading and
		 * out params
		 */
		[Test]
		public void CallObjectMethodOverloadedOutParam()
		{
			TestClass t1=new TestClass();
			lua["netobj"]=t1;
			lua.DoString("a,b=netobj:outVal(2)");
			int a=(int)lua.GetNumber("a");
			int b=(int)lua.GetNumber("b");
			Assertion.AssertEquals(2,a);
			Assertion.AssertEquals(5,b);
			//Console.WriteLine("function returned (from lua)="+a+","+b);
		}
		/*
		 * Tests calling of an object's method with ref params
		 */
		[Test]
		public void CallObjectMethodByRefParam()
		{
			TestClass t1=new TestClass();
			lua["netobj"]=t1;
			lua.DoString("a,b=netobj:outVal(2,3)");
			int a=(int)lua.GetNumber("a");
			int b=(int)lua.GetNumber("b");
			Assertion.AssertEquals(2,a);
			Assertion.AssertEquals(5,b);
			//Console.WriteLine("function returned (from lua)="+a+","+b);
		}
		/*
		 * Tests calling of two versions of an object's method that have
		 * the same name and signature but implement different interfaces
		 */
		[Test]
		public void CallObjectMethodDistinctInterfaces()
		{
			TestClass t1=new TestClass();
			lua["netobj"]=t1;
			lua.DoString("a=netobj:foo()");
			lua.DoString("b=netobj['LuaInterface.Tests.IFoo1.foo'](netobj)");
			int a=(int)lua.GetNumber("a");
			int b=(int)lua.GetNumber("b");
			Assertion.AssertEquals(5,a);
			Assertion.AssertEquals(3,b);
			//Console.WriteLine("function returned (from lua)="+a+","+b);
		}
		/*
		 * Tests instantiating an object with no-argument constructor
		 */
		[Test]
		public void CreateNetObjectNoArgsCons()
		{
			lua.DoString("load_assembly(\"SharpLua.InterfacingTests\")");
			lua.DoString("TestClass=import_type(\"LuaInterface.Tests.TestClass\")");
			lua.DoString("test=TestClass()");
			lua.DoString("test:setVal(3)");
			object[] res=lua.DoString("return test");
			TestClass test=(TestClass)res[0];
			//Console.WriteLine("returned: "+test.testval);
			Assertion.AssertEquals(3,test.testval);
		}
		/*
		 * Tests instantiating an object with one-argument constructor
		 */
		[Test]
		public void CreateNetObjectOneArgCons()
		{
			lua.DoString("load_assembly(\"SharpLua.InterfacingTests\")");
			lua.DoString("TestClass=import_type(\"LuaInterface.Tests.TestClass\")");
			lua.DoString("test=TestClass(3)");
			object[] res=lua.DoString("return test");
			TestClass test=(TestClass)res[0];
			//Console.WriteLine("returned: "+test.testval);
			Assertion.AssertEquals(3,test.testval);
		}
		/*
		 * Tests instantiating an object with overloaded constructor
		 */
		[Test]
		public void CreateNetObjectOverloadedCons()
		{
			lua.DoString("load_assembly(\"SharpLua.InterfacingTests\")");
			lua.DoString("TestClass=import_type(\"LuaInterface.Tests.TestClass\")");
			lua.DoString("test=TestClass('str')");
			object[] res=lua.DoString("return test");
			TestClass test=(TestClass)res[0];
			//Console.WriteLine("returned: "+test.getStrVal());
			Assertion.AssertEquals("str",test.getStrVal());
		}
		/*
		 * Tests getting item of a CLR array
		 */
		[Test]
		public void ReadArrayField()
		{
			string[] arr=new string[] { "str1", "str2", "str3" };
			lua["netobj"]=arr;
			lua.DoString("val=netobj[1]");
			string val=lua.GetString("val");
			Assertion.AssertEquals("str2",val);
			//Console.WriteLine("new val(from array to Lua)="+val);
		}
		/*
		 * Tests setting item of a CLR array
		 */
		[Test]
		public void WriteArrayField()
		{
			string[] arr=new string[] { "str1", "str2", "str3" };
			lua["netobj"]=arr;
			lua.DoString("netobj[1]='test'");
			Assertion.AssertEquals("test",arr[1]);
			//Console.WriteLine("new val(from Lua to array)="+arr[1]);
		}
		/*
		 * Tests creating a new CLR array
		 */
		[Test]
		public void CreateArray()
		{
			lua.DoString("load_assembly(\"SharpLua.InterfacingTests\")");
			lua.DoString("TestClass=import_type(\"LuaInterface.Tests.TestClass\")");
			lua.DoString("arr=TestClass[3]");
			lua.DoString("for i=0,2 do arr[i]=TestClass(i+1) end");
			TestClass[] arr=(TestClass[])lua["arr"];
			Assertion.AssertEquals(arr[1].testval,2);
		}
		/*
		 * Tests passing a Lua function to a delegate
		 * with value-type arguments
		 */
		[Test]
		public void LuaDelegateValueTypes()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("function func(x,y) return x+y; end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callDelegate1(func)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("delegate returned: "+a);
		}
		/*
		 * Tests passing a Lua function to a delegate
		 * with value-type arguments and out params
		 */
		[Test]
		public void LuaDelegateValueTypesOutParam()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("function func(x) return x,x*2; end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callDelegate2(func)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(6,a);
			//Console.WriteLine("delegate returned: "+a);
		}
		/*
		 * Tests passing a Lua function to a delegate
		 * with value-type arguments and ref params
		 */
		[Test]
		public void LuaDelegateValueTypesByRefParam()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("function func(x,y) return x+y; end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callDelegate3(func)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("delegate returned: "+a);
		}
		/*
		 * Tests passing a Lua function to a delegate
		 * with value-type arguments that returns a reference type
		 */
		[Test]
		public void LuaDelegateValueTypesReturnReferenceType()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("function func(x,y) return TestClass(x+y); end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callDelegate4(func)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("delegate returned: "+a);
		}
		/*
		 * Tests passing a Lua function to a delegate
		 * with reference type arguments
		 */
		[Test]
		public void LuaDelegateReferenceTypes()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("function func(x,y) return x.testval+y.testval; end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callDelegate5(func)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("delegate returned: "+a);
		}
		/*
		 * Tests passing a Lua function to a delegate
		 * with reference type arguments and an out param
		 */
		[Test]
		public void LuaDelegateReferenceTypesOutParam()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("function func(x) return x,TestClass(x*2); end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callDelegate6(func)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(6,a);
			//Console.WriteLine("delegate returned: "+a);
		}
		/*
		 * Tests passing a Lua function to a delegate
		 * with reference type arguments and a ref param
		 */
		[Test]
		public void LuaDelegateReferenceTypesByRefParam()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("function func(x,y) return TestClass(x+y.testval); end");
			lua.DoString("a=test:callDelegate7(func)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("delegate returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * calling one of its methods with value-type params
		 */
		[Test]
		public void LuaInterfaceValueTypes()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:test1(x,y) return x+y; end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callInterface1(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * calling one of its methods with value-type params
		 * and an out param
		 */
		[Test]
		public void LuaInterfaceValueTypesOutParam()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:test2(x) return x,x*2; end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callInterface2(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(6,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * calling one of its methods with value-type params
		 * and a ref param
		 */
		[Test]
		public void LuaInterfaceValueTypesByRefParam()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:test3(x,y) return x+y; end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callInterface3(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * calling one of its methods with value-type params
		 * returning a reference type param
		 */
		[Test]
		public void LuaInterfaceValueTypesReturnReferenceType()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:test4(x,y) return TestClass(x+y); end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callInterface4(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * calling one of its methods with reference type params
		 */
		[Test]
		public void LuaInterfaceReferenceTypes()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:test5(x,y) return x.testval+y.testval; end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callInterface5(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * calling one of its methods with reference type params
		 * and an out param
		 */
		[Test]
		public void LuaInterfaceReferenceTypesOutParam()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:test6(x) return x,TestClass(x*2); end");
			lua.DoString("test=TestClass()");
			lua.DoString("a=test:callInterface6(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(6,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * calling one of its methods with reference type params
		 * and a ref param
		 */
		[Test]
		public void LuaInterfaceReferenceTypesByRefParam()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:test7(x,y) return TestClass(x+y.testval); end");
			lua.DoString("a=test:callInterface7(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(5,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * accessing one of its value-type properties
		 */
		[Test]
		public void LuaInterfaceValueProperty()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:get_intProp() return itest.int_prop; end");
			lua.DoString("function itest:set_intProp(val) itest.int_prop=val; end");
			lua.DoString("a=test:callInterface8(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(3,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests passing a Lua table as an interface and
		 * accessing one of its reference type properties
		 */
		[Test]
		public void LuaInterfaceReferenceProperty()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("itest={}");
			lua.DoString("function itest:get_refProp() return TestClass(itest.int_prop); end");
			lua.DoString("function itest:set_refProp(val) itest.int_prop=val.testval; end");
			lua.DoString("a=test:callInterface9(itest)");
			int a=(int)lua.GetNumber("a");
			Assertion.AssertEquals(3,a);
			//Console.WriteLine("interface returned: "+a);
		}

		/*
		 * Tests making an object from a Lua table and calling the base
		 * class version of one of the methods the table overrides.
		 */
		[Test]
		public void LuaTableBaseMethod()
		{
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test={}");
			lua.DoString("function test:overridableMethod(x,y) return 2*self.base:overridableMethod(x,y); end");
			lua.DoString("make_object(test,'LuaInterface.Tests.TestClass')");
			lua.DoString("a=TestClass:callOverridable(test,2,3)");
			int a=(int)lua.GetNumber("a");
			lua.DoString("free_object(test)");
			Assertion.AssertEquals(10,a);
			//Console.WriteLine("interface returned: "+a);
		}
		/*
		 * Tests getting an object's method by its signature
		 * (from object)
		 */
		[Test]
		public void GetMethodBySignatureFromObj()
		{
			lua.DoString("load_assembly('mscorlib')");
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("setMethod=get_method_bysig(test,'setVal','System.String')");
			lua.DoString("setMethod('test')");
			TestClass test=(TestClass)lua["test"];
			Assertion.AssertEquals("test",test.getStrVal());
			//Console.WriteLine("interface returned: "+test.getStrVal());
		}
		/*
		 * Tests getting an object's method by its signature
		 * (from type)
		 */
		[Test]
		public void GetMethodBySignatureFromType()
		{
			lua.DoString("load_assembly('mscorlib')");
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test=TestClass()");
			lua.DoString("setMethod=get_method_bysig(TestClass,'setVal','System.String')");
			lua.DoString("setMethod(test,'test')");
			TestClass test=(TestClass)lua["test"];
			Assertion.AssertEquals("test",test.getStrVal());
			//Console.WriteLine("interface returned: "+test.getStrVal());
		}
		/*
		 * Tests getting a type's method by its signature
		 */
		[Test]
		public void GetStaticMethodBySignature()
		{
			lua.DoString("load_assembly('mscorlib')");
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("make_method=get_method_bysig(TestClass,'makeFromString','System.String')");
			lua.DoString("test=make_method('test')");
			TestClass test=(TestClass)lua["test"];
			Assertion.AssertEquals("test",test.getStrVal());
			//Console.WriteLine("interface returned: "+test.getStrVal());
		}
		/*
		 * Tests getting an object's constructor by its signature
		 */
		[Test]
		public void GetConstructorBySignature()
		{
			lua.DoString("load_assembly('mscorlib')");
			lua.DoString("load_assembly('SharpLua.InterfacingTests')");
			lua.DoString("TestClass=import_type('LuaInterface.Tests.TestClass')");
			lua.DoString("test_cons=get_constructor_bysig(TestClass,'System.String')");
			lua.DoString("test=test_cons('test')");
			TestClass test=(TestClass)lua["test"];
			Assertion.AssertEquals("test",test.getStrVal());
			//Console.WriteLine("interface returned: "+test.getStrVal());
		}
#endif

        void TestOk(bool flag)
        {
            if (flag)
                Console.WriteLine("Test Passed.");
            else
                Console.WriteLine("Test Failed!!!!");
        }

        /*
         * Tests capturing an exception
         */
        public void ThrowException()
        {
            Init();

            lua.DoString("luanet.load_assembly('mscorlib')");
            lua.DoString("luanet.load_assembly('SharpLua.InterfacingTests')");
            lua.DoString("TestClass=luanet.import_type('LuaInterface.Tests.TestClass')");
            lua.DoString("test=TestClass()");
            lua.DoString("err,errMsg=pcall(test.exceptionMethod,test)");
            bool err = (bool)lua["err"];
            Exception errMsg = (Exception)lua["errMsg"];
            TestOk(!err);
            TestOk("exception test" == errMsg.Message);
            //Console.WriteLine("interface returned: "+errMsg.ToString());

            Destroy();
        }

        /*
         * Tests capturing an exception
         */
        public void ThrowUncaughtException()
        {
            Init();

            lua.DoString("luanet.load_assembly('mscorlib')");
            lua.DoString("luanet.load_assembly('SharpLua.InterfacingTests')");
            lua.DoString("TestClass=luanet.import_type('LuaInterface.Tests.TestClass')");
            lua.DoString("test=TestClass()");

            try
            {
                lua.DoString("test:exceptionMethod()");

                Console.WriteLine("Test failed!!! Should have thrown an exception all the way out of Lua");
            }
            catch (Exception)
            {
                Console.WriteLine("Uncaught exception success");
            }

            Destroy();
        }

        /*
         * Tests nullable fields
         */
        public void TestNullable()
        {
            Init();

            lua.DoString("luanet.load_assembly('mscorlib')");
            lua.DoString("luanet.load_assembly('SharpLua.InterfacingTests')");
            lua.DoString("TestClass=luanet.import_type('LuaInterface.Tests.TestClass')");
            lua.DoString("test=TestClass()");

            lua.DoString("val=test.NullableBool");
            TestOk(((object)lua["val"]) == null);
            lua.DoString("test.NullableBool = true");
            lua.DoString("val=test.NullableBool");
            TestOk(((bool)lua["val"]) == true);

            Destroy();
        }

        /*
         * Tests structure assignment
         */
        public void TestStructs()
        {
            Init();

            lua.DoString("luanet.load_assembly('SharpLua.InterfacingTests')");
            lua.DoString("TestClass=luanet.import_type('LuaInterface.Tests.TestClass')");
            lua.DoString("test=TestClass()");
            lua.DoString("TestStruct=luanet.import_type('LuaInterface.Tests.TestStruct')");

            lua.DoString("struct=TestStruct(2)");
            lua.DoString("test.Struct = struct");
            lua.DoString("val=test.Struct.val");
            TestOk(((double)lua["val"]) == 2.0);

            Destroy();
        }

        /*
         * Tests functions
         */
        public void TestFunctions()
        {
            Init();

            lua.DoString("luanet.load_assembly('mscorlib')");
            lua.DoString("luanet.load_assembly('SharpLua.InterfacingTests')");
            lua.RegisterFunction("p", null, typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(String) }));

            /// Lua command that works (prints to console)
            lua.DoString("p('Foo')");

            /// Yet this works...
            lua.DoString("string.gsub('some string', '(%w+)', function(s) p(s) end)");

            /// This fails if you don't fix Lua5.1 lstrlib.c/add_value to treat LUA_TUSERDATA the same as LUA_FUNCTION
            //  lua.DoString("string.gsub('some string', '(%w+)', p)");

            Destroy();
        }

        /*
         * Tests making an object from a Lua table and calling one of
         * methods the table overrides.
         */
        public void LuaTableOverridedMethod()
        {
            Init();

            lua.DoString("luanet.load_assembly('SharpLua.InterfacingTests')");
            lua.DoString("TestClass=luanet.import_type('LuaInterface.Tests.TestClass')");
            lua.DoString("test={}");
            lua.DoString("function test:overridableMethod(x,y) return x*y; end");
            lua.DoString("luanet.make_object(test,'LuaInterface.Tests.TestClass')");
            lua.DoString("a=TestClass.callOverridable(test,2,3)");
            int a = (int)lua.GetNumber("a");
            lua.DoString("luanet.free_object(test)");
            TestOk(6 == a);
            //Console.WriteLine("interface returned: "+a);
        }

        /*
         * Tests making an object from a Lua table and calling a method
         * the table does not override.
         */
        public void LuaTableInheritedMethod()
        {
            Init();

            lua.DoString("luanet.load_assembly('SharpLua.InterfacingTests')");
            lua.DoString("TestClass=luanet.import_type('LuaInterface.Tests.TestClass')");
            lua.DoString("test={}");
            lua.DoString("function test:overridableMethod(x,y) return x*y; end");
            lua.DoString("luanet.make_object(test,'LuaInterface.Tests.TestClass')");
            lua.DoString("test:setVal(3)");
            lua.DoString("a=test.testval");
            int a = (int)lua.GetNumber("a");
            lua.DoString("luanet.free_object(test)");
            TestOk(3 == a);
            //Console.WriteLine("interface returned: "+a);
        }

        /// <summary>
        /// Basic multiply method which expects 2 floats
        /// </summary>
        /// <param name="val"></param>
        /// <param name="val2"></param>
        /// <returns></returns>
        private float _TestException(float val, float val2)
        {
            return val * val2;
        }

        public void TestEventException()
        {
            Init();

            //Register a C# function
            MethodInfo testException = this.GetType().GetMethod("_TestException", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance, null, new Type[] { typeof(float), typeof(float) }, null);
            lua.RegisterFunction("Multiply", this, testException);

            //create the lua event handler code for the entity
            //includes the bad code!
            lua.DoString("function OnClick(sender, eventArgs)\r\n" +
                          "--Multiply expects 2 floats, but instead receives 2 strings\r\n" +
                          "Multiply(asd, we)\r\n" +
                        "end");

            //create the lua event handler code for the entity
            //good code
            //lua.DoString("function OnClick(sender, eventArgs)\r\n" +
            //              "--Multiply expects 2 floats\r\n" +
            //              "Multiply(2, 50)\r\n" +
            //            "end");

            //Create the event handler script
            lua.DoString("function SubscribeEntity(e)\r\ne.Clicked:Add(OnClick)\r\nend");

            //Create the entity object
            Entity entity = new Entity();

            //Register the entity object with the event handler inside lua
            LuaFunction lf = lua.GetFunction("SubscribeEntity");
            lf.Call(new object[1] { entity });

            try
            {
                //Cause the event to be fired
                entity.Click();

                Console.WriteLine("Test failed!!! Should have thrown an exception all the way out of Lua");
            }
            catch (LuaException)
            {
                Console.WriteLine("Event exception success");
            }

        }

        public static int func(int x, int y)
        {
            return x + y;
        }
        public int funcInstance(int x, int y)
        {
            return x + y;
        }

        public void RegisterFunctionStressTest()
        {
            LuaFunction fc = null;
            const int Count = 200;  // it seems to work with 41

            Init();

            MyClass t = new MyClass();

            for (int i = 1; i < Count - 1; ++i)
            {
                fc = lua.RegisterFunction("func" + i, t, typeof(MyClass).GetMethod("Func1"));
            }
            fc = lua.RegisterFunction("func" + (Count - 1), t, typeof(MyClass).GetMethod("Func1"));

            lua.DoString("print(func1())");
        }

        /*
         * Sample test script that shows some of the capabilities of
         * LuaInterface
         */
        public static void Main()
        {
            Console.WriteLine("Starting interpreter...");
            LuaInterface l = new LuaInterface();

            // Pause so we can connect with the debugger
            // Thread.Sleep(30000);

            Console.WriteLine("Reading test.lua file...");
            l.DoFile("test.lua");
            double width = l.GetNumber("width");
            double height = l.GetNumber("height");
            string message = l.GetString("message");
            double color_r = l.GetNumber("color.r");
            double color_g = l.GetNumber("color.g");
            double color_b = l.GetNumber("color.b");
            Console.WriteLine("Printing values of global variables width, height and message...");
            Console.WriteLine("width: " + width);
            Console.WriteLine("height: " + height);
            Console.WriteLine("message: " + message);
            Console.WriteLine("Printing values of the 'color' table's fields...");
            Console.WriteLine("color.r: " + color_r);
            Console.WriteLine("color.g: " + color_g);
            Console.WriteLine("color.b: " + color_b);
            width = 150;
            Console.WriteLine("Changing width's value and calling Lua function print to show it...");
            l["width"] = width;
            l.GetFunction("print").Call(width);
            message = "LuaNet Interface Test";
            Console.WriteLine("Changing message's value and calling Lua function print to show it...");
            l["message"] = message;
            l.GetFunction("print").Call(message);
            color_r = 30;
            color_g = 10;
            color_b = 200;
            Console.WriteLine("Changing color's fields' values and calling Lua function print to show it...");
            l["color.r"] = color_r;
            l["color.g"] = color_g;
            l["color.b"] = color_b;
            l.DoString("print(color.r,color.g,color.b)");
            Console.WriteLine("Printing values of the tree table's fields...");
            double leaf1 = l.GetNumber("tree.branch1.leaf1");
            string leaf2 = l.GetString("tree.branch1.leaf2");
            string leaf3 = l.GetString("tree.leaf3");
            Console.WriteLine("leaf1: " + leaf1);
            Console.WriteLine("leaf2: " + leaf2);
            Console.WriteLine("leaf3: " + leaf3);
            leaf1 = 30; leaf2 = "new leaf2";
            Console.WriteLine("Changing tree's fields' values and calling Lua function print to show it...");
            l["tree.branch1.leaf1"] = leaf1; l["tree.branch1.leaf2"] = leaf2;
            l.DoString("print(tree.branch1.leaf1,tree.branch1.leaf2)");
            Console.WriteLine("Returning values from Lua with 'return'...");
            object[] vals = l.DoString("return 2,3");
            Console.WriteLine("Returned: " + vals[0] + " and " + vals[1]);
            Console.WriteLine("Calling a Lua function that returns multiple values...");
            object[] vals1 = l.GetFunction("func").Call(2, 3);
            Console.WriteLine("Returned: " + vals1[0] + " and " + vals1[1]);
            Console.WriteLine("Creating a table and filling it from C#...");
            l.NewTable("tab");
            l.NewTable("tab.tab");
            l["tab.a"] = "a!";
            l["tab.b"] = 5.5;
            l["tab.tab.c"] = 6.5;
            l.DoString("print(tab.a,tab.b,tab.tab.c)");
            Console.WriteLine("Setting a table as another table's field...");
            l["tab.a"] = l["tab.tab"];
            l.DoString("print(tab.a.c)");
            Console.WriteLine("Registering a C# static method and calling it from Lua...");

            // Pause so we can connect with the debugger
            // Thread.Sleep(30000);

            l.RegisterFunction("func1", null, typeof(TestLuaInterface).GetMethod("func"));
            vals1 = l.GetFunction("func1").Call(2, 3);
            Console.WriteLine("Returned: " + vals1[0]);
            TestLuaInterface obj = new TestLuaInterface();
            Console.WriteLine("Registering a C# instance method and calling it from Lua...");
            l.RegisterFunction("func2", obj, typeof(TestLuaInterface).GetMethod("funcInstance"));
            vals1 = l.GetFunction("func2").Call(2, 3);
            Console.WriteLine("Returned: " + vals1[0]);

            Console.WriteLine("Testing throwing an exception...");
            obj.ThrowUncaughtException();

            Console.WriteLine("Testing catching an exception...");
            obj.ThrowException();

            Console.WriteLine("Testing inheriting a method from Lua...");
            obj.LuaTableInheritedMethod();

            Console.WriteLine("Testing overriding a C# method with Lua...");
            obj.LuaTableOverridedMethod();

            Console.WriteLine("Stress test RegisterFunction (based on a reported bug)..");
            obj.RegisterFunctionStressTest();

            Console.WriteLine("Test structures...");
            obj.TestStructs();

            Console.WriteLine("Test Nullable types...");
            obj.TestNullable();

            Console.WriteLine("Test functions...");
            obj.TestFunctions();

            Console.WriteLine("Test event exceptions...");
            obj.TestEventException();

            Console.Write("Press any key to continue...");
            Console.ReadKey(true);
            //Console.ReadLine();
        }
    }

}


text:
using System;

namespace TCC2.API.Filesystem
{
    public sealed partial class DirResult : IApiCallResult
    {
        const string FileDoesNotExist = "FILE_DOES_NOT_EXIST";

        bool m_Success;
        string m_ErrorId;
        string m_Message;
        IDirBaseEntry m_Content;

        internal DirResult(SerializableDirResult dirResult)
        {
            if (dirResult == null)
                throw new ArgumentNullException("dirResult");

            m_Success = dirResult.Success;
            m_ErrorId = dirResult.ErrorId;
            m_Message = dirResult.Message;

            if (dirResult.ErrorId == FileDoesNotExist)
                Exists = false;
            else
            {
                m_Content = GetContent(dirResult);
                Exists = true;
            }
        }

        public bool Exists { get; private set; }

        public IDirBaseEntry Content
        {
            get
            {
                if (!Exists)
                    throw new InvalidOperationException("File does not exist");

                if (m_Content == null)
                    throw new InvalidOperationException("Entry has invalid format");

                return m_Content;
            }
        }

        public IDirFile ContentAsFile
        {
            get { return Content as IDirFile; }
        }

        public IDirFolder ContentAsFolder
        {
            get { return Content as IDirFolder; }
        }

        static IDirBaseEntry GetContent(SerializableDirResult dirResult)
        {
            if (dirResult.IsValidFile)
                return new FileEntry(dirResult.Entries[0]);

            if (dirResult.IsValidFolder)
                return new FolderEntry(dirResult);

            return null;
        }

        void IApiCallResult.Validate(IRequestDataProvider provider)
        {
            if (Exists)
            {
                ApiCallResult.Validate(provider, m_Success, m_ErrorId, m_Message);
                if (m_Content == null)
                    throw new TccException("Entry has invalid format", true);
            }
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.CodeAnalysis.Sarif;
using Microsoft.Sarif.Viewer.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Sarif.Viewer.Sarif
{
    static class CodeFlowExtensions
    {
        public static AnnotatedCodeLocationCollection ToAnnotatedCodeLocationCollection(this CodeFlow codeFlow)
        {
            if (codeFlow == null)
            {
                return null;
            }

            AnnotatedCodeLocationCollection model = new AnnotatedCodeLocationCollection(codeFlow.Message);

            if (codeFlow.Locations != null)
            {
                foreach (AnnotatedCodeLocation location in codeFlow.Locations)
                {
                    // TODO we are not yet properly hardened against locationless
                    // code locations (and what this means is also in flux as
                    // far as SARIF producers). For now we skip these.
                    if (location.PhysicalLocation == null) { continue; }

                    model.Add(location.ToAnnotatedCodeLocationModel());
                }
            }

            return model;
        }
    }
}


text:
#include "config.h"

#include "core/inspector/WorkerInspectorController.h"

#include "InspectorBackendDispatcher.h"
#include "InspectorFrontend.h"
#include "core/inspector/InjectedScriptHost.h"
#include "core/inspector/InjectedScriptManager.h"
#include "core/inspector/InspectorConsoleAgent.h"
#include "core/inspector/InspectorFrontendChannel.h"
#include "core/inspector/InspectorHeapProfilerAgent.h"
#include "core/inspector/InspectorProfilerAgent.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InspectorStateClient.h"
#include "core/inspector/InspectorTimelineAgent.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/inspector/WorkerConsoleAgent.h"
#include "core/inspector/WorkerDebuggerAgent.h"
#include "core/inspector/WorkerRuntimeAgent.h"
#include "core/workers/WorkerContext.h"
#include "core/workers/WorkerReportingProxy.h"
#include "core/workers/WorkerThread.h"
#include <wtf/PassOwnPtr.h>

namespace WebCore {

namespace {

class PageInspectorProxy : public InspectorFrontendChannel {
    WTF_MAKE_FAST_ALLOCATED;
public:
    explicit PageInspectorProxy(WorkerContext* workerContext) : m_workerContext(workerContext) { }
    virtual ~PageInspectorProxy() { }
private:
    virtual bool sendMessageToFrontend(const String& message)
    {
        m_workerContext->thread()->workerReportingProxy().postMessageToPageInspector(message);
        return true;
    }
    WorkerContext* m_workerContext;
};

class WorkerStateClient : public InspectorStateClient {
    WTF_MAKE_FAST_ALLOCATED;
public:
    WorkerStateClient(WorkerContext* context) : m_workerContext(context) { }
    virtual ~WorkerStateClient() { }

private:
    virtual void updateInspectorStateCookie(const String& cookie)
    {
        m_workerContext->thread()->workerReportingProxy().updateInspectorStateCookie(cookie);
    }

    WorkerContext* m_workerContext;
};

}

WorkerInspectorController::WorkerInspectorController(WorkerContext* workerContext)
    : m_workerContext(workerContext)
    , m_stateClient(adoptPtr(new WorkerStateClient(workerContext)))
    , m_state(adoptPtr(new InspectorCompositeState(m_stateClient.get())))
    , m_instrumentingAgents(InstrumentingAgents::create())
    , m_injectedScriptManager(InjectedScriptManager::createForWorker())
    , m_debugServer(adoptPtr(new WorkerScriptDebugServer(workerContext, WorkerDebuggerAgent::debuggerTaskMode)))
{
    m_agents.append(WorkerRuntimeAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get(), m_debugServer.get(), workerContext));

    OwnPtr<InspectorConsoleAgent> consoleAgent = WorkerConsoleAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get());
    m_agents.append(WorkerDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), m_debugServer.get(), workerContext, m_injectedScriptManager.get()));

    m_agents.append(InspectorProfilerAgent::create(m_instrumentingAgents.get(), consoleAgent.get(), m_state.get(), m_injectedScriptManager.get()));
    m_agents.append(InspectorHeapProfilerAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get()));
    m_agents.append(InspectorTimelineAgent::create(m_instrumentingAgents.get(), 0, 0, 0, m_state.get(), InspectorTimelineAgent::WorkerInspector, 0));
    m_agents.append(consoleAgent.release());

    m_injectedScriptManager->injectedScriptHost()->init(m_instrumentingAgents.get(), m_debugServer.get());
}

WorkerInspectorController::~WorkerInspectorController()
{
    m_instrumentingAgents->reset();
    disconnectFrontend();
}

void WorkerInspectorController::connectFrontend()
{
    ASSERT(!m_frontend);
    m_state->unmute();
    m_frontendChannel = adoptPtr(new PageInspectorProxy(m_workerContext));
    m_frontend = adoptPtr(new InspectorFrontend(m_frontendChannel.get()));
    m_backendDispatcher = InspectorBackendDispatcher::create(m_frontendChannel.get());
    m_agents.registerInDispatcher(m_backendDispatcher.get());
    m_agents.setFrontend(m_frontend.get());
}

void WorkerInspectorController::disconnectFrontend()
{
    if (!m_frontend)
        return;
    m_backendDispatcher->clearFrontend();
    m_backendDispatcher.clear();
    // Destroying agents would change the state, but we don't want that.
    // Pre-disconnect state will be used to restore inspector agents.
    m_state->mute();
    m_agents.clearFrontend();
    m_frontend.clear();
    m_frontendChannel.clear();
}

void WorkerInspectorController::restoreInspectorStateFromCookie(const String& inspectorCookie)
{
    ASSERT(!m_frontend);
    connectFrontend();
    m_state->loadFromCookie(inspectorCookie);

    m_agents.restore();
}

void WorkerInspectorController::dispatchMessageFromFrontend(const String& message)
{
    if (m_backendDispatcher)
        m_backendDispatcher->dispatch(message);
}

void WorkerInspectorController::resume()
{
    if (WorkerRuntimeAgent* runtimeAgent = m_instrumentingAgents->workerRuntimeAgent()) {
        ErrorString unused;
        runtimeAgent->run(&unused);
    }
}

}


text:
<?php

namespace tecnocen\fullcalendar\widgets;

use tecnocen\fullcalendar\assets\Lang as LangAsset;
use Yii;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Json;

/**
 * @author Angel (Faryshta) Guevara <aguevara@tecnocen.com>
 */
class Fullcalendar extends \yii\base\Widget
{
    /**
     * @var string the locale ID (e.g. 'fr', 'de', 'en-GB') for the language to
     * be used by the date picker. If this property is empty, then the current
     * application language will be used.
     */
    public $lang;

    /**
     * @var array the HTML attributes for the widget container tag.
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $options = [];

    /**
     * @var array the options for the underlying Bootstrap JS plugin.
     * Please refer to http://fullcalendar.io Web page for possible options.
     */
    public $clientOptions = [];

    /**
     * @var array the event handlers for the underlying Bootstrap JS plugin.
     * Please refer to http://fullcalendar.io Web page for possible events.
     */
    public $clientEvents = [];

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();
        if (!isset($this->options['id'])) {
            $this->options['id'] = $this->getId();
        }
    }

    /**
     * Registers a specific Bootstrap plugin and the related events
     * @param string $name the name of the Bootstrap plugin
     */
    protected function registerPlugin($name)
    {
        $view = $this->getView();
        $id = $this->options['id'];
        if ($this->clientOptions !== false) {
            $options = empty($this->clientOptions) ? '' : Json::htmlEncode($this->clientOptions);
            $js = "jQuery('#$id').$name($options);";
            $view->registerJs($js);
        }
        $this->registerClientEvents();
    }

    /**
     * Registers JS event handlers that are listed in [[clientEvents]].
     * @since 2.0.2
     */
    protected function registerClientEvents()
    {
        if (!empty($this->clientEvents)) {
            $id = $this->options['id'];
            $js = '';
            foreach ($this->clientEvents as $event => $handler) {
                $js .= "jQuery('#$id').on('$event', $handler);";
            }
            $this->getView()->registerJs($js);
        }
    }

    /**
     * @inheritdoc
     */
    public function run()
    {
        $lang = $this->lang
            ? $this->lang
            : strtolower(Yii::$app->language);

        $assetBundle = LangAsset::register($this->getView());
        $assetBundle->lang = $lang;
        $this->clientOptions['lang'] = $lang;

        $this->registerPlugin('fullCalendar');
        $tag = ArrayHelper::remove($this->options, 'tag', 'div');
        return Html::tag($tag, '', $this->options);
    }
}


text:
<?php
/* Reminder: always indent with 4 spaces (no tabs). */
// +---------------------------------------------------------------------------+
// | Copyright (c) 2013, Demian Turner                                         |
// | All rights reserved.                                                      |
// |                                                                           |
// | Redistribution and use in source and binary forms, with or without        |
// | modification, are permitted provided that the following conditions        |
// | are met:                                                                  |
// |                                                                           |
// | o Redistributions of source code must retain the above copyright          |
// |   notice, this list of conditions and the following disclaimer.           |
// | o Redistributions in binary form must reproduce the above copyright       |
// |   notice, this list of conditions and the following disclaimer in the     |
// |   documentation and/or other materials provided with the distribution.    |
// | o The names of the authors may not be used to endorse or promote          |
// |   products derived from this software without specific prior written      |
// |   permission.                                                             |
// |                                                                           |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR     |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT          |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE     |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.      |
// |                                                                           |
// +---------------------------------------------------------------------------+
// | Seagull 1.0                                                               |
// +---------------------------------------------------------------------------+
// | String.php                                                                |
// +---------------------------------------------------------------------------+
// | Author:   Demian Turner <demian@phpkitchen.com>                           |
// +---------------------------------------------------------------------------+
// $Id: String.php,v 1.14 2005/06/01 11:11:23 demian Exp $

define('SGL_CENSOR_DISABLE',        0);
define('SGL_CENSOR_EXACT_MATCH',    1);
define('SGL_CENSOR_WORD_BEGINNING', 2);
define('SGL_CENSOR_WORD_FRAGMENT',  3);

/**
 * Various string helper methods.
 *
 * @package SGL
 * @author  Demian Turner <demian@phpkitchen.com>
 * @version $Revision: 1.14 $
 */
class SGL_String
{
    /**
     * Censors profanity.
     *
     * @author  Tony Bibbs  <tony@tonybibbs.com>
     * @access  public
     * @static
     * @param   string  $text           string to check
     * @return  string  $editedText     edited text
     */
    function censor($text)
    {
        SGL::logMessage(null, PEAR_LOG_DEBUG);
        $c = SGL_Config::singleton();
        $conf = $c->getAll();

        $editedText = $text;
        $censorMode = self::pseudoConstantToInt($conf['censor']['mode']);
        $regExPrefix = '';
        $regExSuffix = '';
        if ($censorMode != SGL_CENSOR_DISABLE) {
            $aBadWords = explode(',', $conf['censor']['badWords']);
            if (is_array($aBadWords)) {
                $replacement = $conf['censor']['replaceString'];

                switch ($censorMode) {
                case SGL_CENSOR_EXACT_MATCH:
                    $regExPrefix = '(\s*)';
                    $regExSuffix = '(\W*)';
                    break;
                case SGL_CENSOR_WORD_BEGINNING:
                    $regExPrefix = '(\s*)';
                    $regExSuffix = '(\w*)';
                    break;
                case SGL_CENSOR_WORD_FRAGMENT:
                    $regExPrefix   = '(\w*)';
                    $regExSuffix   = '(\w*)';
                    break;
                }
                for ($i = 0; $i < count($aBadWords); $i++ ) {
                    $editedText = eregi_replace( $regExPrefix .
                        $aBadWords[$i] .
                        $regExSuffix, "\\1$replacement\\2", $editedText);
                }
            }
        }
        return $editedText;
    }

    /**
     * Defines the <CR><LF> value depending on the user OS.
     *
     * @return  string   the <CR><LF> value to use
     * @access  public
     */
    public static function getCrlf()
    {
        SGL::logMessage(null, PEAR_LOG_DEBUG);
        // TODO: deal with Mac OS Classic i.e. < OS X when line ending is CR
        $crlf = (substr(PHP_OS, 0, 3) == 'WIN')
            ? "\r\n"
            : "\n";
        return $crlf;
    }

    /**
     * @param $var
     * @return array|bool|string
     */
    public static function trimWhitespace($var)
    {
        if (!isset($var)) {
            return false;
        }
        if (is_array($var)) {
            $newArray = array();
            foreach ($var as $key => $value) {
                $newArray[$key] = self::trimWhitespace($value);
            }
            return $newArray;
        } else {
            return trim($var);
        }
    }

    /**
     * If magic_quotes_gpc is in use, run stripslashes() on $var.
     *
     * @access  public
     * @param   string $var  The string to un-quote, if necessary.
     * @return  string       $var, minus any magic quotes.
     * @author  Chuck Hagenbuch <chuck@horde.org>
     */
    public static function dispelMagicQuotes(&$var)
    {
        static $magicQuotes;
        if (!isset($magicQuotes)) {
            $magicQuotes = get_magic_quotes_gpc();
        }
        if ($magicQuotes) {
            if (!is_array($var)) {
                $var = stripslashes($var);
            } else {
                array_walk($var, array('SGL_String', 'dispelMagicQuotes'));
            }
        }
    }

    /**
     * Returns cleaned user input.
     *
     * Instead of addslashing potential ' and " chars, let's remove them and get
     * rid of any magic quoting which is enabled by default.  Also removes any
     * html tags and ASCII zeros
     *
     * @access  public
     * @param   string $var  The string to clean.
     * @return  string       $cleaned result.
     */
    public static function clean($var)
    {
        if (!isset($var)) {
            return false;
        }
        $var = self::trimWhitespace($var);
        if (is_array($var)) {
            $newArray = array();
            foreach ($var as $key => $value) {
                $newArray[$key] = self::clean($value);
            }
            return $newArray;
        } else {
            return strip_tags($var);
        }
    }

    /**
     * @param $var
     * @return array|bool|mixed
     */
    public static function removeJs($var)
    {
        if (!isset($var)) {
            return false;
        }
        $var = self::trimWhitespace($var);
        if (is_array($var)) {
            $newArray = array();
            foreach ($var as $key => $value) {
                $newArray[$key] = self::removeJs($value);
            }
            return $newArray;
        } else {
            $search = "/<script[^>]*?>.*?<\/script\s*>/i";
            $replace = '';
            $clean = preg_replace($search, $replace, $var);
            return $clean;
        }
    }

    /**
     * Uses PHP tidy lib (http://www.coggeshall.org/tidy.php) if enabled and
     * extension is available. Cleans/corrects input html. If $logErrors
     * is set to true and logging is set to true in default.conf.ini, tidy()
     * will add entry to log with a string describing the errors and changes
     * Tidy made via SGL::logMessage().
     *
     * @access public
     * @param string $html the text to clean
     * @param bool $logErrors
     * @return string cleaned text
     *
     * @author  Andy Crain <andy@newslogic.com>
     * @since   PHP 4.3
     */
    function tidy($html, $logErrors = false)
    {
        SGL::logMessage(null, PEAR_LOG_DEBUG);

        $c = SGL_Config::singleton();
        $conf = $c->getAll();

        if (       !$conf['site']['tidyhtml']
                || !extension_loaded('tidy')) {
            return $html;
        }
        $options = array(
            'wrap' => 0,
            'indent' => true,
            'indent-spaces' => 4,
            'output-xhtml' => true,
            'drop-font-tags' => false,
            'clean' => false,
        );
        if (strlen($html)) {
            $tidy = new Tidy();
            $tidy->parseString($html, $options, 'utf8');
            $tidy->cleanRepair();
            $ret = $tidy->body();
        }
        return $ret;
    }

    /**
     * Looks up key in current lang file (determined by preference)
     * and returns target value.
     *
     * @param string $key       Translation term
     * @param bool|string $filter Optional filter fn
     * @param array $aParams
     * @param string $langCode  Pass the lang code for the language you wish to translate
     * @return string
     *
     * @todo better integrate $lang handling
     */
    public static function translate($key, $filter = false, $aParams = array(), $langCode = null)
    {
        if (!is_null($langCode)) {
            return self::translate2($key, $filter, $aParams, $langCode);
        }
        $c = SGL_Config::singleton();
        $conf = $c->getAll();

        $trans = isset($GLOBALS['_SGL']['TRANSLATION'])
			? $GLOBALS['_SGL']['TRANSLATION']
			: false;
		if (!$trans) return $key;
        if (isset($trans[$key])) {
            if (!is_array($trans[$key])
                    && strstr($trans[$key], '||')
                    && $conf['translation']['container'] == 'db') {
                preg_match_all('/([^|]*)\|([^|]*)(?=\|\|)/', $trans[$key], $aPieces);
                $ret = array_combine($aPieces[1], $aPieces[2]);
            } else {
                $ret = $trans[$key];
            }
            if (!is_array($trans[$key]) && $filter && function_exists($filter)) {
                if (is_object($aParams)) {
                    $aParams = (array)$aParams;
                }
                if (!empty($aParams) && is_array($aParams) && $filter == 'vprintf') {
                    $i = 1;
                    foreach ($aParams as $key => $value) {
                        if (!empty($value) && !is_scalar($value)) {
                            continue;
                        }
                        $value = str_replace('%', '%%', $value);
                        $ret = str_replace("%$i%", $value, $ret);
                        $ret = str_replace("%$i", $value, $ret);
                        $ret = str_replace("%$key%", $value, $ret);
                        $ret = str_replace("%$key", $value, $ret);
                        $i++;
                    }
                    $ret = vsprintf($ret, $aParams);
                } else {
                    $ret = $filter($ret);
                }
            }
            return $ret;
        } else {
            //  add translation
            if (!empty($key)
                    && isset($conf['translation']['addMissingTrans'])
                    && $conf['translation']['addMissingTrans']
                    && isset($conf['translation']['container'])
                    && $conf['translation']['container'] == 'db') {

                //  get a reference to the request object
                $req =  SGL_Request::singleton();
                $moduleName = $req->get('moduleName');

                //  fetch fallback lang
                $fallbackLang = $conf['translation']['fallbackLang'];

                $trans = SGL_Translation3::singleton('admin');
                $result = $trans->add($key, $moduleName, array($fallbackLang => $key));
            }
            SGL::logMessage('Key \''.$key.'\' Not found', PEAR_LOG_NOTICE);
            $key = (isset($conf['debug']['showUntranslated']) && $conf['debug']['showUntranslated'])
                ? '>' . $key . '<'
                : $key;
            return $key;
        }
    }

    /**
     * Looks up key in current lang dictionary (SGL_Translation3) or specific language
     * and returns target value.
     *
     * @param string $key       Translation term
     * @param bool|string $filter Optional filter fn
     * @param array $aParams   Optional params
     * @param string $langCode  Optional langCode to force translation in this language
     * @return string
     */
    function translate2($key, $filter = false, $aParams = array(), $langCode)
    {
        require_once 'SGL/Translation3.php';
        $trans = SGL_Translation3::singleton('array');
        if ($ret = $trans->translate($langCode, $key)) {
            if (!is_array($ret) && $filter && function_exists($filter)) {
                if (is_object($aParams)) {
                    $aParams = (array)$aParams;
                }
                if (!empty($aParams) && is_array($aParams) && $filter == 'vprintf') {
                    $i = 1;
                    foreach ($aParams as $key => $value) {
                        if (!empty($value) && !is_scalar($value)) {
                            continue;
                        }
                        $value = str_replace('%', '%%', $value);
                        $ret = str_replace("%$i%", $value, $ret);
                        $ret = str_replace("%$i", $value, $ret);
                        $ret = str_replace("%$key%", $value, $ret);
                        $ret = str_replace("%$key", $value, $ret);
                        $i++;
                    }
                    $ret = vsprintf($ret, $aParams);
                } else {
                    $ret = $filter($ret);
                }
            }
            return $ret;
        } else {
            SGL::logMessage('Key \''.$key.'\' Not found', PEAR_LOG_NOTICE);
            $key = SGL_Config::get('debug.showUntranslated')
                ? '>' . $key . '<'
                : $key;
            return $key;
        }
    }

    /**
     * Encode a given character to a decimal or hexadecimal HTML entity or
     * to an hexadecimal URL-encoded symbol.
     *
     * @param string $char Char to encode
     * @param mixed $encoding 1 or D for decimal entity, 2 or H for hexa entity,
     *        3 or U for URL-encoding,
     *        R for a random choice of any of the above,
     *        E for a random choice of any of the HTML entities.
     * @return string $encoded Encoded character (or raw char if unknown encoding)
     *
     * @author  Philippe Lhoste <PhiLho(a)GMX.net>
     */
    function char2entity($char, $encoding = 'H')
    {
        $pad = 1;
        if ($encoding == 'R' || $encoding == 'E') {
            // Use random padding with zeroes
            // Unicode stops at 0x10FFFF, ie. at 1114111 (7 digits)
            $pad = rand(2, 7);
            if ($encoding == 'R') {
                // Full random
                $encoding = rand(1, 3);
            } else {
                // Random only to entity
                $encoding = rand(1, 2);
            }
        }
        $asc = ord($char);

        switch ($encoding) {
        case 1: // Decimal entity
        case 'D':
            return sprintf("&#%0{$pad}d;", $asc);
            break;
        case 2: // Hexadecimal entity
        case 'H':
            return sprintf("&#x%0{$pad}X;", $asc);
            break;
        case 3: // URL-encoding
        case 'U':
            return sprintf("%%%02X", $asc);
            break;
        default:
            return $char;
        }
    }

    /**
     * Primarily used for obfuscating email addresses to prevent spam
     * harvesting. Since it is URL-encoded, this can be used only in the href
     * part of a <a> tag (mailto: scheme).
     *
     * @param string $str String to encode
     * @return string $encoded Encoded string
     */
    function obfuscate($str)
    {
        $encoded = bin2hex($str);
        $encoded = chunk_split($encoded, 2, '%');
        $encoded = '%' . substr($encoded, 0, strlen($encoded) - 1);
        return $encoded;
    }

    /**
     * Primarily used for obfuscating email addresses to prevent spam
     * harvesting.
     *
     * @param string $str String to encode
     * @param bool $bForLink true if used in the href part of a <a> tag, false to be used in HTML
     * @return string $encoded Encoded string
     *
     * @author  Philippe Lhoste <PhiLho(a)GMX.net>
     */
    function obfuscate2($str, $bForLink = true)
    {
        if ($bForLink) {
            $e = "'R'";
        } else {
            $e = "'E'";
        }
        $encoded = preg_replace_callback(
                '|([-?=@._emailto:])|', // Mostly arbitrary, to mix encoded and unencoded chars...
                create_function(
                        '$matches',
                        "return char2entity(\$matches[0], $e);"
                ),
                $str
        );
        return $encoded;
     }

    /**
     * Lightweight function to obfuscate mail addresses: substitutes @ and dots
     * in the domain part with a string.
     *
     * @access  public
     * @param   string $address
     * @return  string
     *
     * @author Riccardo Magliocchetti <riccardo@datahost.it>
     */
    function obfuscate3($address)
    {
        $at = '(at)';
        $dot = '(dot)';

        $len = strlen($address);
        $pos = strpos($address, '@');
        $name = substr($address, 0, $pos-$len);

        /* Trick to avoid the regex */
        $domain = $at . substr($address, $pos+1);
        $domain = preg_replace('/\./', $dot, $domain);

        return $name . $domain;
    }

    /**
     * Munge email addresses swapping plain text with html char entities as
     * explained here: http://perso.crans.org/~raffo/aem/index.php.
     *
     * @access  public
     * @param   string $address
     * @return  string
     *
     * @author Riccardo Magliocchetti <riccardo@datahost.it>
     */
    function mungeMailAddress($address)
    {
        $len = strlen($address);
        $aOld = str_split($address);
        $aMunged = array();

        for ($i = 0; $i < $len; $i++) {
            $aMunged[$i] =  "&#" . ord($aOld[$i]) . ";";
        }

        $munged = implode('' ,$aMunged);

        return $munged;
    }

    /**
     * Returns a shortened version of text string resolved by word boundaries.
     *
     * @static
     *
     * @access public
     *
     * @param string $str           Text to be shortened.
     * @param integer $limit        Number of words/chars to cut to.
     * @param integer $element      What string element type to count by.
     * @param string $appendString  Trailing string to be appended.
     *
     * @return string Correctly shortened text.
     */
    public static function summarise($str, $limit = 50, $element = SGL_WORD,
        $appendString = ' ...')
    {
        switch ($element) {

        // strip by chars
        case SGL_CHAR:
            if (extension_loaded('mbstring')) {
                $enc = mb_detect_encoding($str);
                $len = mb_strlen($str, $enc);
                $ret = $len > $limit
                    ? mb_substr($str, 0, $limit, $enc) . $appendString
                    : $str;
            } else {
                $len = strlen($str);
                $ret = $len > $limit
                    ? substr($str, 0, $limit) . $appendString
                    : $str;
            }
            break;

        // strip by words
        case SGL_WORD:
            $aWords = explode(' ', $str);
            if (count($aWords) > $limit) {
                $ret = implode(' ', array_slice($aWords, 0, $limit)) . $appendString;
            } else {
                $ret = $str;
            }
            break;
        }

        return  $ret;
    }

    /**
     * Returns a set number of lines of a block of html, for summarising articles.
     *
     * @param string $str
     * @param integer $lines
     * @internal param string $appendString
     * @return string
     * @todo    needs to handle orphan <b> and <strong> tags
     */
    function summariseHtml($str, $lines=10)
    {
        $aLines = explode("\n", $str);
        $aSegment = array_slice($aLines, 0, $lines);

        //  close tags like <ul> so page layout doesn't break
        $unclosedListTags = 0;
        $aMatches = array();
        foreach ($aSegment as $line) {
            if (preg_match("/<[u|o]l/i", $line, $matches)) {
                $aMatches[] = $matches;
                $unclosedListTags++;
            }
            if (preg_match("/<\/[u|o]l>/i", $line)) {
                $unclosedListTags--;
            }
        }
        //  reinstate close tags
        for ($x=0; $x < $unclosedListTags; $x++) {
            array_push($aSegment, '</ul>');
        }
        $ret = implode("\n", $aSegment);
        $ret = self::tidy($ret);
        return $ret;
    }

    /**
     * Converts bytes to KB/MB/GB as appropriate.
     *
     * @access  public
     * @param $size
     * @param   int $decimals
     * @param   string $lang
     *
     * @internal param int $bytes
     * @return  string $formatted B/KB/MB/GB
     */
     public static function formatBytes($size, $decimals = 1, $lang = '--')
    {
        $aSizeList = array(1073741824, 1048576, 1024, 0);
        // Should check if string is in an array, other languages may use octets
        if ($lang == 'FR') {
            $aSizeNameList = array(' Go', ' Mo', ' Ko', ' octets');
            // Note: should also use French decimal separator (coma)
        } else {
            $aSizeNameList = array('GB', 'MB', 'KB', 'B');
        }
        $i = 0;
        $formatted = '';
        foreach ($aSizeList as $bytes) {
            if ($size >= $bytes) {
                if ($bytes == 0) {
                    // size 0 override
                    $bytes = 1;
                    $decimals = 0;
                }
                $formatted = sprintf("%.{$decimals}f{$aSizeNameList[$i]}", $size / $bytes);
                break;
            }
            $i++;
        }
        return $formatted;
    }

    /**
     * @param $str
     * @return mixed
     */
    public static function toValidVariableName($str)
    {
        //  remove illegal chars
        $search = '/[^a-zA-Z1-9_]/';
        $replace = '';
        $res = preg_replace($search, $replace, $str);
        //  ensure 1st letter is lc
        $firstLetter = strtolower($res[0]);
        $final = substr_replace($res, $firstLetter, 0, 1);
        return $final;
    }

    /**
     * @param $origName
     * @return mixed
     */
    function toValidFileName($origName)
    {
        return self::dirify($origName);
    }

    //  from http://kalsey.com/2004/07/dirify_in_php/
    /**
     * @param $s
     * @return mixed
     */
    public static function dirify($s)
    {
         $s = self::convertHighAscii($s);     ## convert high-ASCII chars to 7bit.
         $s = strtolower($s);                       ## lower-case.
         $s = strip_tags($s);                       ## remove HTML tags.
         // Note that &nbsp (for example) is legal in HTML 4, ie. semi-colon is optional if it is followed
         // by a non-alphanumeric character (eg. space, tag...).
//         $s = preg_replace('!&[^;\s]+;!','',$s);    ## remove HTML entities.
         $s = preg_replace('!&#?[A-Za-z0-9]{1,7};?!', '', $s);    ## remove HTML entities.
         $s = preg_replace('![^\w\s-]!', '',$s);    ## remove non-word/space chars.
         $s = preg_replace('!\s+!', '_',$s);        ## change space chars to underscores.
         return $s;
    }

    /**
     * @param $s
     * @return mixed
     */
    function convertHighAscii($s)
    {
        // Seems to be for Latin-1 (ISO-8859-1) and quite limited (no ae/oe, no y:/Y:, etc.)
         $aHighAscii = array(
           "!\xc0!" => 'A',    # A`
           "!\xe0!" => 'a',    # a`
           "!\xc1!" => 'A',    # A'
           "!\xe1!" => 'a',    # a'
           "!\xc2!" => 'A',    # A^
           "!\xe2!" => 'a',    # a^
           "!\xc4!" => 'A',    # A:
           "!\xe4!" => 'a',    # a:
           "!\xc3!" => 'A',    # A~
           "!\xe3!" => 'a',    # a~
           "!\xc8!" => 'E',    # E`
           "!\xe8!" => 'e',    # e`
           "!\xc9!" => 'E',    # E'
           "!\xe9!" => 'e',    # e'
           "!\xca!" => 'E',    # E^
           "!\xea!" => 'e',    # e^
           "!\xcb!" => 'E',    # E:
           "!\xeb!" => 'e',    # e:
           "!\xcc!" => 'I',    # I`
           "!\xec!" => 'i',    # i`
           "!\xcd!" => 'I',    # I'
           "!\xed!" => 'i',    # i'
           "!\xce!" => 'I',    # I^
           "!\xee!" => 'i',    # i^
           "!\xcf!" => 'I',    # I:
           "!\xef!" => 'i',    # i:
           "!\xd2!" => 'O',    # O`
           "!\xf2!" => 'o',    # o`
           "!\xd3!" => 'O',    # O'
           "!\xf3!" => 'o',    # o'
           "!\xd4!" => 'O',    # O^
           "!\xf4!" => 'o',    # o^
           "!\xd6!" => 'O',    # O:
           "!\xf6!" => 'o',    # o:
           "!\xd5!" => 'O',    # O~
           "!\xf5!" => 'o',    # o~
           "!\xd8!" => 'O',    # O/
           "!\xf8!" => 'o',    # o/
           "!\xd9!" => 'U',    # U`
           "!\xf9!" => 'u',    # u`
           "!\xda!" => 'U',    # U'
           "!\xfa!" => 'u',    # u'
           "!\xdb!" => 'U',    # U^
           "!\xfb!" => 'u',    # u^
           "!\xdc!" => 'U',    # U:
           "!\xfc!" => 'u',    # u:
           "!\xc7!" => 'C',    # ,C
           "!\xe7!" => 'c',    # ,c
           "!\xd1!" => 'N',    # N~
           "!\xf1!" => 'n',    # n~
           "!\xdf!" => 'ss'
         );
         $find = array_keys($aHighAscii);
         $replace = array_values($aHighAscii);
         $s = preg_replace($find, $replace, $s);
         return $s;
    }

    /**
     * @param $text
     * @return mixed
     */
    function to7bit($text)
    {
        if (!function_exists('mb_convert_encoding')) {
            return $text;
        }
        $text = mb_convert_encoding($text,'HTML-ENTITIES',mb_detect_encoding($text));
        $text = preg_replace(
           array('/ß/','/&(..)lig;/',
                 '/&([aouAOU])uml;/','/&(.)[^;]*;/'),
           array('ss',"$1","$1".'e',"$1"),
           $text);
        return $text;
    }

    /**
     * Replaces accents in string.
     *
     * @static
     *
     * @todo make it work with cyrillic chars
     * @todo make it work with non utf-8 encoded strings
     *
     * @see self::isCyrillic()
     * @param string $str
     *
     * @return string
     */
    public static function replaceAccents($str)
    {
        if (!self::isCyrillic($str)) {
            $str = self::to7bit($str);
            $str = preg_replace('/[^A-Z^a-z^0-9()]+/',' ',$str);
        }
        return $str;
    }

    /**
     * Checks if strings has cyrillic chars.
     *
     * @static
     * @param string $str
     *
     * @return boolean
     */
    public static function isCyrillic($str)
    {
        $ret = false;
        if (function_exists('mb_convert_encoding') && !empty($str)) {
            // codes for Russian chars
            $aCodes = range(1040, 1103);
            // convert to entities
            $encoded = mb_convert_encoding($str, 'HTML-ENTITIES',
                mb_detect_encoding($str));
            // get codes of the string
            $aChars = explode(';', str_replace('&#', '', $encoded));
            array_pop($aChars);
            $aChars = array_unique($aChars);
            // see if cyrillic chars there
            $aNonCyrillicChars = array_diff($aChars, $aCodes);
            // if string is the same -> no cyrillic chars
            $ret = count($aNonCyrillicChars) != count($aChars);
        }
        return $ret;
    }

    /**
     * Removes chars that are illegal in ini files.
     *
     * @param string $string
     * @return string
     */
    public static function stripIniFileIllegalChars($string)
    {
        return preg_replace("/[\|\&\~\!\"\(\)]/i", "", $string);
    }

    /**
     * Converts strings representing constants to int values.
     *
     * Used for when constants are stored as strings in config.
     *
     * @static
     * @param string $string
     * @return integer
     */
    public static function pseudoConstantToInt($string)
    {
        $ret = 0;
        if (is_int($string)) {
            $ret = $string;
        }
        if (is_numeric($string)) {
            $ret = (int)$string;
        }
        if (SGL_Inflector::isConstant($string)) {
            $const = str_replace("'", '', $string);
            if (defined($const)) {
                $ret = constant($const);
            }
        }
        return $ret;
    }

    /**
     * Escape single quote.
     *
     * @param   string $string
     *
     * @return  string
     *
     * @static
     */
    function escapeSingleQuote($string)
    {
        $ret = str_replace('\\', '\\\\', $string);
        $ret = str_replace("'", '\\\'', $ret);
        return $ret;
    }

    /**
     * Escape single quotes in every key of given array.
     *
     * @param   array $array
     * @return  array
     *
     * @static
     */
    public static function escapeSingleQuoteInArrayKeys($array)
    {
        $ret = array();
        foreach ($array as $key => $value) {
            $k = self::escapeSingleQuote($key);
            $ret[$k] = is_array($value)
                ? self::escapeSingleQuoteInArrayKeys($value)
                : $value;
        }
        return $ret;
    }
}
?>


text:
import alt from '../alt';

class FooterActions {
  constructor() {
    this.generateActions(
      'getSitesSuccess',
      'getSitesFail'
    );
  }

  getSites() {
    $.ajax({ url: '/api/sites' })
      .done((data) => {
        this.actions.getSitesSuccess(data)
      })
      .fail((jqXhr) => {
        this.actions.getSitesFail(jqXhr)
      });
  }
}

export default alt.createActions(FooterActions);