diff --git a/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs b/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs
index ccfe21d..c810a08 100644
--- a/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs
+++ b/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs
@@ -26,17 +26,16 @@
 using Thrift;
 using Test.Multiplex;
 
-
 namespace Test.Multiplex.Client
 {
     public class TestClient
     {
-        private void Run()
+        static void Execute(int port)
         {
             try
             {
                 TTransport trans;
-                trans = new TSocket("localhost", 9090);
+                trans = new TSocket("localhost", port);
                 trans = new TFramedTransport(trans);
                 trans.Open();
 
@@ -44,44 +43,40 @@
 
                 TMultiplexedProtocol multiplex;
 
-                multiplex = new TMultiplexedProtocol( Protocol, Constants.NAME_BENCHMARKSERVICE);
-                BenchmarkService.Iface bench = new BenchmarkService.Client( multiplex);
+                multiplex = new TMultiplexedProtocol(Protocol, Constants.NAME_BENCHMARKSERVICE);
+                BenchmarkService.Iface bench = new BenchmarkService.Client(multiplex);
 
-                multiplex = new TMultiplexedProtocol( Protocol, Constants.NAME_AGGR);
-                Aggr.Iface aggr = new Aggr.Client( multiplex);
+                multiplex = new TMultiplexedProtocol(Protocol, Constants.NAME_AGGR);
+                Aggr.Iface aggr = new Aggr.Client(multiplex);
 
-                sbyte i;
-                for( i = 1; 10 >= i; ++i)
+                for (sbyte i = 1; 10 >= i; ++i)
                 {
-                    aggr.addValue( bench.fibonacci(i));
+                    aggr.addValue(bench.fibonacci(i));
                 }
 
-                foreach( int k in aggr.getValues())
+                foreach (int k in aggr.getValues())
                 {
-                    Console.Write(k.ToString()+" ");
+                    Console.Write(k.ToString() + " ");
                     Console.WriteLine("");
                 }
+                trans.Close();
             }
-            catch( Exception e)
+            catch (Exception e)
             {
-                Console.WriteLine( e.Message);
+                Console.WriteLine(e.Message);
             }
         }
 
-
-        public static void Execute()
-        {
-            TestClient client = new TestClient();
-            client.Run();
-        }
-
         static void Main(string[] args)
         {
-            Execute();
+            int port = 9090;
+            if (args.Length > 0)
+            {
+                port = ushort.Parse(args[0]);
+            }
+            Execute(port);
             Console.WriteLine("done.");
-            Console.ReadLine();
         }
-
     }
 }
 
diff --git a/lib/csharp/test/Multiplex/Makefile.am b/lib/csharp/test/Multiplex/Makefile.am
new file mode 100644
index 0000000..57253d6
--- /dev/null
+++ b/lib/csharp/test/Multiplex/Makefile.am
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+GENERATED = \
+	gen-csharp/Aggr.cs \
+	gen-csharp/BenchmarkService.cs \
+	gen-csharp/Error.cs
+
+BUILT_SOURCES = $(GENERATED)
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+gen-csharp/Aggr.cs: $(top_srcdir)/contrib/async-test/aggr.thrift
+	$(THRIFT) --gen csharp $<
+
+gen-csharp/BenchmarkService.cs gen-csharp/Error.cs: $(top_srcdir)/lib/rb/benchmark/Benchmark.thrift
+	$(THRIFT) --gen csharp $<
+
+ThriftImpl.dll: Multiplex.Test.Common.cs $(GENERATED) ../../Thrift.dll
+	$(CSC) $(CSC_DEFINES) -t:library -out:./ThriftImpl.dll -reference:../../Thrift.dll $(GENERATED) $<
+
+MultiplexClient.exe: Client/Multiplex.Test.Client.cs ThriftImpl.dll
+	$(CSC) $(CSC_DEFINES) -out:$@ -reference:../../Thrift.dll -reference:ThriftImpl.dll $<
+
+MultiplexServer.exe: Server/Multiplex.Test.Server.cs ThriftImpl.dll
+	$(CSC) $(CSC_DEFINES) -out:$@ -reference:../../Thrift.dll -reference:ThriftImpl.dll $<
+
+clean-local:
+	$(RM) -rf gen-csharp *.exe *.dll
+
+TESTPORT = 9501
+check-local: MultiplexServer.exe MultiplexClient.exe
+	echo $(TESTPORT)
+	MONO_PATH=../../ timeout 10 mono MultiplexServer.exe $(TESTPORT) &
+	sleep 1
+	MONO_PATH=../../ mono MultiplexClient.exe $(TESTPORT)
diff --git a/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs b/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs
index 61c2d7c..9786189 100644
--- a/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs
+++ b/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs
@@ -30,30 +30,14 @@
 {
     public class TestServer
     {
-        public interface ITestHandler
-        {
-            void SetServer( TServer aServer);
-        }
-
-        protected class TestHandlerImpl : ITestHandler
-        {
-            private TServer Server;
-
-            public void SetServer( TServer aServer)
-            {
-                Server = aServer;
-            }
-        }
-
-
-        protected class BenchmarkServiceImpl : TestHandlerImpl, BenchmarkService.Iface
+        class BenchmarkServiceImpl : BenchmarkService.Iface
         {
             public int fibonacci(sbyte n)
             {
                 int prev, next, result;
                 prev   = 0;
                 result = 1;
-                while( n > 0)
+                while (n > 0)
                 {
                     next   = result + prev;
                     prev   = result;
@@ -64,14 +48,13 @@
             }
         }
 
-
-        protected class AggrServiceImpl : TestHandlerImpl,  Aggr.Iface
+        class AggrServiceImpl : Aggr.Iface
         {
             List<int> values = new List<int>();
 
             public void addValue(int value)
             {
-                values.Add( value);
+                values.Add(value);
             }
 
             public List<int> getValues()
@@ -80,52 +63,45 @@
             }
         }
 
-       static void Execute()
-       {
-           try
-           {
-               // create protocol factory, default to BinaryProtocol
-               TProtocolFactory ProtocolFactory = new TBinaryProtocol.Factory(true,true);
-               TServerTransport servertrans     = new TServerSocket( 9090, 0, false);
-               TTransportFactory TransportFactory = new TFramedTransport.Factory();
+        static void Execute(int port)
+        {
+            try
+            {
+                // create protocol factory, default to BinaryProtocol
+                TProtocolFactory ProtocolFactory = new TBinaryProtocol.Factory(true,true);
+                TServerTransport servertrans = new TServerSocket(port, 0, false);
+                TTransportFactory TransportFactory = new TFramedTransport.Factory();
 
-               BenchmarkService.Iface benchHandler = new BenchmarkServiceImpl();
-               TProcessor benchProcessor = new BenchmarkService.Processor( benchHandler);
+                BenchmarkService.Iface benchHandler = new BenchmarkServiceImpl();
+                TProcessor benchProcessor = new BenchmarkService.Processor(benchHandler);
 
-               Aggr.Iface aggrHandler = new AggrServiceImpl();
-               TProcessor aggrProcessor = new Aggr.Processor( aggrHandler);
+                Aggr.Iface aggrHandler = new AggrServiceImpl();
+                TProcessor aggrProcessor = new Aggr.Processor(aggrHandler);
 
-               TMultiplexedProcessor multiplex = new TMultiplexedProcessor();
-               multiplex.RegisterProcessor(Constants.NAME_BENCHMARKSERVICE, benchProcessor);
-               multiplex.RegisterProcessor(Constants.NAME_AGGR, aggrProcessor);
+                TMultiplexedProcessor multiplex = new TMultiplexedProcessor();
+                multiplex.RegisterProcessor(Constants.NAME_BENCHMARKSERVICE, benchProcessor);
+                multiplex.RegisterProcessor(Constants.NAME_AGGR, aggrProcessor);
 
-               TServer ServerEngine = new TSimpleServer( multiplex, servertrans, TransportFactory, ProtocolFactory);
+                TServer ServerEngine = new TSimpleServer(multiplex, servertrans, TransportFactory, ProtocolFactory);
 
-               (benchHandler as ITestHandler).SetServer( ServerEngine);
-               (aggrHandler as ITestHandler).SetServer( ServerEngine);
+                Console.WriteLine("Starting the server ...");
+                ServerEngine.Serve();
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.Message);
+            }
+        }
 
-               Console.WriteLine("Starting the server ...");
-               ServerEngine.Serve();
-
-               (benchHandler as ITestHandler).SetServer(null);
-               (aggrHandler as ITestHandler).SetServer(null);
-
-           }
-           catch( Exception e)
-           {
-               Console.WriteLine( e.Message);
-           }
-           Console.WriteLine( "done.");
-       }
-
-
-       static void Main(string[] args)
-       {
-           Execute();
-       }
+        static void Main(string[] args)
+        {
+            int port = 9090;
+            if (args.Length > 0)
+            {
+                port = ushort.Parse(args[0]);
+            }
+            Execute(port);
+        }
     }
-
-
-
 }
 
diff --git a/lib/csharp/test/Multiplex/maketest.sh b/lib/csharp/test/Multiplex/maketest.sh
deleted file mode 100755
index 1f29ee2..0000000
--- a/lib/csharp/test/Multiplex/maketest.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-
-#
-# 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.
-#
-
-../../../../compiler/cpp/thrift --gen csharp  ../../../../contrib/async-test/aggr.thrift
-../../../../compiler/cpp/thrift --gen csharp  ../../../rb/benchmark/Benchmark.thrift
-gmcs /t:library /out:./ThriftImpl.dll /recurse:./gen-csharp/* /reference:../../Thrift.dll Multiplex.Test.Common.cs
-gmcs  /out:MultiplexClient.exe /reference:../../Thrift.dll /reference:ThriftImpl.dll Client/Multiplex.Test.Client.cs
-gmcs  /out:MultiplexServer.exe /reference:../../Thrift.dll /reference:ThriftImpl.dll Server/Multiplex.Test.Server.cs
-
-
-
-export MONO_PATH=../../
-
-timeout 120 ./MultiplexServer.exe &
-sleep 3;
-./MultiplexClient.exe
diff --git a/lib/csharp/test/ThriftTest/Makefile.am b/lib/csharp/test/ThriftTest/Makefile.am
deleted file mode 100644
index c0014e6..0000000
--- a/lib/csharp/test/ThriftTest/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-THRIFT = $(top_builddir)/compiler/cpp/thrift
-if MONO_MCS
-CSC=mcs
-else
-CSC=gmcs
-endif
-
-stubs: $(top_srcdir)/test/ThriftTest.thrift
-	$(THRIFT) --gen csharp -o . $(top_srcdir)/test/ThriftTest.thrift
-
-precross: TestClientServer.exe
-
-ThriftImpl.dll: stubs
-	$(CSC) /t:library /out:./ThriftImpl.dll /recurse:./gen-csharp/Thrift/Test/*.cs /reference:../../Thrift.dll
-
-TestClientServer.exe: TestClient.cs TestServer.cs Program.cs ThriftImpl.dll
-	$(CSC)  /out:TestClientServer.exe /reference:../../Thrift.dll /reference:ThriftImpl.dll TestClient.cs TestServer.cs Program.cs
diff --git a/lib/csharp/test/ThriftTest/Program.cs b/lib/csharp/test/ThriftTest/Program.cs
deleted file mode 100644
index 8ec00e3..0000000
--- a/lib/csharp/test/ThriftTest/Program.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.
- */
-
-// Distributed under the Thrift Software License
-//
-// See accompanying file LICENSE or visit the Thrift site at:
-// http://developers.facebook.com/thrift/
-
-using System;
-using Thrift.Transport;
-using Thrift.Protocol;
-using Thrift.Test; //generated code
-
-namespace Test
-{
-    class Program
-    {
-        static int Main(string[] args)
-        {
-            if (args.Length == 0)
-            {
-                Console.WriteLine("must provide 'server' or 'client' arg");
-                return -1;
-            }
-
-            try
-            {
-                Console.SetBufferSize(Console.BufferWidth, 4096);
-            }
-            catch (Exception)
-            {
-                Console.WriteLine("Failed to grow scroll-back buffer");
-            }
-
-            string[] subArgs = new string[args.Length - 1];
-            for(int i = 1; i < args.Length; i++)
-            {
-                subArgs[i-1] = args[i];
-            }
-            if (args[0] == "client")
-            {
-                return TestClient.Execute(subArgs);
-            }
-            else if (args[0] == "server")
-            {
-                return TestServer.Execute(subArgs) ? 0 : 1;
-            }
-            else
-            {
-                Console.WriteLine("first argument must be 'server' or 'client'");
-            }
-            return 0;
-        }
-    }
-}
diff --git a/lib/csharp/test/ThriftTest/Properties/AssemblyInfo.cs b/lib/csharp/test/ThriftTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index 504ca8d..0000000
--- a/lib/csharp/test/ThriftTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ThriftTest")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ThriftTest")]
-[assembly: AssemblyCopyright("Copyright © 2009 The Apache Software Foundation")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components.  If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("f41b193b-f1ab-48ee-8843-f88e43084e26")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/lib/csharp/test/ThriftTest/TestClient.cs b/lib/csharp/test/ThriftTest/TestClient.cs
deleted file mode 100644
index cb73597..0000000
--- a/lib/csharp/test/ThriftTest/TestClient.cs
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * 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.
- */
-
-using System;
-using System.Linq;
-using System.Diagnostics;
-using System.Collections.Generic;
-using System.Threading;
-using System.Security.Cryptography.X509Certificates;
-using Thrift.Collections;
-using Thrift.Protocol;
-using Thrift.Transport;
-using Thrift.Test;
-using System.Security.Authentication;
-
-namespace Test
-{
-    public class TestClient
-    {
-        private class TestParams
-        {
-            public int numIterations = 1;
-            public string host = "localhost";
-            public int port = 9090;
-            public string url;
-            public string pipe;
-            public bool buffered;
-            public bool framed;
-            public string protocol;
-            public bool encrypted = false;
-            protected bool _isFirstTransport = true;
-
-
-            public TTransport CreateTransport()
-            {
-                if (url == null)
-                {
-                    // endpoint transport
-                    TTransport trans = null;
-                    if (pipe != null)
-                        trans = new TNamedPipeClientTransport(pipe);
-                    else
-                    {
-                        if (encrypted)
-                        {
-                            string certPath = "../../../../test/keys/client.p12";
-                            X509Certificate cert = new X509Certificate2(certPath, "thrift");
-                            trans = new TTLSSocket(host, port, 0, cert, (o, c, chain, errors) => true, null, SslProtocols.Tls);
-                        }
-                        else
-                        {
-                            trans = new TSocket(host, port);
-                        }
-                    }
-
-                    // layered transport
-                    if (buffered)
-                        trans = new TBufferedTransport(trans);
-                    if (framed)
-                        trans = new TFramedTransport(trans);
-
-                    if (_isFirstTransport)
-                    {
-                        //ensure proper open/close of transport
-                        trans.Open();
-                        trans.Close();
-                        _isFirstTransport = false;
-                    }
-                    return trans;
-                }
-                else
-                {
-                    return new THttpClient(new Uri(url));
-                }
-            }
-
-            public TProtocol CreateProtocol(TTransport transport)
-            {
-                if (protocol == "compact")
-                    return new TCompactProtocol(transport);
-                else if (protocol == "json")
-                    return new TJSONProtocol(transport);
-                else
-                    return new TBinaryProtocol(transport);
-            }
-        };
-
-        private const int ErrorBaseTypes = 1;
-        private const int ErrorStructs = 2;
-        private const int ErrorContainers = 4;
-        private const int ErrorExceptions = 8;
-        private const int ErrorUnknown = 64;
-
-        private class ClientTest
-        {
-            private readonly TTransport transport;
-            private readonly ThriftTest.Client client;
-            private readonly int numIterations;
-            private bool done;
-
-            public int ReturnCode { get; set; }
-
-            public ClientTest(TestParams param)
-            {
-                transport = param.CreateTransport();
-                client = new ThriftTest.Client(param.CreateProtocol(transport));
-                numIterations = param.numIterations;
-            }
-            public void Execute()
-            {
-                if (done)
-                {
-                    Console.WriteLine("Execute called more than once");
-                    throw new InvalidOperationException();
-                }
-
-                for (int i = 0; i < numIterations; i++)
-                {
-                    try
-                    {
-                        if (!transport.IsOpen)
-                            transport.Open();
-                    }
-                    catch (TTransportException ex)
-                    {
-                        Console.WriteLine("*** FAILED ***");
-                        Console.WriteLine("Connect failed: " + ex.Message);
-                        ReturnCode |= ErrorUnknown;
-                        Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-                        continue;
-                    }
-
-                    try
-                    {
-                        ReturnCode |= ExecuteClientTest(client);
-                    }
-                    catch (Exception ex)
-                    {
-                        Console.WriteLine("*** FAILED ***");
-                        Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-                        ReturnCode |= ErrorUnknown;
-                    }
-                }
-                try
-                {
-                    transport.Close();
-                }
-                catch(Exception ex)
-                {
-                    Console.WriteLine("Error while closing transport");
-                    Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-                }
-                done = true;
-            }
-        }
-
-        public static int Execute(string[] args)
-        {
-            try
-            {
-                TestParams param = new TestParams();
-                int numThreads = 1;
-                try
-                {
-                    for (int i = 0; i < args.Length; i++)
-                    {
-                        if (args[i] == "-u")
-                        {
-                            param.url = args[++i];
-                        }
-                        else if (args[i] == "-n")
-                        {
-                            param.numIterations = Convert.ToInt32(args[++i]);
-                        }
-                        else if (args[i] == "-pipe")  // -pipe <name>
-                        {
-                            param.pipe = args[++i];
-                            Console.WriteLine("Using named pipes transport");
-                        }
-                        else if (args[i].Contains("--host="))
-                        {
-                            param.host = args[i].Substring(args[i].IndexOf("=") + 1);
-                        }
-                        else if (args[i].Contains("--port="))
-                        {
-                            param.port = int.Parse(args[i].Substring(args[i].IndexOf("=")+1));
-                        }
-                        else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
-                        {
-                            param.buffered = true;
-                            Console.WriteLine("Using buffered sockets");
-                        }
-                        else if (args[i] == "-f" || args[i] == "--framed"  || args[i] == "--transport=framed")
-                        {
-                            param.framed = true;
-                            Console.WriteLine("Using framed transport");
-                        }
-                        else if (args[i] == "-t")
-                        {
-                            numThreads = Convert.ToInt32(args[++i]);
-                        }
-                        else if (args[i] == "--compact" || args[i] == "--protocol=compact")
-                        {
-                            param.protocol = "compact";
-                            Console.WriteLine("Using compact protocol");
-                        }
-                        else if (args[i] == "--json" || args[i] == "--protocol=json")
-                        {
-                            param.protocol = "json";
-                            Console.WriteLine("Using JSON protocol");
-                        }
-                        else if (args[i] == "--ssl")
-                        {
-                            param.encrypted = true;
-                            Console.WriteLine("Using encrypted transport");
-                        }
-                    }
-                }
-                catch (Exception ex)
-                {
-                    Console.WriteLine("*** FAILED ***");
-                    Console.WriteLine("Error while  parsing arguments");
-                    Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-                    return ErrorUnknown;
-                }
-
-                var tests = Enumerable.Range(0, numThreads).Select(_ => new ClientTest(param)).ToArray();
-                //issue tests on separate threads simultaneously
-                var threads = tests.Select(test => new Thread(test.Execute)).ToArray();
-                DateTime start = DateTime.Now;
-                foreach (var t in threads)
-                    t.Start();
-                foreach (var t in threads)
-                    t.Join();
-                Console.WriteLine("Total time: " + (DateTime.Now - start));
-                Console.WriteLine();
-                return tests.Select(t => t.ReturnCode).Aggregate((r1, r2) => r1 | r2);
-            }
-            catch (Exception outerEx)
-            {
-                Console.WriteLine("*** FAILED ***");
-                Console.WriteLine("Unexpected error");
-                Console.WriteLine(outerEx.Message + " ST: " + outerEx.StackTrace);
-                return ErrorUnknown;
-            }
-        }
-
-        public static string BytesToHex(byte[] data) {
-            return BitConverter.ToString(data).Replace("-", string.Empty);
-        }
-
-        public static byte[] PrepareTestData(bool randomDist)
-        {
-            byte[] retval = new byte[0x100];
-            int initLen = Math.Min(0x100,retval.Length);
-
-            // linear distribution, unless random is requested
-            if (!randomDist) {
-                for (var i = 0; i < initLen; ++i) {
-                    retval[i] = (byte)i;
-                }
-                return retval;
-            }
-
-            // random distribution
-            for (var i = 0; i < initLen; ++i) {
-                retval[i] = (byte)0;
-            }
-            var rnd = new Random();
-            for (var i = 1; i < initLen; ++i) {
-                while( true) {
-                    int nextPos = rnd.Next() % initLen;
-                    if (retval[nextPos] == 0) {
-                        retval[nextPos] = (byte)i;
-                        break;
-                    }
-                }
-            }
-            return retval;
-        }
-
-        public static int ExecuteClientTest(ThriftTest.Client client)
-        {
-            int returnCode = 0;
-
-            Console.Write("testVoid()");
-            client.testVoid();
-            Console.WriteLine(" = void");
-
-            Console.Write("testString(\"Test\")");
-            string s = client.testString("Test");
-            Console.WriteLine(" = \"" + s + "\"");
-            if ("Test" != s)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-
-            Console.Write("testBool(true)");
-            bool t = client.testBool((bool)true);
-            Console.WriteLine(" = " + t);
-            if (!t)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-            Console.Write("testBool(false)");
-            bool f = client.testBool((bool)false);
-            Console.WriteLine(" = " + f);
-            if (f)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-
-            Console.Write("testByte(1)");
-            sbyte i8 = client.testByte((sbyte)1);
-            Console.WriteLine(" = " + i8);
-            if (1 != i8)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-
-            Console.Write("testI32(-1)");
-            int i32 = client.testI32(-1);
-            Console.WriteLine(" = " + i32);
-            if (-1 != i32)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-
-            Console.Write("testI64(-34359738368)");
-            long i64 = client.testI64(-34359738368);
-            Console.WriteLine(" = " + i64);
-            if (-34359738368 != i64)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-
-            // TODO: Validate received message
-            Console.Write("testDouble(5.325098235)");
-            double dub = client.testDouble(5.325098235);
-            Console.WriteLine(" = " + dub);
-            if (5.325098235 != dub)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-            Console.Write("testDouble(-0.000341012439638598279)");
-            dub = client.testDouble(-0.000341012439638598279);
-            Console.WriteLine(" = " + dub);
-            if (-0.000341012439638598279 != dub)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-
-            byte[] binOut = PrepareTestData(true);
-            Console.Write("testBinary(" + BytesToHex(binOut) + ")");
-            try
-            {
-                byte[] binIn = client.testBinary(binOut);
-                Console.WriteLine(" = " + BytesToHex(binIn));
-                if (binIn.Length != binOut.Length)
-                {
-                    Console.WriteLine("*** FAILED ***");
-                    returnCode |= ErrorBaseTypes;
-                }
-                for (int ofs = 0; ofs < Math.Min(binIn.Length, binOut.Length); ++ofs)
-                    if (binIn[ofs] != binOut[ofs])
-                    {
-                        Console.WriteLine("*** FAILED ***");
-                        returnCode |= ErrorBaseTypes;
-                    }
-            }
-            catch (Thrift.TApplicationException ex)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-                Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-            }
-
-            // binary equals? only with hashcode option enabled ...
-            Console.WriteLine("Test CrazyNesting");
-            if( typeof(CrazyNesting).GetMethod("Equals").DeclaringType == typeof(CrazyNesting))
-            {
-                CrazyNesting one = new CrazyNesting();
-                CrazyNesting two = new CrazyNesting();
-                one.String_field = "crazy";
-                two.String_field = "crazy";
-                one.Binary_field = new byte[10] { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF };
-                two.Binary_field = new byte[10] { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF };
-                if (!one.Equals(two))
-                {
-                    Console.WriteLine("*** FAILED ***");
-                    returnCode |= ErrorContainers;
-                    throw new Exception("CrazyNesting.Equals failed");
-                }
-            }
-
-            // TODO: Validate received message
-            Console.Write("testStruct({\"Zero\", 1, -3, -5})");
-            Xtruct o = new Xtruct();
-            o.String_thing = "Zero";
-            o.Byte_thing = (sbyte)1;
-            o.I32_thing = -3;
-            o.I64_thing = -5;
-            Xtruct i = client.testStruct(o);
-            Console.WriteLine(" = {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}");
-
-            // TODO: Validate received message
-            Console.Write("testNest({1, {\"Zero\", 1, -3, -5}, 5})");
-            Xtruct2 o2 = new Xtruct2();
-            o2.Byte_thing = (sbyte)1;
-            o2.Struct_thing = o;
-            o2.I32_thing = 5;
-            Xtruct2 i2 = client.testNest(o2);
-            i = i2.Struct_thing;
-            Console.WriteLine(" = {" + i2.Byte_thing + ", {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}, " + i2.I32_thing + "}");
-
-            Dictionary<int, int> mapout = new Dictionary<int, int>();
-            for (int j = 0; j < 5; j++)
-            {
-                mapout[j] = j - 10;
-            }
-            Console.Write("testMap({");
-            bool first = true;
-            foreach (int key in mapout.Keys)
-            {
-                if (first)
-                {
-                    first = false;
-                }
-                else
-                {
-                    Console.Write(", ");
-                }
-                Console.Write(key + " => " + mapout[key]);
-            }
-            Console.Write("})");
-
-            Dictionary<int, int> mapin = client.testMap(mapout);
-
-            Console.Write(" = {");
-            first = true;
-            foreach (int key in mapin.Keys)
-            {
-                if (first)
-                {
-                    first = false;
-                }
-                else
-                {
-                    Console.Write(", ");
-                }
-                Console.Write(key + " => " + mapin[key]);
-            }
-            Console.WriteLine("}");
-
-            // TODO: Validate received message
-            List<int> listout = new List<int>();
-            for (int j = -2; j < 3; j++)
-            {
-                listout.Add(j);
-            }
-            Console.Write("testList({");
-            first = true;
-            foreach (int j in listout)
-            {
-                if (first)
-                {
-                    first = false;
-                }
-                else
-                {
-                    Console.Write(", ");
-                }
-                Console.Write(j);
-            }
-            Console.Write("})");
-
-            List<int> listin = client.testList(listout);
-
-            Console.Write(" = {");
-            first = true;
-            foreach (int j in listin)
-            {
-                if (first)
-                {
-                    first = false;
-                }
-                else
-                {
-                    Console.Write(", ");
-                }
-                Console.Write(j);
-            }
-            Console.WriteLine("}");
-
-            //set
-            // TODO: Validate received message
-            THashSet<int> setout = new THashSet<int>();
-            for (int j = -2; j < 3; j++)
-            {
-                setout.Add(j);
-            }
-            Console.Write("testSet({");
-            first = true;
-            foreach (int j in setout)
-            {
-                if (first)
-                {
-                    first = false;
-                }
-                else
-                {
-                    Console.Write(", ");
-                }
-                Console.Write(j);
-            }
-            Console.Write("})");
-
-            THashSet<int> setin = client.testSet(setout);
-
-            Console.Write(" = {");
-            first = true;
-            foreach (int j in setin)
-            {
-                if (first)
-                {
-                    first = false;
-                }
-                else
-                {
-                    Console.Write(", ");
-                }
-                Console.Write(j);
-            }
-            Console.WriteLine("}");
-
-
-            Console.Write("testEnum(ONE)");
-            Numberz ret = client.testEnum(Numberz.ONE);
-            Console.WriteLine(" = " + ret);
-            if (Numberz.ONE != ret)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorStructs;
-            }
-
-            Console.Write("testEnum(TWO)");
-            ret = client.testEnum(Numberz.TWO);
-            Console.WriteLine(" = " + ret);
-            if (Numberz.TWO != ret)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorStructs;
-            }
-
-            Console.Write("testEnum(THREE)");
-            ret = client.testEnum(Numberz.THREE);
-            Console.WriteLine(" = " + ret);
-            if (Numberz.THREE != ret)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorStructs;
-            }
-
-            Console.Write("testEnum(FIVE)");
-            ret = client.testEnum(Numberz.FIVE);
-            Console.WriteLine(" = " + ret);
-            if (Numberz.FIVE != ret)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorStructs;
-            }
-
-            Console.Write("testEnum(EIGHT)");
-            ret = client.testEnum(Numberz.EIGHT);
-            Console.WriteLine(" = " + ret);
-            if (Numberz.EIGHT != ret)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorStructs;
-            }
-
-            Console.Write("testTypedef(309858235082523)");
-            long uid = client.testTypedef(309858235082523L);
-            Console.WriteLine(" = " + uid);
-            if (309858235082523L != uid)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorStructs;
-            }
-
-            // TODO: Validate received message
-            Console.Write("testMapMap(1)");
-            Dictionary<int, Dictionary<int, int>> mm = client.testMapMap(1);
-            Console.Write(" = {");
-            foreach (int key in mm.Keys)
-            {
-                Console.Write(key + " => {");
-                Dictionary<int, int> m2 = mm[key];
-                foreach (int k2 in m2.Keys)
-                {
-                    Console.Write(k2 + " => " + m2[k2] + ", ");
-                }
-                Console.Write("}, ");
-            }
-            Console.WriteLine("}");
-
-            // TODO: Validate received message
-            Insanity insane = new Insanity();
-            insane.UserMap = new Dictionary<Numberz, long>();
-            insane.UserMap[Numberz.FIVE] = 5000L;
-            Xtruct truck = new Xtruct();
-            truck.String_thing = "Truck";
-            truck.Byte_thing = (sbyte)8;
-            truck.I32_thing = 8;
-            truck.I64_thing = 8;
-            insane.Xtructs = new List<Xtruct>();
-            insane.Xtructs.Add(truck);
-            Console.Write("testInsanity()");
-            Dictionary<long, Dictionary<Numberz, Insanity>> whoa = client.testInsanity(insane);
-            Console.Write(" = {");
-            foreach (long key in whoa.Keys)
-            {
-                Dictionary<Numberz, Insanity> val = whoa[key];
-                Console.Write(key + " => {");
-
-                foreach (Numberz k2 in val.Keys)
-                {
-                    Insanity v2 = val[k2];
-
-                    Console.Write(k2 + " => {");
-                    Dictionary<Numberz, long> userMap = v2.UserMap;
-
-                    Console.Write("{");
-                    if (userMap != null)
-                    {
-                        foreach (Numberz k3 in userMap.Keys)
-                        {
-                            Console.Write(k3 + " => " + userMap[k3] + ", ");
-                        }
-                    }
-                    else
-                    {
-                        Console.Write("null");
-                    }
-                    Console.Write("}, ");
-
-                    List<Xtruct> xtructs = v2.Xtructs;
-
-                    Console.Write("{");
-                    if (xtructs != null)
-                    {
-                        foreach (Xtruct x in xtructs)
-                        {
-                            Console.Write("{\"" + x.String_thing + "\", " + x.Byte_thing + ", " + x.I32_thing + ", " + x.I32_thing + "}, ");
-                        }
-                    }
-                    else
-                    {
-                        Console.Write("null");
-                    }
-                    Console.Write("}");
-
-                    Console.Write("}, ");
-                }
-                Console.Write("}, ");
-            }
-            Console.WriteLine("}");
-
-            sbyte arg0 = 1;
-            int arg1 = 2;
-            long arg2 = long.MaxValue;
-            Dictionary<short, string> multiDict = new Dictionary<short, string>();
-            multiDict[1] = "one";
-            Numberz arg4 = Numberz.FIVE;
-            long arg5 = 5000000;
-            Console.Write("Test Multi(" + arg0 + "," + arg1 + "," + arg2 + "," + multiDict + "," + arg4 + "," + arg5 + ")");
-            Xtruct multiResponse = client.testMulti(arg0, arg1, arg2, multiDict, arg4, arg5);
-            Console.Write(" = Xtruct(byte_thing:" + multiResponse.Byte_thing + ",String_thing:" + multiResponse.String_thing
-                        + ",i32_thing:" + multiResponse.I32_thing + ",i64_thing:" + multiResponse.I64_thing + ")\n");
-
-            try
-            {
-                Console.WriteLine("testException(\"Xception\")");
-                client.testException("Xception");
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-            }
-            catch (Xception ex)
-            {
-                if (ex.ErrorCode != 1001 || ex.Message != "Xception")
-                {
-                    Console.WriteLine("*** FAILED ***");
-                    returnCode |= ErrorExceptions;
-                }
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-                Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-            }
-            try
-            {
-                Console.WriteLine("testException(\"TException\")");
-                client.testException("TException");
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-            }
-            catch (Thrift.TException)
-            {
-                // OK
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-                Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-            }
-            try
-            {
-                Console.WriteLine("testException(\"ok\")");
-                client.testException("ok");
-                // OK
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-                Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-            }
-
-            try
-            {
-                Console.WriteLine("testMultiException(\"Xception\", ...)");
-                client.testMultiException("Xception", "ignore");
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-            }
-            catch (Xception ex)
-            {
-                if (ex.ErrorCode != 1001 || ex.Message != "This is an Xception")
-                {
-                    Console.WriteLine("*** FAILED ***");
-                    returnCode |= ErrorExceptions;
-                }
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-                Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-            }
-            try
-            {
-                Console.WriteLine("testMultiException(\"Xception2\", ...)");
-                client.testMultiException("Xception2", "ignore");
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-            }
-            catch (Xception2 ex)
-            {
-                if (ex.ErrorCode != 2002 || ex.Struct_thing.String_thing != "This is an Xception2")
-                {
-                    Console.WriteLine("*** FAILED ***");
-                    returnCode |= ErrorExceptions;
-                }
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-                Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-            }
-            try
-            {
-                Console.WriteLine("testMultiException(\"success\", \"OK\")");
-                if ("OK" != client.testMultiException("success", "OK").String_thing)
-                {
-                    Console.WriteLine("*** FAILED ***");
-                    returnCode |= ErrorExceptions;
-                }
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorExceptions;
-                Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
-            }
-
-            Stopwatch sw = new Stopwatch();
-            sw.Start();
-            Console.WriteLine("Test Oneway(1)");
-            client.testOneway(1);
-            sw.Stop();
-            if (sw.ElapsedMilliseconds > 1000)
-            {
-                Console.WriteLine("*** FAILED ***");
-                returnCode |= ErrorBaseTypes;
-            }
-
-            Console.Write("Test Calltime()");
-            var startt = DateTime.UtcNow;
-            for ( int k=0; k<1000; ++k )
-                client.testVoid();
-            Console.WriteLine(" = " + (DateTime.UtcNow - startt).TotalSeconds.ToString() + " ms a testVoid() call" );
-            return returnCode;
-        }
-    }
-}
diff --git a/lib/csharp/test/ThriftTest/TestServer.cs b/lib/csharp/test/ThriftTest/TestServer.cs
deleted file mode 100644
index e51ae92..0000000
--- a/lib/csharp/test/ThriftTest/TestServer.cs
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * 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.
- */
-
-// Distributed under the Thrift Software License
-//
-// See accompanying file LICENSE or visit the Thrift site at:
-// http://developers.facebook.com/thrift/
-using System;
-using System.Collections.Generic;
-using System.Security.Cryptography.X509Certificates;
-using Thrift.Collections;
-using Thrift.Test; //generated code
-using Thrift.Transport;
-using Thrift.Protocol;
-using Thrift.Server;
-using Thrift;
-using System.Threading;
-using System.Text;
-using System.Security.Authentication;
-
-namespace Test
-{
-    public class TestServer
-    {
-        public static int _clientID = -1;
-        public delegate void TestLogDelegate(string msg, params object[] values);
-
-    public class TradeServerEventHandler : 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++;
-      }
-    };
-
-        public class TestHandler : ThriftTest.Iface, Thrift.TControllingHandler
-        {
-            public TServer server { get; set; }
-            private int handlerID;
-            private StringBuilder reusableStringBuilder = new StringBuilder();
-            private TestLogDelegate testLogDelegate;
-
-            public TestHandler()
-            {
-                handlerID = Interlocked.Increment(ref _clientID);
-                testLogDelegate += testConsoleLogger;
-                testLogDelegate.Invoke("New TestHandler instance created");
-            }
-
-            public void testConsoleLogger(string msg, params object[] values)
-            {
-                reusableStringBuilder.Clear();
-                reusableStringBuilder.AppendFormat("handler{0:D3}:",handlerID);
-                reusableStringBuilder.AppendFormat(msg, values);
-                reusableStringBuilder.AppendLine();
-                Console.Write( reusableStringBuilder.ToString() );
-            }
-
-            public void testVoid()
-            {
-                testLogDelegate.Invoke("testVoid()");
-            }
-
-            public string testString(string thing)
-            {
-                testLogDelegate.Invoke("testString({0})", thing);
-                return thing;
-            }
-
-            public bool testBool(bool thing)
-            {
-                testLogDelegate.Invoke("testBool({0})", thing);
-                return thing;
-            }
-
-            public sbyte testByte(sbyte thing)
-            {
-                testLogDelegate.Invoke("testByte({0})", thing);
-                return thing;
-            }
-
-            public int testI32(int thing)
-            {
-                testLogDelegate.Invoke("testI32({0})", thing);
-                return thing;
-            }
-
-            public long testI64(long thing)
-            {
-                testLogDelegate.Invoke("testI64({0})", thing);
-                return thing;
-            }
-
-            public double testDouble(double thing)
-            {
-                testLogDelegate.Invoke("testDouble({0})", thing);
-                return thing;
-            }
-
-            public byte[] testBinary(byte[] thing)
-            {
-                string hex = BitConverter.ToString(thing).Replace("-", string.Empty);
-                testLogDelegate.Invoke("testBinary({0:X})", hex);
-                return thing;
-            }
-
-            public Xtruct testStruct(Xtruct thing)
-            {
-                testLogDelegate.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing.String_thing, thing.Byte_thing, thing.I32_thing, thing.I64_thing);
-                return thing;
-            }
-
-            public Xtruct2 testNest(Xtruct2 nest)
-            {
-                Xtruct thing = nest.Struct_thing;
-                testLogDelegate.Invoke("testNest({{{0}, {{\"{1}\", {2}, {3}, {4}, {5}}}}})",
-                                 nest.Byte_thing,
-                                 thing.String_thing,
-                                 thing.Byte_thing,
-                                 thing.I32_thing,
-                                 thing.I64_thing,
-                                 nest.I32_thing);
-                return nest;
-            }
-
-            public Dictionary<int, int> testMap(Dictionary<int, int> thing)
-            {
-                reusableStringBuilder.Clear();
-                reusableStringBuilder.Append("testMap({{");
-                bool first = true;
-                foreach (int key in thing.Keys)
-                {
-                    if (first)
-                    {
-                        first = false;
-                    }
-                    else
-                    {
-                        reusableStringBuilder.Append(", ");
-                    }
-                    reusableStringBuilder.AppendFormat("{0} => {1}", key, thing[key]);
-                }
-                reusableStringBuilder.Append("}})");
-                testLogDelegate.Invoke(reusableStringBuilder.ToString());
-                return thing;
-            }
-
-            public Dictionary<string, string> testStringMap(Dictionary<string, string> thing)
-            {
-                reusableStringBuilder.Clear();
-                reusableStringBuilder.Append("testStringMap({{");
-                bool first = true;
-                foreach (string key in thing.Keys)
-                {
-                    if (first)
-                    {
-                        first = false;
-                    }
-                    else
-                    {
-                        reusableStringBuilder.Append(", ");
-                    }
-                    reusableStringBuilder.AppendFormat("{0} => {1}", key, thing[key]);
-                }
-                reusableStringBuilder.Append("}})");
-                testLogDelegate.Invoke(reusableStringBuilder.ToString());
-                return thing;
-            }
-
-            public THashSet<int> testSet(THashSet<int> thing)
-            {
-                reusableStringBuilder.Clear();
-                reusableStringBuilder.Append("testSet({{");
-                bool first = true;
-                foreach (int elem in thing)
-                {
-                    if (first)
-                    {
-                        first = false;
-                    }
-                    else
-                    {
-                        reusableStringBuilder.Append(", ");
-                    }
-                    reusableStringBuilder.AppendFormat("{0}", elem);
-                }
-                reusableStringBuilder.Append("}})");
-                testLogDelegate.Invoke(reusableStringBuilder.ToString());
-                return thing;
-            }
-
-            public List<int> testList(List<int> thing)
-            {
-                reusableStringBuilder.Clear();
-                reusableStringBuilder.Append("testList({{");
-                bool first = true;
-                foreach (int elem in thing)
-                {
-                    if (first)
-                    {
-                        first = false;
-                    }
-                    else
-                    {
-                        reusableStringBuilder.Append(", ");
-                    }
-                    reusableStringBuilder.AppendFormat("{0}", elem);
-                }
-                reusableStringBuilder.Append("}})");
-                testLogDelegate.Invoke(reusableStringBuilder.ToString());
-                return thing;
-            }
-
-            public Numberz testEnum(Numberz thing)
-            {
-                testLogDelegate.Invoke("testEnum({0})", thing);
-                return thing;
-            }
-
-            public long testTypedef(long thing)
-            {
-                testLogDelegate.Invoke("testTypedef({0})", thing);
-                return thing;
-            }
-
-            public Dictionary<int, Dictionary<int, int>> testMapMap(int hello)
-            {
-                testLogDelegate.Invoke("testMapMap({0})", hello);
-                Dictionary<int, Dictionary<int, int>> mapmap =
-                  new Dictionary<int, Dictionary<int, int>>();
-
-                Dictionary<int, int> pos = new Dictionary<int, int>();
-                Dictionary<int, int> neg = new Dictionary<int, int>();
-                for (int i = 1; i < 5; i++)
-                {
-                    pos[i] = i;
-                    neg[-i] = -i;
-                }
-
-                mapmap[4] = pos;
-                mapmap[-4] = neg;
-
-                return mapmap;
-            }
-
-            public Dictionary<long, Dictionary<Numberz, Insanity>> testInsanity(Insanity argument)
-            {
-                testLogDelegate.Invoke("testInsanity()");
-
-                Xtruct hello = new Xtruct();
-                hello.String_thing = "Hello2";
-                hello.Byte_thing = 2;
-                hello.I32_thing = 2;
-                hello.I64_thing = 2;
-
-                Xtruct goodbye = new Xtruct();
-                goodbye.String_thing = "Goodbye4";
-                goodbye.Byte_thing = (sbyte)4;
-                goodbye.I32_thing = 4;
-                goodbye.I64_thing = (long)4;
-
-                Insanity crazy = new Insanity();
-                crazy.UserMap = new Dictionary<Numberz, long>();
-                crazy.UserMap[Numberz.EIGHT] = (long)8;
-                crazy.Xtructs = new List<Xtruct>();
-                crazy.Xtructs.Add(goodbye);
-
-                Insanity looney = new Insanity();
-                crazy.UserMap[Numberz.FIVE] = (long)5;
-                crazy.Xtructs.Add(hello);
-
-                Dictionary<Numberz, Insanity> first_map = new Dictionary<Numberz, Insanity>();
-                Dictionary<Numberz, Insanity> second_map = new Dictionary<Numberz, Insanity>(); ;
-
-                first_map[Numberz.TWO] = crazy;
-                first_map[Numberz.THREE] = crazy;
-
-                second_map[Numberz.SIX] = looney;
-
-                Dictionary<long, Dictionary<Numberz, Insanity>> insane =
-                  new Dictionary<long, Dictionary<Numberz, Insanity>>();
-                insane[(long)1] = first_map;
-                insane[(long)2] = second_map;
-
-                return insane;
-            }
-
-            public Xtruct testMulti(sbyte arg0, int arg1, long arg2, Dictionary<short, string> arg3, Numberz arg4, long arg5)
-            {
-                testLogDelegate.Invoke("testMulti()");
-
-                Xtruct 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
-             */
-            public void testException(string arg)
-            {
-                testLogDelegate.Invoke("testException({0})", arg);
-                if (arg == "Xception")
-                {
-                    Xception x = new Xception();
-                    x.ErrorCode = 1001;
-                    x.Message = arg;
-                    throw x;
-                }
-                if (arg == "TException")
-                {
-                    throw new Thrift.TException();
-                }
-                return;
-            }
-
-            public Xtruct testMultiException(string arg0, string arg1)
-            {
-                testLogDelegate.Invoke("testMultiException({0}, {1})", arg0,arg1);
-                if (arg0 == "Xception")
-                {
-                    Xception x = new Xception();
-                    x.ErrorCode = 1001;
-                    x.Message = "This is an Xception";
-                    throw x;
-                }
-                else if (arg0 == "Xception2")
-                {
-                    Xception2 x = new Xception2();
-                    x.ErrorCode = 2002;
-                    x.Struct_thing = new Xtruct();
-                    x.Struct_thing.String_thing = "This is an Xception2";
-                    throw x;
-                }
-
-                Xtruct result = new Xtruct();
-                result.String_thing = arg1;
-                return result;
-            }
-
-            public void testStop()
-            {
-                if (server != null)
-                {
-                    server.Stop();
-                }
-            }
-
-            public void testOneway(int arg)
-            {
-                testLogDelegate.Invoke("testOneway({0}), sleeping...", arg);
-                System.Threading.Thread.Sleep(arg * 1000);
-                testLogDelegate.Invoke("testOneway finished");
-            }
-
-        } // class TestHandler
-
-        private enum ServerType
-        {
-            TSimpleServer,
-            TThreadedServer,
-            TThreadPoolServer,
-        }
-
-        private enum ProcessorFactoryType
-        {
-            TSingletonProcessorFactory,
-            TPrototypeProcessorFactory,
-        }
-
-        public static bool Execute(string[] args)
-        {
-            try
-            {
-                bool useBufferedSockets = false, useFramed = false, useEncryption = false, compact = false, json = false;
-                ServerType serverType = ServerType.TSimpleServer;
-                ProcessorFactoryType processorFactoryType = ProcessorFactoryType.TSingletonProcessorFactory;
-                int port = 9090;
-                string pipe = null;
-                for (int i = 0; i < args.Length; i++)
-                {
-                    if (args[i] == "-pipe")  // -pipe name
-                    {
-                        pipe = args[++i];
-                    }
-                    else if (args[i].Contains("--port="))
-                    {
-                        port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1));
-                    }
-                    else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
-                    {
-                        useBufferedSockets = true;
-                    }
-                    else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed")
-                    {
-                        useFramed = true;
-                    }
-                    else if (args[i] == "--compact" || args[i] == "--protocol=compact")
-                    {
-                        compact = true;
-                    }
-                    else if (args[i] == "--json" || args[i] == "--protocol=json")
-                    {
-                        json = true;
-                    }
-                    else if (args[i] == "--threaded" || args[i] == "--server-type=threaded")
-                    {
-                        serverType = ServerType.TThreadedServer;
-                    }
-                    else if (args[i] == "--threadpool" || args[i] == "--server-type=threadpool")
-                    {
-                        serverType = ServerType.TThreadPoolServer;
-                    }
-                    else if (args[i] == "--prototype" || args[i] == "--processor=prototype")
-                    {
-                        processorFactoryType = ProcessorFactoryType.TPrototypeProcessorFactory;
-                    }
-                    else if (args[i] == "--ssl")
-                    {
-                        useEncryption = true;
-                    }
-                }
-
-                // Transport
-                TServerTransport trans;
-                if (pipe != null)
-                {
-                    trans = new TNamedPipeServerTransport(pipe);
-                }
-                else
-                {
-                    if (useEncryption)
-                    {
-                        string certPath = "../../../../test/keys/server.p12";
-                        trans = new TTLSServerSocket(port, 0, useBufferedSockets, new X509Certificate2(certPath, "thrift"), null, null, SslProtocols.Tls);
-                    }
-                    else
-                    {
-                        trans = new TServerSocket(port, 0, useBufferedSockets);
-                    }
-                }
-
-                TProtocolFactory proto;
-                if (compact)
-                    proto = new TCompactProtocol.Factory();
-                else if (json)
-                    proto = new TJSONProtocol.Factory();
-                else
-                    proto = new TBinaryProtocol.Factory();
-
-                TProcessorFactory processorFactory;
-                if (processorFactoryType == ProcessorFactoryType.TPrototypeProcessorFactory)
-                {
-                    processorFactory = new TPrototypeProcessorFactory<ThriftTest.Processor, TestHandler>();
-                }
-                else
-                {
-                    // Processor
-                    TestHandler testHandler = new TestHandler();
-                    ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler);
-                    processorFactory = new TSingletonProcessorFactory(testProcessor);
-                }
-
-                TTransportFactory transFactory;
-                if (useFramed)
-                    transFactory = new TFramedTransport.Factory();
-                else
-                    transFactory = new TTransportFactory();
-
-                TServer serverEngine;
-                switch (serverType)
-                {
-                    case ServerType.TThreadPoolServer:
-                        serverEngine = new TThreadPoolServer(processorFactory, trans, transFactory, proto);
-                        break;
-                    case ServerType.TThreadedServer:
-                        serverEngine = new TThreadedServer(processorFactory, trans, transFactory, proto);
-                        break;
-                    default:
-                        serverEngine = new TSimpleServer(processorFactory, trans, transFactory, proto);
-                        break;
-                }
-
-                //Server event handler
-                TradeServerEventHandler serverEvents = new TradeServerEventHandler();
-                serverEngine.setEventHandler(serverEvents);
-
-                // Run it
-                string where = (pipe != null ? "on pipe " + pipe : "on port " + port);
-                Console.WriteLine("Starting the " + serverType.ToString() + " " + where +
-                    (processorFactoryType == ProcessorFactoryType.TPrototypeProcessorFactory ? " with processor prototype factory " : "") +
-                    (useBufferedSockets ? " with buffered socket" : "") +
-                    (useFramed ? " with framed transport" : "") +
-                    (useEncryption ? " with encryption" : "") +
-                    (compact ? " with compact protocol" : "") +
-                    (json ? " with json protocol" : "") +
-                    "...");
-                serverEngine.Serve();
-
-            }
-            catch (Exception x)
-            {
-                Console.Error.Write(x);
-                return false;
-            }
-            Console.WriteLine("done.");
-            return true;
-        }
-    }
-}
diff --git a/lib/csharp/test/ThriftTest/ThriftTest.csproj b/lib/csharp/test/ThriftTest/ThriftTest.csproj
deleted file mode 100644
index d671997..0000000
--- a/lib/csharp/test/ThriftTest/ThriftTest.csproj
+++ /dev/null
@@ -1,141 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<!--
-  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.
--->
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.21022</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>ThriftTest</RootNamespace>
-    <AssemblyName>ThriftTest</AssemblyName>
-    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>3.5</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="ThriftImpl, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>.\ThriftImpl.dll</HintPath>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="TestClient.cs" />
-    <Compile Include="TestServer.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
-      <Visible>False</Visible>
-      <ProductName>Windows Installer 3.1</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\src\Thrift.csproj">
-      <Project>{499EB63C-D74C-47E8-AE48-A2FC94538E9D}</Project>
-      <Name>Thrift</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-  <PropertyGroup>
-    <PreBuildEvent>rmdir /s /q "$(ProjectDir)gen-csharp"
-del /f /q "$(ProjectDir)ThriftImpl.dll"
-SET OUTPUT_DIR=$(ProjectDir)
-SET THRIFT_FILE=$(ProjectDir)\..\..\..\..\test\ThriftTest.thrift
-for %25%25I in ("%25OUTPUT_DIR%25") do set SHORT_DIR=%25%25~fsI
-for %25%25I in ("%25THRIFT_FILE%25") do set THRIFT_SHORT=%25%25~fsI
-"$(ProjectDir)\..\..\..\..\compiler\cpp\thrift.exe" --gen csharp -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
-$(MSBuildToolsPath)\Csc.exe /t:library /out:"$(ProjectDir)ThriftImpl.dll" /recurse:"$(ProjectDir)gen-csharp"\* /reference:"$(ProjectDir)..\..\src\bin\Debug\Thrift.dll"</PreBuildEvent>
-  </PropertyGroup>
-</Project>
\ No newline at end of file
diff --git a/lib/csharp/test/ThriftTest/maketest.sh b/lib/csharp/test/ThriftTest/maketest.sh
deleted file mode 100755
index 210a523..0000000
--- a/lib/csharp/test/ThriftTest/maketest.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-
-#
-# 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.
-#
-
-../../../../compiler/cpp/thrift --gen csharp -o . ../../../../test/ThriftTest.thrift
-gmcs /t:library /out:./ThriftImpl.dll /recurse:./gen-csharp/* /reference:../../Thrift.dll
-gmcs  /out:TestClientServer.exe /reference:../../Thrift.dll /reference:ThriftImpl.dll TestClient.cs TestServer.cs Program.cs
-
-export MONO_PATH=../../
-
-timeout 120 ./TestClientServer.exe server &
-sleep 1
-./TestClientServer.exe client
