diff --git a/test/haxe/src/Arguments.hx b/test/haxe/src/Arguments.hx
new file mode 100644
index 0000000..bcf3793
--- /dev/null
+++ b/test/haxe/src/Arguments.hx
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package;
+
+import org.apache.thrift.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+
+using StringTools;
+
+
+enum Prot {
+	binary;
+	json;
+}
+
+enum Trns {
+	socket;
+	http;
+}
+
+
+class Arguments
+{
+	public var server(default,null) : Bool = false;
+	public var framed(default,null) : Bool = false;
+	public var buffered(default,null) : Bool = false;
+	public var protocol(default,null) : Prot = binary;
+	public var transport(default,null) : Trns = socket;
+	
+	public var host(default,null) : String = "localhost";
+	public var port(default,null) : Int = 9090;
+
+	public var numIterations(default,null) : Int = 1;
+	public var numThreads(default,null) : Int = 1;
+	
+	
+	public function new() {
+		#if sys
+		try {
+  			ParseArgs();
+		} catch (e : String) {
+			trace(GetHelp());
+			throw e;
+		}
+		#else
+		trace("WN: Platform does not support program arguments, using defaults.");
+		#end
+	}
+	
+	#if sys
+		
+	private static function GetHelp() : String {
+		return "\n"
+			+Sys.executablePath()+"  [client|server]  [options]\n"
+			+"Modus: Either client or server, the default is client.\n"
+			+"\n"
+			+"Options:\n"
+			+"  -f, --framed         framed transport (supersedes buffered)\n"
+			+"  -b, --buffered       buffered transport\n"
+			+"  --json               JSON protocol\n"
+			+"  --protocol=<prot>    Choose protocol: json, binary (default binary).\n"
+			+"  --port=<port>        Port number for socket transport, default 9090\n"
+			+"\n"
+			+"Client only options:\n"
+			+"  --host=<host>        Host name, IP or URL, default localhost\n"
+			+"  -n=<iterations>      Number of test iterations\n"
+			+"  -t=<threads>         Number of test threads\n"
+			+"  -u=<url>             Target Host/URL (same as --host)\n"
+			+"\n"
+			+"All arguments are optional.\n";
+	}
+	
+
+	private function ParseArgs() : Void {
+		var step = 0;
+		for (arg in Sys.args()) {
+			
+			// server|client
+			switch(step) {
+			case 0:
+				++step;
+				if ( arg == "client") 
+					server = false;
+				else if ( arg == "server") 
+					server = true;
+				else
+					throw "First argument must be 'server' or 'client'";
+					
+			case 1:					
+				if ( (arg == "-f") || (arg == "--framed")) {
+					framed = true;
+				} else if (( arg == "-b") || ( arg == "--buffered")) {
+					buffered = true;
+				} else if (( arg == "--json") || (arg == "--protocol=json")){
+					protocol = json;
+				} else if (( arg == "--protocol=binary")){
+					protocol = binary;
+				} else if (arg.startsWith("--host=")) {
+					ClientOnlyOption(arg);
+					host = arg.substr(arg.indexOf("=") + 1);
+				} else if (arg.startsWith("--port=")) {
+					var tmp = Std.parseInt(arg.substr(arg.indexOf("=")+1));
+					if( tmp != null)
+						port = tmp;
+					else
+						throw "Invalid port number "+arg;
+				} else if (arg == "-n") {
+					ClientOnlyOption(arg);
+					step = 2;
+				} else if (arg == "-t") {
+					ClientOnlyOption(arg);
+					step = 3;
+				} else if (arg == "-u") {
+					ClientOnlyOption(arg);
+					step = 4;
+				} else {
+					throw "Unexpected argument "+arg;
+				}					
+					
+			case 2:  // num iterations
+				step = 1;
+				var tmp = Std.parseInt(arg);
+				if( tmp != null)
+					numIterations = tmp;
+				else
+					throw "Invalid numeric value "+arg;
+					
+			case 3: // num threads
+				step = 1;
+				var tmp = Std.parseInt(arg);
+				if( tmp != null)
+					numThreads = tmp;
+				else
+					throw "Invalid numeric value "+arg;
+					
+			case 4:  // url
+				step = 1;
+				host = arg;
+					
+			default:
+				throw "Unexpected state";
+			}
+
+			
+			if ( framed && buffered)
+			{
+				trace("WN: framed supersedes buffered transport");
+			}
+
+		}
+	}
+
+	#end
+		
+		
+	private function ClientOnlyOption( arg : String) {
+		if( server) {
+			throw "Unexpected argument in client mode: "+arg;
+		}
+	}
+}
diff --git a/test/haxe/src/Main.hx b/test/haxe/src/Main.hx
new file mode 100644
index 0000000..a8ad147
--- /dev/null
+++ b/test/haxe/src/Main.hx
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ 
+package;
+
+import org.apache.thrift.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+
+import thrift.test.*;  // generated code
+
+class Main
+{
+	static function main() {
+		try {
+			var args = new Arguments();
+			
+			if (args.server)
+				TestServer.Execute(args);
+			else 
+				TestClient.Execute(args);
+			
+			trace("Completed.");
+		} catch (e : String) {
+			trace(e);
+		}
+	}
+
+}
diff --git a/test/haxe/src/TestClient.hx b/test/haxe/src/TestClient.hx
new file mode 100644
index 0000000..8698220
--- /dev/null
+++ b/test/haxe/src/TestClient.hx
@@ -0,0 +1,696 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package;
+
+import haxe.Int32;
+import haxe.Int64;
+import haxe.Timer;
+import haxe.ds.IntMap;
+import haxe.ds.StringMap;
+import haxe.ds.ObjectMap;
+
+import org.apache.thrift.*;
+import org.apache.thrift.helper.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+
+#if cpp
+import cpp.vm.Thread;
+#else
+// no thread support (yet)
+#end
+
+import thrift.test.*;  // generated code
+
+
+class TestResults {
+	private var successCnt : Int = 0;
+	private var errorCnt : Int = 0;
+	private var failedTests : String = "";
+	private var print_direct : Bool = false;
+
+	public function new(direct : Bool) {
+		print_direct = direct;
+	}
+	
+	public function Expect( expr : Bool, msg : String) : Void {
+		if ( expr) {
+			++successCnt;
+		} else {
+			++errorCnt;
+			failedTests += "\n  " + msg;
+			if( print_direct) {
+				trace('FAIL: $msg');
+			}
+		}
+	}
+
+
+	public function PrintSummary() : Void {
+		var total = successCnt + errorCnt;
+		var sp = (100 * successCnt) / total;
+		var ep = (100 * errorCnt) / total;
+		
+		trace('===========================');
+		trace('Tests executed    $total');
+		trace('Tests succeeded   $successCnt ($sp%)');
+		trace('Tests failed      $errorCnt ($ep%)');
+		if ( errorCnt > 0)
+		{
+			trace('===========================');
+  			trace('FAILED TESTS: $failedTests');
+		}
+		trace('===========================');
+	}
+}
+
+
+class TestClient {
+
+	public static function Execute(args : Arguments) :  Void
+	{
+		try
+		{
+			var difft = Timer.stamp();
+			
+			if( args.numThreads > 1) {
+				var threads = new List<Thread>();
+				for( test in 0 ... args.numThreads) {
+					threads.add( StartThread( args));
+				} 
+				for( thread in threads) {
+					Thread.readMessage(true);
+				}
+			} else {
+				var rslt = new TestResults(true);
+				RunClient(args,rslt);
+				rslt.PrintSummary();
+			}
+
+    		difft = Timer.stamp() - difft;
+			trace('total test time: $difft seconds');
+		}
+		catch (e : TException)
+		{
+			trace('$e');
+		}
+		catch (e : Dynamic)
+		{
+			trace('$e');
+		}
+	}
+
+	
+	private static function StartThread(args : Arguments) : Thread {
+		var thread = Thread.create(
+			function() : Void {
+				var main : Thread = Thread.readMessage(true);
+				try 
+				{
+					var rslt = new TestResults(false);
+					RunClient(args,rslt);
+					// TODO: promote rslt values to main thread
+				}
+				catch (e : TException)
+				{
+					trace('$e');
+				}
+				catch (e : Dynamic)
+				{
+					trace('$e');
+				}					
+				main.sendMessage("done");
+			});
+		
+		thread.sendMessage(Thread.current());
+		return thread;
+	}
+
+	
+	public static function RunClient(args : Arguments, rslt : TestResults)
+	{
+		var transport : TTransport = null;
+		switch (args.transport)
+		{
+			case socket:
+				transport = new TSocket(args.host, args.port);
+			case http:
+				throw "http transport not supported yet";
+				//transport = new THttpClient(args.host);
+			default:
+				throw "Unhandled transport";
+		}
+
+		// optional: layered transport
+		if ( args.framed) {
+			trace("- framed transport");
+			transport = new TFramedTransport(transport);
+		} else if ( args.buffered) {
+			trace("- buffered transport");
+			throw "TBufferedTransport not implemented yet";
+			//transport = new TBufferedTransport(transport);
+		}
+
+		// protocol
+		var protocol : TProtocol = null;
+		switch( args.protocol)
+		{
+		case binary:
+			trace("- binary protocol");
+			protocol = new TBinaryProtocol(transport);
+		case json:
+			trace("- json protocol");
+			protocol = new TJSONProtocol(transport);
+		default:
+			throw "Unhandled protocol";
+		}
+
+
+		// run the test code
+		HaxeBasicsTest( rslt);
+		ClientTest( transport, protocol, rslt);
+					
+	}
+
+
+	public static function HaxeBasicsTest( rslt : TestResults) : Void
+	{
+		// We need to test a few basic things used in the ClientTest
+		// Anything else beyond this scope should go into /lib/haxe/ instead
+		
+		var map32 = new IntMap<Int32>();
+		var map64 = new Int64Map<Int32>();
+
+		rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map<Int32> Test #1");
+		rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map<Int32> Test #2");
+		rslt.Expect( map32.remove( 4711) == map64.remove( Int64.make(47,11)), "Int64Map<Int32> Test #3");
+		rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map<Int32> Test #4");
+		
+		map32.set( 42, 815);
+		map64.set( Int64.make(0,42), 815);
+		map32.set( -517, 23);
+		map64.set( Int64.make(-5,17), 23);
+		map32.set( 0, -123);
+		map64.set( Int64.make(0,0), -123);
+
+		rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map<Int32> Test #10");
+		rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map<Int32> Test #11");
+		rslt.Expect( map32.exists( -517) == map64.exists( Int64.make(-5,17)), "Int64Map<Int32> Test #12");
+		rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map<Int32> Test #13");
+		rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map<Int32> Test #14");
+		rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map<Int32> Test #15");
+		rslt.Expect( map32.get( -517) == map64.get( Int64.make(-5,17)), "Int64Map<Int32> Test #16");
+		rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map<Int32> Test #Int64.make(-5,17)");
+		rslt.Expect( map32.get( 0) == map64.get( Int64.make(0,0)), "Int64Map<Int32> Test #18");
+		rslt.Expect( map32.remove( 4711) == map64.remove( Int64.make(47,11)), "Int64Map<Int32> Test #19");
+		rslt.Expect( map32.remove( -517) == map64.remove( Int64.make(-5,17)), "Int64Map<Int32> Test #20");
+		rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map<Int32> Test #21");
+		rslt.Expect( map32.exists( -517) == map64.exists( Int64.make(-5,17)), "Int64Map<Int32> Test #22");
+		rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map<Int32> Test #23");
+		rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map<Int32> Test #24");
+		rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map<Int32> Test #25");
+		rslt.Expect( map32.get( -517) == map64.get( Int64.make(-5,17)), "Int64Map<Int32> Test #26");
+		rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map<Int32> Test #27");
+		rslt.Expect( map32.get( 0) == map64.get( Int64.make(0,0)), "Int64Map<Int32> Test #28");
+
+		map32.set( 42, 1);
+		map64.set( Int64.make(0,42), 1);
+		map32.set( -517, -2);
+		map64.set( Int64.make(-5,17), -2);
+		map32.set( 0, 3);
+		map64.set( Int64.make(0,0), 3);
+
+		var c32 = 0;
+		for (key in map32.keys()) {
+			++c32;
+		}
+		var c64 = 0;
+		for (key in map64.keys()) {
+			++c64;
+		}
+		rslt.Expect( c32 == c64, "Int64Map<Int32> Test #30");
+
+		var s32 = map32.toString();
+		var s64 = map64.toString();
+		trace("Int64Map<Int32>.toString(): " + ' ("$s32" == "$s64")');
+
+		map32.remove( 42);
+		map64.remove( Int64.make(0,42));
+		map32.remove( -517);
+		map64.remove( Int64.make(-5,17));
+		map32.remove( 0);
+		map64.remove( Int64.make(0,0));
+		
+		rslt.Expect( map32.keys().hasNext() == map64.keys().hasNext(), "Int64Map<Int32> Test #90");
+		rslt.Expect( map32.exists( 4711) == map64.exists( Int64.make(47,11)), "Int64Map<Int32> Test #91");
+		rslt.Expect( map32.exists( -517) == map64.exists( Int64.make(-5,17)), "Int64Map<Int32> Test #92");
+		rslt.Expect( map32.exists( 42) == map64.exists( Int64.make(0,42)), "Int64Map<Int32> Test #93");
+		rslt.Expect( map32.exists( 0) == map64.exists( Int64.make(0,0)), "Int64Map<Int32> Test #94");
+		rslt.Expect( map32.get( 4711) == map64.get( Int64.make(47,11)), "Int64Map<Int32> Test #95");
+		rslt.Expect( map32.get( -517) == map64.get( Int64.make(-5,17)), "Int64Map<Int32> Test #96");
+		rslt.Expect( map32.get( 42) == map64.get( Int64.make(0,42)), "Int64Map<Int32> Test #97");
+		rslt.Expect( map32.get( 0) == map64.get( Int64.make(0,0)), "Int64Map<Int32> Test #98");
+	}
+
+
+	public static function ClientTest( transport : TTransport, protocol : TProtocol, rslt : TestResults) : Void
+	{
+		var client = new ThriftTestImpl(protocol,protocol);
+		try
+		{
+			if (!transport.isOpen())
+			{
+				transport.open();
+			}
+		}
+		catch (e : TException)
+		{
+			trace('$e');
+			return;
+		}
+		catch (e : Dynamic)
+		{
+			trace('$e');
+			return;
+		}
+
+		var start = Date.now();
+
+		trace('testVoid()');
+		client.testVoid();
+		trace(' = void');
+		rslt.Expect(true,"testVoid()");  // bump counter
+
+		trace('testString("Test")');
+		var s = client.testString("Test");
+		trace(' = "$s"');
+		rslt.Expect(s == "Test", '$s == "Test"');
+
+		trace('testByte(1)');
+		var i8 = client.testByte(1);
+		trace(' = $i8');
+		rslt.Expect(i8 == 1, '$i8 == 1');
+
+		trace('testI32(-1)');
+		var i32 = client.testI32(-1);
+		trace(' = $i32');
+		rslt.Expect(i32 == -1, '$i32 == -1');
+
+		trace('testI64(-34359738368)');
+		var i64 = client.testI64( Int64.make( 0xFFFFFFF8, 0x00000000)); // -34359738368
+		trace(' = $i64');
+		rslt.Expect( Int64.compare( i64, Int64.make( 0xFFFFFFF8, 0x00000000)) == 0, 
+		             Int64.toStr(i64) +" == "+Int64.toStr(Int64.make( 0xFFFFFFF8, 0x00000000)));
+
+		// edge case: the largest negative Int64 has no positive Int64 equivalent
+		trace('testI64(-9223372036854775808)');
+		i64 = client.testI64( Int64.make( 0x80000000, 0x00000000)); // -9223372036854775808
+		trace(' = $i64');
+		rslt.Expect( Int64.compare( i64, Int64.make( 0x80000000, 0x00000000)) == 0, 
+		             Int64.toStr(i64) +" == "+Int64.toStr(Int64.make( 0x80000000, 0x00000000)));
+
+		trace('testDouble(5.325098235)');
+		var dub = client.testDouble(5.325098235);
+		trace(' = $dub');
+		rslt.Expect(dub == 5.325098235, '$dub == 5.325098235');
+
+		trace('testStruct({"Zero", 1, -3, -5})');
+		var o = new Xtruct();
+		o.string_thing = "Zero";
+		o.byte_thing = 1;
+		o.i32_thing = -3;
+		o.i64_thing = Int64.make(0,-5);
+		var i = client.testStruct(o);
+		trace(' = {"' + i.string_thing + '", ' + i.byte_thing +', ' 
+                      + i.i32_thing +', '+ Int64.toStr(i.i64_thing) + '}');
+		rslt.Expect( i.string_thing == o.string_thing, "i.string_thing == o.string_thing");
+		rslt.Expect( i.byte_thing == o.byte_thing, "i.byte_thing == o.byte_thing");
+		rslt.Expect( i.i32_thing == o.i32_thing, "i.i64_thing == o.i64_thing");
+		rslt.Expect( i.i32_thing == o.i32_thing, "i.i64_thing == o.i64_thing");
+
+		trace('testNest({1, {\"Zero\", 1, -3, -5}, 5})');
+		var o2 = new Xtruct2();
+		o2.byte_thing = 1;
+		o2.struct_thing = o;
+		o2.i32_thing = 5;
+		var i2 = client.testNest(o2);
+		i = i2.struct_thing;
+		trace(" = {" + i2.byte_thing + ", {\"" + i.string_thing + "\", " 
+			  + i.byte_thing + ", " + i.i32_thing + ", " + Int64.toStr(i.i64_thing) + "}, " 
+			  + i2.i32_thing + "}");
+		rslt.Expect( i2.byte_thing == o2.byte_thing, "i2.byte_thing == o2.byte_thing");
+		rslt.Expect( i2.i32_thing == o2.i32_thing, "i2.i32_thing == o2.i32_thing");
+		rslt.Expect( i.string_thing == o.string_thing, "i.string_thing == o.string_thing");
+		rslt.Expect( i.byte_thing == o.byte_thing, "i.byte_thing == o.byte_thing");
+		rslt.Expect( i.i32_thing == o.i32_thing, "i.i32_thing == o.i32_thing");
+		rslt.Expect( Int64.compare( i.i64_thing, o.i64_thing) == 0, "i.i64_thing == o.i64_thing");
+
+		var mapout = new IntMap< haxe.Int32>();
+		for ( j in 0 ... 5)
+		{
+			mapout.set(j, j - 10);
+		}
+		trace("testMap({");
+		var first : Bool = true;
+		for( key in mapout.keys())
+		{
+			if (first)
+			{
+				first = false;
+			}
+			else
+			{
+				trace(", ");
+			}
+			trace(key + " => " + mapout.get(key));
+		}
+		trace("})");
+
+		var mapin = client.testMap(mapout);
+
+		trace(" = {");
+		first = true;
+		for( key in mapin.keys())
+		{
+			if (first)
+			{
+				first = false;
+			}
+			else
+			{
+				trace(", ");
+			}
+			trace(key + " => " + mapin.get(key));
+			rslt.Expect( mapin.get(key) == mapout.get(key), ' mapin.get($key) == mapout.get($key)');
+		}
+		trace("}");
+		for( key in mapout.keys())
+		{
+			rslt.Expect(mapin.exists(key), 'mapin.exists($key)');
+		}
+
+		var listout = new List<Int>();
+		for (j in -2 ... 3)
+		{
+			listout.add(j);
+		}
+		trace("testList({");
+		first = true;
+		for( j in listout)
+		{
+			if (first)
+			{
+				first = false;
+			}
+			else
+			{
+				trace(", ");
+			}
+			trace(j);
+		}
+		trace("})");
+
+		var listin = client.testList(listout);
+
+		trace(" = {");
+		first = true;
+		for( j in listin)
+		{
+			if (first)
+			{
+				first = false;
+			}
+			else
+			{
+				trace(", ");
+			}
+			trace(j);
+		}
+		trace("}");
+
+		rslt.Expect(listin.length == listout.length, "listin.length == listout.length");
+		var literout = listout.iterator();
+		var literin = listin.iterator();
+		while( literin.hasNext()) {
+			rslt.Expect(literin.next() == literout.next(), "literin[i] == literout[i]");
+		}
+	
+		//set
+		var setout = new IntSet();
+		for (j in -2 ... 3)
+		{
+			setout.add(j);
+		}
+		trace("testSet({");
+		first = true;
+		for( j in setout)
+		{
+			if (first)
+			{
+				first = false;
+			}
+			else
+			{
+				trace(", ");
+			}
+			trace(j);
+		}
+		trace("})");
+
+		var setin = client.testSet(setout);
+
+		trace(" = {");
+		first = true;
+		for( j in setin)
+		{
+			if (first)
+			{
+				first = false;
+			}
+			else
+			{
+				trace(", ");
+			}
+			trace(j);
+			rslt.Expect(setout.contains(j), 'setout.contains($j)');
+		}
+		trace("}");
+		rslt.Expect(setin.size == setout.size, "setin.length == setout.length");
+	
+
+		trace("testEnum(ONE)");
+		var ret = client.testEnum(Numberz.ONE);
+		trace(" = " + ret);
+		rslt.Expect(ret == Numberz.ONE, '$ret == Numberz.ONE');
+
+		trace("testEnum(TWO)");
+		ret = client.testEnum(Numberz.TWO);
+		trace(" = " + ret);
+		rslt.Expect(ret == Numberz.TWO, '$ret == Numberz.TWO');
+
+		trace("testEnum(THREE)");
+		ret = client.testEnum(Numberz.THREE);
+		trace(" = " + ret);
+		rslt.Expect(ret == Numberz.THREE, '$ret == Numberz.THREE');
+
+		trace("testEnum(FIVE)");
+		ret = client.testEnum(Numberz.FIVE);
+		trace(" = " + ret);
+		rslt.Expect(ret == Numberz.FIVE, '$ret == Numberz.FIVE');
+
+		trace("testEnum(EIGHT)");
+		ret = client.testEnum(Numberz.EIGHT);
+		trace(" = " + ret);
+		rslt.Expect(ret == Numberz.EIGHT, '$ret == Numberz.EIGHT');
+
+		trace("testTypedef(309858235082523)");
+		var uid = client.testTypedef( Int64.make( 0x119D0, 0x7E08671B));  // 309858235082523
+		trace(" = " + uid);
+		rslt.Expect( Int64.compare( uid, Int64.make( 0x119D0, 0x7E08671B)) == 0,
+		             Int64.toStr(uid)+" == "+Int64.toStr(Int64.make( 0x119D0, 0x7E08671B)));
+
+		trace("testMapMap(1)");
+		var mm = client.testMapMap(1);
+		trace(" = {");
+		for( key in mm.keys())
+		{
+			trace(key + " => {");
+			var m2 = mm.get(key);
+			for( k2 in m2.keys())
+			{
+				trace(k2 + " => " + m2.get(k2) + ", ");
+			}
+			trace("}, ");
+		}
+		trace("}");
+
+		var pos = mm.get(4);
+		var neg = mm.get(-4);
+		rslt.Expect( (pos != null) && (neg != null), "(pos != null) && (neg != null)");
+		for (i in 0 ... 5) {
+			rslt.Expect( pos.get(i) == i, 'pos.get($i) == $i');
+			rslt.Expect( neg.get(-i) == -i, 'neg.get(-$i) == -$i');
+	 	}
+
+		var insane = new Insanity();
+		insane.userMap = new IntMap< Int64>();
+		insane.userMap.set( Numberz.FIVE, Int64.make(0,5000));
+		var truck = new Xtruct();
+		truck.string_thing = "Truck";
+		truck.byte_thing = 8;
+		truck.i32_thing = 8;
+		truck.i64_thing = Int64.make(0,8);
+		insane.xtructs = new List<Xtruct>();
+		insane.xtructs.add(truck);
+		trace("testInsanity()");
+		var whoa = client.testInsanity(insane);
+		trace(" = {");
+		for( key in whoa.keys())
+		{
+			var val = whoa.get(key);
+			trace(key + " => {");
+
+			for( k2 in val.keys())
+			{
+				var v2 = val.get(k2);
+
+				trace(k2 + " => {");
+				var userMap = v2.userMap;
+
+				trace("{");
+				if (userMap != null)
+				{
+					for( k3 in userMap.keys())
+					{
+						trace(k3 + " => " + userMap.get(k3) + ", ");
+					}
+				}
+				else
+				{
+					trace("null");
+				}
+				trace("}, ");
+
+				var xtructs = v2.xtructs;
+
+				trace("{");
+				if (xtructs != null)
+				{
+					for( x in xtructs)
+					{
+						trace("{\"" + x.string_thing + "\", " 
+							  + x.byte_thing + ", " + x.i32_thing + ", " 
+							  + x.i32_thing + "}, ");
+					}
+				}
+				else
+				{
+					trace("null");
+				}
+				trace("}");
+
+				trace("}, ");
+			}
+			trace("}, ");
+		}
+		trace("}");
+
+		var first_map = whoa.get(Int64.make(0,1));
+		var second_map = whoa.get(Int64.make(0,2));
+		rslt.Expect( (first_map != null) && (second_map != null), "(first_map != null) && (second_map != null)");
+		if ((first_map != null) && (second_map != null))
+		{
+			var crazy2 = first_map.get(Numberz.TWO);
+			var crazy3 = first_map.get(Numberz.THREE);
+			var looney = second_map.get(Numberz.SIX);
+			rslt.Expect( (crazy2 != null) && (crazy3 != null) && (looney != null), 
+						"(crazy2 != null) && (crazy3 != null) && (looney != null)");
+
+			rslt.Expect( Int64.compare( crazy2.userMap.get(Numberz.EIGHT), Int64.make(0,8)) == 0, 
+						"crazy2.UserMap.get(Numberz.EIGHT) == 8");
+			rslt.Expect( Int64.compare( crazy3.userMap.get(Numberz.EIGHT), Int64.make(0,8)) == 0, 
+						"crazy3.UserMap.get(Numberz.EIGHT) == 8");
+			rslt.Expect( Int64.compare( crazy2.userMap.get(Numberz.FIVE), Int64.make(0,5)) == 0, 
+						"crazy2.UserMap.get(Numberz.FIVE) == 5");
+			rslt.Expect( Int64.compare( crazy3.userMap.get(Numberz.FIVE), Int64.make(0,5)) == 0, 
+						"crazy3.UserMap.get(Numberz.FIVE) == 5");
+
+			var crz2iter = crazy2.xtructs.iterator();
+			var crz3iter = crazy3.xtructs.iterator();
+			rslt.Expect( crz2iter.hasNext() && crz3iter.hasNext(), "crz2iter.hasNext() && crz3iter.hasNext()");
+			var goodbye2 = crz2iter.next();
+			var goodbye3 = crz3iter.next();
+			rslt.Expect( crz2iter.hasNext() && crz3iter.hasNext(), "crz2iter.hasNext() && crz3iter.hasNext()");
+			var hello2 = crz2iter.next();
+			var hello3 = crz3iter.next();
+			rslt.Expect( ! (crz2iter.hasNext() || crz3iter.hasNext()), "! (crz2iter.hasNext() || crz3iter.hasNext())");
+
+			rslt.Expect( hello2.string_thing == "Hello2", 'hello2.String_thing == "Hello2"');
+			rslt.Expect( hello2.byte_thing == 2, 'hello2.Byte_thing == 2');
+			rslt.Expect( hello2.i32_thing == 2, 'hello2.I32_thing == 2');
+			rslt.Expect( Int64.compare( hello2.i64_thing, Int64.make(0,2)) == 0, 'hello2.I64_thing == 2');
+			rslt.Expect( hello3.string_thing == "Hello2", 'hello3.String_thing == "Hello2"');
+			rslt.Expect( hello3.byte_thing == 2, 'hello3.Byte_thing == 2');
+			rslt.Expect( hello3.i32_thing == 2, 'hello3.I32_thing == 2');
+			rslt.Expect( Int64.compare( hello3.i64_thing, Int64.make(0,2)) == 0, 'hello3.I64_thing == 2');
+
+			rslt.Expect( goodbye2.string_thing == "Goodbye4", 'goodbye2.String_thing == "Goodbye4"');
+			rslt.Expect( goodbye2.byte_thing == 4, 'goodbye2.Byte_thing == 4');
+			rslt.Expect( goodbye2.i32_thing == 4, 'goodbye2.I32_thing == 4');
+			rslt.Expect( Int64.compare( goodbye2.i64_thing, Int64.make(0,4)) == 0, 'goodbye2.I64_thing == 4');
+			rslt.Expect( goodbye3.string_thing == "Goodbye4", 'goodbye3.String_thing == "Goodbye4"');
+			rslt.Expect( goodbye3.byte_thing == 4, 'goodbye3.Byte_thing == 4');
+			rslt.Expect( goodbye3.i32_thing == 4, 'goodbye3.I32_thing == 4');
+			rslt.Expect( Int64.compare( goodbye3.i64_thing, Int64.make(0,4)) == 0, 'goodbye3.I64_thing == 4');
+		}
+
+		var arg0 = 1;
+		var arg1 = 2;
+		var arg2 = Int64.make( 0x7FFFFFFF,0xFFFFFFFF);
+		var multiDict = new IntMap< String>();
+		multiDict.set(1, "one");
+		var arg4 = Numberz.FIVE;
+		var arg5 = Int64.make(0,5000000);
+		trace("Test Multi(" + arg0 + "," + arg1 + "," + arg2 + "," + multiDict + "," + arg4 + "," + arg5 + ")");
+		var multiResponse = client.testMulti(arg0, arg1, arg2, multiDict, arg4, arg5);
+		trace(" = Xtruct(byte_thing:" + multiResponse.byte_thing + ",string_thing:" + multiResponse.string_thing
+					+ ",i32_thing:" + multiResponse.i32_thing 
+			        + ",i64_thing:" + Int64.toStr(multiResponse.i64_thing) + ")");
+
+		rslt.Expect( multiResponse.string_thing == "Hello2", 'multiResponse.String_thing == "Hello2"');
+		rslt.Expect( multiResponse.byte_thing == arg0, 'multiResponse.Byte_thing == arg0');
+		rslt.Expect( multiResponse.i32_thing == arg1, 'multiResponse.I32_thing == arg1');
+		rslt.Expect( Int64.compare( multiResponse.i64_thing, arg2) == 0, 'multiResponse.I64_thing == arg2');
+
+
+		trace("Test Oneway(1)");
+		client.testOneway(1);
+
+		trace("Test Calltime()");
+		var difft = Timer.stamp();
+		for ( k in 0 ... 1000) {
+			client.testVoid();
+		}
+		difft = Timer.stamp() - difft;
+		trace('$difft ms per testVoid() call');
+	}
+}
diff --git a/test/haxe/src/TestServer.hx b/test/haxe/src/TestServer.hx
new file mode 100644
index 0000000..66b06e0
--- /dev/null
+++ b/test/haxe/src/TestServer.hx
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package;
+
+import org.apache.thrift.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+
+import thrift.test.*;  // generated code
+
+
+class TestServer
+{
+	public static function Execute(args : Arguments) :  Void
+	{
+		try
+		{
+			// Transport
+			var transport : TServerTransport = null;
+			switch( args.transport) {
+			case socket:
+				trace("- socket port "+args.port);
+				transport = new TServerSocket( args.port);
+			case http:
+				trace("- http");
+				throw "HTTP server not implemented yet";
+		 		//transport = new THttpServer( targetHost);
+			default:
+				throw "Unhandled transport";
+			}
+
+			// optional: layered transport
+			var transfactory : TTransportFactory = null;
+			if ( args.framed) {
+				trace("- framed transport");
+				transfactory = new TFramedTransportFactory();
+			} else if ( args.buffered) {
+				trace("- buffered transport");
+				throw "TBufferedTransport not implemented yet";
+				//transfactory = new TBufferedTransportFactory();
+			}
+
+			// protocol
+			var protfactory : TProtocolFactory = null;
+			switch( args.protocol)
+			{
+			case binary:
+				trace("- binary protocol");
+				protfactory = new TBinaryProtocolFactory();
+			case json:
+				trace("- json protocol");
+				protfactory = new TJSONProtocolFactory();
+			default:
+				throw "Unhandled protocol";
+			}
+
+		
+			// Processor
+			var handler = new TestServerHandler();
+			var processor = new ThriftTestProcessor(handler);
+
+			// Simple Server
+			var server = new TSimpleServer( processor, transport, transfactory, protfactory);
+				
+
+			/*
+			// Server event handler
+			var events = new TestServerEventHandler();
+			server.setEventHandler(serverEvents);
+			handler.server = serverEngine;
+			*/
+
+			// Run it
+			server.Serve();
+			trace("done.");
+
+		}
+		catch (x : TException)
+		{
+			trace('$x');
+		}
+		catch (x : Dynamic)
+		{
+			trace('$x');
+		}
+	}
+}
diff --git a/test/haxe/src/TestServerEventHandler.hx b/test/haxe/src/TestServerEventHandler.hx
new file mode 100644
index 0000000..b52943a
--- /dev/null
+++ b/test/haxe/src/TestServerEventHandler.hx
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package;
+
+import org.apache.thrift.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+
+import thrift.test.*;  // generated code
+
+
+class TestServerEventHandler : TServerEventHandler
+{
+	public int callCount = 0;
+	public void preServe()
+	{
+		callCount++;
+	}
+	public Object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output)
+	{
+		callCount++;
+		return null;
+	}
+	public void deleteContext(Object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output)
+	{
+		callCount++;
+	}
+	public void processContext(Object serverContext, Thrift.Transport.TTransport transport)
+	{
+		callCount++;
+	}
+}
+
+	
\ No newline at end of file
diff --git a/test/haxe/src/TestServerHandler.hx b/test/haxe/src/TestServerHandler.hx
new file mode 100644
index 0000000..e988adb
--- /dev/null
+++ b/test/haxe/src/TestServerHandler.hx
@@ -0,0 +1,470 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package;
+
+import org.apache.thrift.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+import org.apache.thrift.helper.*;
+
+import haxe.Int32;
+import haxe.Int64;
+import haxe.io.Bytes;
+import haxe.ds.IntMap;
+import haxe.ds.StringMap;
+import haxe.ds.ObjectMap;
+
+import thrift.test.*;  // generated code
+
+
+class TestServerHandler implements ThriftTest {
+
+    public var server:TServer;
+
+    public function new() {
+    }
+
+	/**
+	* Prints "testVoid()" and returns nothing.
+	*/
+    public function testVoid():Void
+    {
+    	trace("testVoid()");
+    }
+
+	/**
+	* Prints 'testString("%s")' with thing as '%s'
+	* @param string thing - the string to print
+	* @return string - returns the string 'thing'
+	* 
+	* @param thing
+	*/
+    public function testString(thing:String):String
+    {
+    	trace("teststring(\"" + thing + "\")");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testByte("%d")' with thing as '%d'
+	* @param byte thing - the byte to print
+	* @return byte - returns the byte 'thing'
+	* 
+	* @param thing
+	*/
+    public function testByte(thing:haxe.Int32):haxe.Int32
+    {
+    	trace("testByte(" + thing + ")");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testI32("%d")' with thing as '%d'
+	* @param i32 thing - the i32 to print
+	* @return i32 - returns the i32 'thing'
+	* 
+	* @param thing
+	*/
+    public function testI32(thing:haxe.Int32):haxe.Int32
+    {
+    	trace("testI32(" + thing + ")");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testI64("%d")' with thing as '%d'
+	* @param i64 thing - the i64 to print
+	* @return i64 - returns the i64 'thing'
+	* 
+	* @param thing
+	*/
+    public function testI64(thing:haxe.Int64):haxe.Int64
+    {
+    	trace("testI64(" + thing + ")");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testDouble("%f")' with thing as '%f'
+	* @param double thing - the double to print
+	* @return double - returns the double 'thing'
+	* 
+	* @param thing
+	*/
+    public function testDouble(thing:Float):Float
+    {
+    	trace("testDouble(" + thing + ")");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testStruct("{%s}")' where thing has been formatted 
+    *  into a string of comma seperated values
+	* @param Xtruct thing - the Xtruct to print
+	* @return Xtruct - returns the Xtruct 'thing'
+	* 
+	* @param thing
+	*/
+    public function testStruct(thing:Xtruct):Xtruct
+    {
+    	trace("testStruct({" + 
+                          "\"" + thing.string_thing + "\", " + 
+                          thing.byte_thing + ", " + 
+                          thing.i32_thing + ", " + 
+                          Int64.toStr(thing.i64_thing) + "})");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testNest("{%s}")' where thing has been formatted 
+    *  into a string of the nested struct
+	* @param Xtruct2 thing - the Xtruct2 to print
+	* @return Xtruct2 - returns the Xtruct2 'thing'
+	* 
+	* @param thing
+	*/
+    public function testNest(nest:Xtruct2):Xtruct2
+    {
+    	var thing:Xtruct = nest.struct_thing;
+    	trace("testNest({" + 
+                          nest.byte_thing + ", {" + 
+                          "\"" + thing.string_thing + "\", " + 
+                          thing.byte_thing + ", " + 
+                          thing.i32_thing + ", " + 
+                          Int64.toStr(thing.i64_thing) + "}, " + 
+                          nest.i32_thing + "})");
+    	return nest;
+    }
+
+	/**
+	* Prints 'testMap("{%s")' where thing has been formatted
+    *  into a string of  'key => value' pairs
+	*  seperated by commas and new lines
+	* @param map<i32,i32> thing - the map<i32,i32> to print
+	* @return map<i32,i32> - returns the map<i32,i32> 'thing'
+	* 
+	* @param thing
+	*/
+    public function testMap(thing:IntMap<haxe.Int32>):IntMap<haxe.Int32>
+    {
+    	trace("testMap({");
+    	var first:Bool = true;
+    	for (key in thing.keys()) {
+    		if (first) {
+    			first = false;
+    		} else {
+    			trace(", ");
+    		};
+    		trace(key + " => " + thing.get(key));
+    	};
+    	trace("})");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testStringMap("{%s}")' where thing has been formatted 
+    *  into a string of  'key => value' pairs
+	*  seperated by commas and new lines
+	* @param map<string,string> thing - the map<string,string> to print
+	* @return map<string,string> - returns the map<string,string> 'thing'
+	* 
+	* @param thing
+	*/
+    public function testStringMap(thing:StringMap<String>):StringMap<String>
+    {
+    	trace("testStringMap({");
+    	var first:Bool = true;
+    	for (key in thing.keys()) {
+    		if (first) {
+    			first = false;
+    		} else {
+    			trace(", ");
+    		};
+    		trace(key + " => " + thing.get(key));
+    	};
+    	trace("})");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testSet("{%s}")' where thing has been formatted 
+    *  into a string of  values
+	*  seperated by commas and new lines
+	* @param set<i32> thing - the set<i32> to print
+	* @return set<i32> - returns the set<i32> 'thing'
+	* 
+	* @param thing
+	*/
+    public function testSet(thing:IntSet):IntSet
+    {
+    	trace("testSet({");
+    	var first:Bool = true;
+    	for (elem in thing) {
+    		if (first) {
+    			first = false;
+    		} else {
+    			trace(", ");
+    		};
+    		trace(elem);
+    	};
+    	trace("})");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testList("{%s}")' where thing has been formatted 
+    *  into a string of  values
+	*  seperated by commas and new lines
+	* @param list<i32> thing - the list<i32> to print
+	* @return list<i32> - returns the list<i32> 'thing'
+	* 
+	* @param thing
+	*/
+    public function testList(thing:List<haxe.Int32>):List<haxe.Int32>
+    {
+    	trace("testList({");
+    	var first:Bool = true;
+    	for (elem in thing) {
+    		if (first) {
+    			first = false;
+    		} else {
+    			trace(", ");
+    		};
+    		trace(elem);
+    	};
+    	trace("})");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testEnum("%d")' where thing has been formatted into it's numeric value
+	* @param Numberz thing - the Numberz to print
+	* @return Numberz - returns the Numberz 'thing'
+	* 
+	* @param thing
+	*/
+    public function testEnum(thing:Int):Int
+    {
+    	trace("testEnum(" + thing + ")");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testTypedef("%d")' with thing as '%d'
+	* @param UserId thing - the UserId to print
+	* @return UserId - returns the UserId 'thing'
+	* 
+	* @param thing
+	*/
+    public function testTypedef(thing:haxe.Int64):haxe.Int64
+    {
+    	trace("testTypedef(" + thing + ")");
+    	return thing;
+    }
+
+	/**
+	* Prints 'testMapMap("%d")' with hello as '%d'
+	* @param i32 hello - the i32 to print
+	* @return map<i32,map<i32,i32>> - returns a dictionary with these values:
+	*   {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 
+	*     4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, }
+	* 
+	* @param hello
+	*/
+    public function testMapMap(hello:haxe.Int32):IntMap<IntMap<haxe.Int32>>
+    {
+    	trace("testMapMap(" + hello + ")");
+    	var mapmap = new IntMap<IntMap<Int>>();
+    	var pos = new IntMap<Int>();
+    	var neg = new IntMap<Int>();
+    	for (i in 1 ... 5) {
+    		pos.set(i, i);
+    		neg.set(-i, -i);
+    	};
+    	mapmap.set(4, pos);
+    	mapmap.set(-4, neg);
+    	return mapmap;
+    }
+
+	/**
+	* So you think you've got this all worked, out eh?
+	* 
+	* Creates a the returned map with these values and prints it out:
+	*   { 1 => { 2 => argument,
+	*            3 => argument,
+	*          },
+	*     2 => { 6 => <empty Insanity struct>, },
+	*   }
+	* @return map<UserId, map<Numberz,Insanity>> - a map with the above values
+	* 
+	* @param argument
+	*/
+    public function testInsanity(argument : Insanity) : Int64Map< IntMap< Insanity>>
+    {
+    	trace("testInsanity()");
+
+    	var hello = new Xtruct();
+    	hello.string_thing = "Hello2";
+    	hello.byte_thing = 2;
+    	hello.i32_thing = 2;
+    	hello.i64_thing = Int64.make(0, 2);
+
+    	var goodbye = new Xtruct();
+    	goodbye.string_thing = "Goodbye4";
+    	goodbye.byte_thing = 4;
+    	goodbye.i32_thing = 4;
+    	goodbye.i64_thing = Int64.make(0, 4);
+
+    	var crazy = new Insanity();
+		crazy.userMap = new IntMap< haxe.Int64>();
+    	crazy.userMap.set(Numberz.EIGHT, Int64.make(0,8));
+    	crazy.xtructs = new List<Xtruct>();
+    	crazy.xtructs.add(goodbye);
+
+    	var looney = new Insanity();
+    	crazy.userMap.set(Numberz.FIVE, Int64.make(0,5));
+    	crazy.xtructs.add(hello);
+
+    	var first_map = new IntMap< Insanity>();
+    	first_map.set(Numberz.TWO, crazy);
+    	first_map.set(Numberz.THREE, crazy);
+
+    	var second_map = new IntMap< Insanity>();
+    	second_map.set(Numberz.SIX, looney);
+
+		var insane = new Int64Map< IntMap< Insanity>>();
+    	insane.set( Int64.make(0,1), first_map);
+    	insane.set( Int64.make(0,2), second_map);
+
+    	return insane;
+    }
+
+	/**
+	* Prints 'testMulti()'
+	* @param byte arg0 -
+	* @param i32 arg1 -
+	* @param i64 arg2 -
+	* @param map<i16, string> arg3 -
+	* @param Numberz arg4 -
+	* @param UserId arg5 -
+	* @return Xtruct - returns an Xtruct 
+    *    with string_thing = "Hello2, byte_thing = arg0, i32_thing = arg1
+	*    and i64_thing = arg2
+	* 
+	* @param arg0
+	* @param arg1
+	* @param arg2
+	* @param arg3
+	* @param arg4
+	* @param arg5
+	*/
+    public function testMulti(arg0:haxe.Int32, arg1:haxe.Int32, arg2:haxe.Int64, 
+        arg3:IntMap<String>, arg4:Int, arg5:haxe.Int64):Xtruct
+    {
+    	trace("testMulti()");
+    	var hello = new Xtruct();
+    	hello.string_thing = "Hello2";
+    	hello.byte_thing = arg0;
+    	hello.i32_thing = arg1;
+    	hello.i64_thing = arg2;
+    	return hello;
+    }
+
+	/**
+	* Print 'testException(%s)' with arg as '%s'
+	* @param string arg - a string indication what type of exception to throw
+	* if arg == "Xception" throw Xception with errorCode = 1001 and message = arg
+	* elsen if arg == "TException" throw TException
+	* else do not throw anything
+	* 
+	* @param arg
+	*/
+    public function testException(arg:String):Void
+    {
+    	trace("testException(" + arg + ")");
+    	if (arg == "Xception") {
+    		var x = new Xception();
+    		x.errorCode = 1001;
+    		x.message = arg;
+    		throw x;
+    	};
+    	if (arg == "TException") {
+    		throw new TException();
+    	};		
+    	return;
+    }
+
+	/**
+	* Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s'
+	* @param string arg - a string indication what type of exception to throw
+	* if arg0 == "Xception" 
+	* throw Xception with errorCode = 1001 and message = "This is an Xception"
+	* else if arg0 == "Xception2" 
+	* throw Xception2 with errorCode = 2002 and message = "This is an Xception2"
+	* else do not throw anything
+	* @return Xtruct - an Xtruct with string_thing = arg1
+	* 
+	* @param arg0
+	* @param arg1
+	*/
+    public function testMultiException(arg0:String, arg1:String):Xtruct
+    {
+    	trace("testMultiException(" + arg0 + ", " + arg1 + ")");
+    	if (arg0 == "Xception") {
+    		var x = new Xception();
+    		x.errorCode = 1001;
+    		x.message = "This is an Xception";
+    		throw x;
+    	} else if (arg0 == "Xception2") {
+    		var x = new Xception2();
+    		x.errorCode = 2002;
+    		x.struct_thing = new Xtruct();
+    		x.struct_thing.string_thing = "This is an Xception2";
+    		throw x;
+    	};
+    	var result = new Xtruct();
+    	result.string_thing = arg1;
+    	return result;
+    }
+
+	/**
+	* Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d'
+	* sleep 'secondsToSleep'
+	* Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d'
+	* @param i32 secondsToSleep - the number of seconds to sleep
+	* 
+	* @param secondsToSleep
+	*/
+    public function testOneway(secondsToSleep:haxe.Int32):Void
+    {
+    	trace("testOneway(" + secondsToSleep + "), sleeping...");
+    	Sys.sleep(secondsToSleep);
+    	trace("testOneway finished");
+    }
+
+    public function testStop():Void
+    {
+    	if (server != null) {
+    		server.Stop();
+    	};
+    }
+}
