Revert "THRIFT-4982 Remove deprecated C# bindings from the code base"

Only compiler, test, lib and tutorial code.
diff --git a/lib/csharp/src/Transport/TBufferedTransport.cs b/lib/csharp/src/Transport/TBufferedTransport.cs
new file mode 100644
index 0000000..8870988
--- /dev/null
+++ b/lib/csharp/src/Transport/TBufferedTransport.cs
@@ -0,0 +1,194 @@
+/**
+ * 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.IO;
+
+namespace Thrift.Transport
+{
+    public class TBufferedTransport : TTransport, IDisposable
+    {
+        private readonly int bufSize;
+        private readonly MemoryStream inputBuffer = new MemoryStream(0);
+        private readonly MemoryStream outputBuffer = new MemoryStream(0);
+        private readonly TTransport transport;
+
+        public TBufferedTransport(TTransport transport, int bufSize = 1024)
+        {
+            if (transport == null)
+                throw new ArgumentNullException("transport");
+            if (bufSize <= 0)
+                throw new ArgumentException("bufSize", "Buffer size must be a positive number.");
+            this.transport = transport;
+            this.bufSize = bufSize;
+        }
+
+        public TTransport UnderlyingTransport
+        {
+            get
+            {
+                CheckNotDisposed();
+                return transport;
+            }
+        }
+
+        public override bool IsOpen
+        {
+            get
+            {
+                // We can legitimately throw here but be nice a bit.
+                // CheckNotDisposed();
+                return !_IsDisposed && transport.IsOpen;
+            }
+        }
+
+        public override void Open()
+        {
+            CheckNotDisposed();
+            transport.Open();
+        }
+
+        public override void Close()
+        {
+            CheckNotDisposed();
+            transport.Close();
+        }
+
+        public override int Read(byte[] buf, int off, int len)
+        {
+            CheckNotDisposed();
+            ValidateBufferArgs(buf, off, len);
+            if (!IsOpen)
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+
+            if (inputBuffer.Capacity < bufSize)
+                inputBuffer.Capacity = bufSize;
+
+            while (true)
+            {
+                int got = inputBuffer.Read(buf, off, len);
+                if (got > 0)
+                    return got;
+
+                inputBuffer.Seek(0, SeekOrigin.Begin);
+                inputBuffer.SetLength(inputBuffer.Capacity);
+                int filled = transport.Read(inputBuffer.GetBuffer(), 0, (int)inputBuffer.Length);
+                inputBuffer.SetLength(filled);
+                if (filled == 0)
+                    return 0;
+            }
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            CheckNotDisposed();
+            ValidateBufferArgs(buf, off, len);
+            if (!IsOpen)
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+            // Relative offset from "off" argument
+            int offset = 0;
+            if (outputBuffer.Length > 0)
+            {
+                int capa = (int)(outputBuffer.Capacity - outputBuffer.Length);
+                int writeSize = capa <= len ? capa : len;
+                outputBuffer.Write(buf, off, writeSize);
+                offset += writeSize;
+                if (writeSize == capa)
+                {
+                    transport.Write(outputBuffer.GetBuffer(), 0, (int)outputBuffer.Length);
+                    outputBuffer.SetLength(0);
+                }
+            }
+            while (len - offset >= bufSize)
+            {
+                transport.Write(buf, off + offset, bufSize);
+                offset += bufSize;
+            }
+            int remain = len - offset;
+            if (remain > 0)
+            {
+                if (outputBuffer.Capacity < bufSize)
+                    outputBuffer.Capacity = bufSize;
+                outputBuffer.Write(buf, off + offset, remain);
+            }
+        }
+
+        private void InternalFlush()
+        {
+            if (!IsOpen)
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+            if (outputBuffer.Length > 0)
+            {
+                transport.Write(outputBuffer.GetBuffer(), 0, (int)outputBuffer.Length);
+                outputBuffer.SetLength(0);
+            }
+        }
+
+        public override void Flush()
+        {
+            CheckNotDisposed();
+            InternalFlush();
+
+            transport.Flush();
+        }
+
+        public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+        {
+            CheckNotDisposed();
+            InternalFlush();
+
+            return transport.BeginFlush( callback, state);
+        }
+
+        public override void EndFlush(IAsyncResult asyncResult)
+        {
+            transport.EndFlush( asyncResult);
+        }
+
+
+
+        protected void CheckNotDisposed()
+        {
+            if (_IsDisposed)
+                throw new ObjectDisposedException("TBufferedTransport");
+        }
+
+        #region " IDisposable Support "
+        protected bool _IsDisposed { get; private set; }
+
+        // IDisposable
+        protected override void Dispose(bool disposing)
+        {
+            if (!_IsDisposed)
+            {
+                if (disposing)
+                {
+                    if (inputBuffer != null)
+                        inputBuffer.Dispose();
+                    if (outputBuffer != null)
+                        outputBuffer.Dispose();
+                    if (transport != null)
+                        transport.Dispose();
+                }
+            }
+            _IsDisposed = true;
+        }
+        #endregion
+    }
+}
diff --git a/lib/csharp/src/Transport/TFramedTransport.cs b/lib/csharp/src/Transport/TFramedTransport.cs
new file mode 100644
index 0000000..a746a32
--- /dev/null
+++ b/lib/csharp/src/Transport/TFramedTransport.cs
@@ -0,0 +1,205 @@
+/**
+ * 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.IO;
+
+namespace Thrift.Transport
+{
+    public class TFramedTransport : TTransport, IDisposable
+    {
+        private readonly TTransport transport;
+        private readonly MemoryStream writeBuffer = new MemoryStream(1024);
+        private readonly MemoryStream readBuffer = new MemoryStream(1024);
+
+        private const int HeaderSize = 4;
+        private readonly byte[] headerBuf = new byte[HeaderSize];
+
+        public class Factory : TTransportFactory
+        {
+            public override TTransport GetTransport(TTransport trans)
+            {
+                return new TFramedTransport(trans);
+            }
+        }
+
+        public TFramedTransport(TTransport transport)
+        {
+            if (transport == null)
+                throw new ArgumentNullException("transport");
+            this.transport = transport;
+            InitWriteBuffer();
+        }
+
+        public override void Open()
+        {
+            CheckNotDisposed();
+            transport.Open();
+        }
+
+        public override bool IsOpen
+        {
+            get
+            {
+                // We can legitimately throw here but be nice a bit.
+                // CheckNotDisposed();
+                return !_IsDisposed && transport.IsOpen;
+            }
+        }
+
+        public override void Close()
+        {
+            CheckNotDisposed();
+            transport.Close();
+        }
+
+        public override int Read(byte[] buf, int off, int len)
+        {
+            CheckNotDisposed();
+            ValidateBufferArgs(buf, off, len);
+            if (!IsOpen)
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+            int got = readBuffer.Read(buf, off, len);
+            if (got > 0)
+            {
+                return got;
+            }
+
+            // Read another frame of data
+            ReadFrame();
+
+            return readBuffer.Read(buf, off, len);
+        }
+
+        private void ReadFrame()
+        {
+            transport.ReadAll(headerBuf, 0, HeaderSize);
+            int size = DecodeFrameSize(headerBuf);
+
+            readBuffer.SetLength(size);
+            readBuffer.Seek(0, SeekOrigin.Begin);
+            byte[] buff = readBuffer.GetBuffer();
+            transport.ReadAll(buff, 0, size);
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            CheckNotDisposed();
+            ValidateBufferArgs(buf, off, len);
+            if (!IsOpen)
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+            if (writeBuffer.Length + (long)len > (long)int.MaxValue)
+                Flush();
+            writeBuffer.Write(buf, off, len);
+        }
+
+        private void InternalFlush()
+        {
+            CheckNotDisposed();
+            if (!IsOpen)
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+            byte[] buf = writeBuffer.GetBuffer();
+            int len = (int)writeBuffer.Length;
+            int data_len = len - HeaderSize;
+            if (data_len < 0)
+                throw new System.InvalidOperationException(); // logic error actually
+
+            // Inject message header into the reserved buffer space
+            EncodeFrameSize(data_len, buf);
+
+            // Send the entire message at once
+            transport.Write(buf, 0, len);
+
+            InitWriteBuffer();
+        }
+
+        public override void Flush()
+        {
+            CheckNotDisposed();
+            InternalFlush();
+
+            transport.Flush();
+        }
+
+        public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+        {
+            CheckNotDisposed();
+            InternalFlush();
+
+            return transport.BeginFlush( callback, state);
+        }
+
+        public override void EndFlush(IAsyncResult asyncResult)
+        {
+            transport.EndFlush( asyncResult);
+        }
+
+        private void InitWriteBuffer()
+        {
+            // Reserve space for message header to be put right before sending it out
+            writeBuffer.SetLength(HeaderSize);
+            writeBuffer.Seek(0, SeekOrigin.End);
+        }
+
+        private static void EncodeFrameSize(int frameSize, byte[] buf)
+        {
+            buf[0] = (byte)(0xff & (frameSize >> 24));
+            buf[1] = (byte)(0xff & (frameSize >> 16));
+            buf[2] = (byte)(0xff & (frameSize >> 8));
+            buf[3] = (byte)(0xff & (frameSize));
+        }
+
+        private static int DecodeFrameSize(byte[] buf)
+        {
+            return
+                ((buf[0] & 0xff) << 24) |
+                ((buf[1] & 0xff) << 16) |
+                ((buf[2] & 0xff) << 8) |
+                ((buf[3] & 0xff));
+        }
+
+
+        private void CheckNotDisposed()
+        {
+            if (_IsDisposed)
+                throw new ObjectDisposedException("TFramedTransport");
+        }
+
+        #region " IDisposable Support "
+        private bool _IsDisposed;
+
+        // IDisposable
+        protected override void Dispose(bool disposing)
+        {
+            if (!_IsDisposed)
+            {
+                if (disposing)
+                {
+                    if (readBuffer != null)
+                        readBuffer.Dispose();
+                    if (writeBuffer != null)
+                        writeBuffer.Dispose();
+                    if (transport != null)
+                        transport.Dispose();
+                }
+            }
+            _IsDisposed = true;
+        }
+        #endregion
+    }
+}
diff --git a/lib/csharp/src/Transport/THttpClient.cs b/lib/csharp/src/Transport/THttpClient.cs
new file mode 100644
index 0000000..986799c
--- /dev/null
+++ b/lib/csharp/src/Transport/THttpClient.cs
@@ -0,0 +1,486 @@
+/**
+ * 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.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Threading;
+using System.Linq;
+using System.Security.Cryptography.X509Certificates;
+using System.IO.Compression;
+
+namespace Thrift.Transport
+{
+    public class THttpClient : TTransport, IDisposable
+    {
+        private readonly Uri uri;
+        private readonly X509Certificate[] certificates;
+        private Stream inputStream;
+        private MemoryStream outputStream = new MemoryStream();
+
+        // Timeouts in milliseconds
+        private int connectTimeout = 30000;
+
+        private int readTimeout = 30000;
+
+        private IDictionary<string, string> customHeaders = new Dictionary<string, string>();
+        private string userAgent = "C#/THttpClient";
+
+#if !SILVERLIGHT
+        private IWebProxy proxy = WebRequest.DefaultWebProxy;
+#endif
+
+        public THttpClient(Uri u)
+            : this(u, Enumerable.Empty<X509Certificate>())
+        {
+        }
+        public THttpClient(Uri u, string userAgent)
+            : this(u, userAgent, Enumerable.Empty<X509Certificate>())
+        {
+        }
+
+        public THttpClient(Uri u, IEnumerable<X509Certificate> certificates)
+        {
+            uri = u;
+            this.certificates = (certificates ?? Enumerable.Empty<X509Certificate>()).ToArray();
+        }
+        public THttpClient(Uri u, string userAgent, IEnumerable<X509Certificate> certificates)
+        {
+            uri = u;
+            this.userAgent = userAgent;
+            this.certificates = (certificates ?? Enumerable.Empty<X509Certificate>()).ToArray();
+        }
+
+        public int ConnectTimeout
+        {
+            set
+            {
+                connectTimeout = value;
+            }
+        }
+
+        public int ReadTimeout
+        {
+            set
+            {
+                readTimeout = value;
+            }
+        }
+
+        public IDictionary<string, string> CustomHeaders
+        {
+            get
+            {
+                return customHeaders;
+            }
+        }
+
+#if !SILVERLIGHT
+        public IWebProxy Proxy
+        {
+            set
+            {
+                proxy = value;
+            }
+        }
+#endif
+
+        public override bool IsOpen
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public override void Open()
+        {
+        }
+
+        public override void Close()
+        {
+            if (inputStream != null)
+            {
+                inputStream.Close();
+                inputStream = null;
+            }
+            if (outputStream != null)
+            {
+                outputStream.Close();
+                outputStream = null;
+            }
+        }
+
+        public override int Read(byte[] buf, int off, int len)
+        {
+            if (inputStream == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No request has been sent");
+            }
+
+            try
+            {
+                int ret = inputStream.Read(buf, off, len);
+
+                if (ret == -1)
+                {
+                    throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "No more data available");
+                }
+
+                return ret;
+            }
+            catch (IOException iox)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString(), iox);
+            }
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            outputStream.Write(buf, off, len);
+        }
+
+#if !SILVERLIGHT
+        public override void Flush()
+        {
+            try
+            {
+                SendRequest();
+            }
+            finally
+            {
+                outputStream = new MemoryStream();
+            }
+        }
+
+        private void SendRequest()
+        {
+            try
+            {
+                HttpWebRequest connection = CreateRequest();
+                connection.Headers.Add("Accept-Encoding", "gzip, deflate");
+
+                byte[] data = outputStream.ToArray();
+                connection.ContentLength = data.Length;
+
+                using (Stream requestStream = connection.GetRequestStream())
+                {
+                    requestStream.Write(data, 0, data.Length);
+
+                    // Resolve HTTP hang that can happens after successive calls by making sure
+                    // that we release the response and response stream. To support this, we copy
+                    // the response to a memory stream.
+                    using (var response = connection.GetResponse())
+                    {
+                        using (var responseStream = response.GetResponseStream())
+                        {
+                            // Copy the response to a memory stream so that we can
+                            // cleanly close the response and response stream.
+                            inputStream = new MemoryStream();
+                            byte[] buffer = new byte[8192];  // multiple of 4096
+                            int bytesRead;
+                            while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
+                            {
+                                inputStream.Write(buffer, 0, bytesRead);
+                            }
+                            inputStream.Seek(0, 0);
+                        }
+
+                        var encodings = response.Headers.GetValues("Content-Encoding");
+                        if (encodings != null)
+                        {
+                            foreach (var encoding in encodings)
+                            {
+                                switch (encoding)
+                                {
+                                    case "gzip":
+                                        DecompressGZipped(ref inputStream);
+                                        break;
+                                    case "deflate":
+                                        DecompressDeflated(ref inputStream);
+                                        break;
+                                    default:
+                                        break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (IOException iox)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString(), iox);
+            }
+            catch (WebException wx)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.Unknown, "Couldn't connect to server: " + wx, wx);
+            }
+        }
+
+        private void DecompressDeflated(ref Stream inputStream)
+        {
+            var tmp = new MemoryStream();
+            using (var decomp = new DeflateStream(inputStream, CompressionMode.Decompress))
+            {
+                decomp.CopyTo(tmp);
+            }
+            inputStream.Dispose();
+            inputStream = tmp;
+            inputStream.Seek(0, 0);
+        }
+
+        private void DecompressGZipped(ref Stream inputStream)
+        {
+            var tmp = new MemoryStream();
+            using (var decomp = new GZipStream(inputStream, CompressionMode.Decompress))
+            {
+                decomp.CopyTo(tmp);
+            }
+            inputStream.Dispose();
+            inputStream = tmp;
+            inputStream.Seek(0, 0);
+        }
+#endif
+        private HttpWebRequest CreateRequest()
+        {
+            HttpWebRequest connection = (HttpWebRequest)WebRequest.Create(uri);
+
+
+#if !SILVERLIGHT
+            // Adding certificates through code is not supported with WP7 Silverlight
+            // see "Windows Phone 7 and Certificates_FINAL_121610.pdf"
+            connection.ClientCertificates.AddRange(certificates);
+
+            if (connectTimeout > 0)
+            {
+                connection.Timeout = connectTimeout;
+            }
+            if (readTimeout > 0)
+            {
+                connection.ReadWriteTimeout = readTimeout;
+            }
+#endif
+            // Make the request
+            connection.ContentType = "application/x-thrift";
+            connection.Accept = "application/x-thrift";
+            connection.UserAgent = userAgent;
+            connection.Method = "POST";
+#if !SILVERLIGHT
+            connection.ProtocolVersion = HttpVersion.Version10;
+#endif
+
+            //add custom headers here
+            foreach (KeyValuePair<string, string> item in customHeaders)
+            {
+#if !SILVERLIGHT
+                connection.Headers.Add(item.Key, item.Value);
+#else
+                connection.Headers[item.Key] = item.Value;
+#endif
+            }
+
+#if !SILVERLIGHT
+            connection.Proxy = proxy;
+#endif
+
+            return connection;
+        }
+
+        public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+        {
+            // Extract request and reset buffer
+            var data = outputStream.ToArray();
+
+            //requestBuffer_ = new MemoryStream();
+
+            try
+            {
+                // Create connection object
+                var flushAsyncResult = new FlushAsyncResult(callback, state);
+                flushAsyncResult.Connection = CreateRequest();
+
+                flushAsyncResult.Data = data;
+
+
+                flushAsyncResult.Connection.BeginGetRequestStream(GetRequestStreamCallback, flushAsyncResult);
+                return flushAsyncResult;
+
+            }
+            catch (IOException iox)
+            {
+                throw new TTransportException(iox.ToString(), iox);
+            }
+        }
+
+        public override void EndFlush(IAsyncResult asyncResult)
+        {
+            try
+            {
+                var flushAsyncResult = (FlushAsyncResult)asyncResult;
+
+                if (!flushAsyncResult.IsCompleted)
+                {
+                    var waitHandle = flushAsyncResult.AsyncWaitHandle;
+                    waitHandle.WaitOne();  // blocking INFINITEly
+                    waitHandle.Close();
+                }
+
+                if (flushAsyncResult.AsyncException != null)
+                {
+                    throw flushAsyncResult.AsyncException;
+                }
+            }
+            finally
+            {
+                outputStream = new MemoryStream();
+            }
+
+        }
+
+        private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
+        {
+            var flushAsyncResult = (FlushAsyncResult)asynchronousResult.AsyncState;
+            try
+            {
+                var reqStream = flushAsyncResult.Connection.EndGetRequestStream(asynchronousResult);
+                reqStream.Write(flushAsyncResult.Data, 0, flushAsyncResult.Data.Length);
+                reqStream.Flush();
+                reqStream.Close();
+
+                // Start the asynchronous operation to get the response
+                flushAsyncResult.Connection.BeginGetResponse(GetResponseCallback, flushAsyncResult);
+            }
+            catch (Exception exception)
+            {
+                flushAsyncResult.AsyncException = new TTransportException(exception.ToString(), exception);
+                flushAsyncResult.UpdateStatusToComplete();
+                flushAsyncResult.NotifyCallbackWhenAvailable();
+            }
+        }
+
+        private void GetResponseCallback(IAsyncResult asynchronousResult)
+        {
+            var flushAsyncResult = (FlushAsyncResult)asynchronousResult.AsyncState;
+            try
+            {
+                inputStream = flushAsyncResult.Connection.EndGetResponse(asynchronousResult).GetResponseStream();
+            }
+            catch (Exception exception)
+            {
+                flushAsyncResult.AsyncException = new TTransportException(exception.ToString(), exception);
+            }
+            flushAsyncResult.UpdateStatusToComplete();
+            flushAsyncResult.NotifyCallbackWhenAvailable();
+        }
+
+        // Based on http://msmvps.com/blogs/luisabreu/archive/2009/06/15/multithreading-implementing-the-iasyncresult-interface.aspx
+        class FlushAsyncResult : IAsyncResult
+        {
+            private volatile Boolean _isCompleted;
+            private ManualResetEvent _evt;
+            private readonly AsyncCallback _cbMethod;
+            private readonly object _state;
+
+            public FlushAsyncResult(AsyncCallback cbMethod, object state)
+            {
+                _cbMethod = cbMethod;
+                _state = state;
+            }
+
+            internal byte[] Data { get; set; }
+            internal HttpWebRequest Connection { get; set; }
+            internal TTransportException AsyncException { get; set; }
+
+            public object AsyncState
+            {
+                get { return _state; }
+            }
+            public WaitHandle AsyncWaitHandle
+            {
+                get { return GetEvtHandle(); }
+            }
+            public bool CompletedSynchronously
+            {
+                get { return false; }
+            }
+            public bool IsCompleted
+            {
+                get { return _isCompleted; }
+            }
+            private readonly object _locker = new object();
+            private ManualResetEvent GetEvtHandle()
+            {
+                lock (_locker)
+                {
+                    if (_evt == null)
+                    {
+                        _evt = new ManualResetEvent(false);
+                    }
+                    if (_isCompleted)
+                    {
+                        _evt.Set();
+                    }
+                }
+                return _evt;
+            }
+            internal void UpdateStatusToComplete()
+            {
+                _isCompleted = true; //1. set _iscompleted to true
+                lock (_locker)
+                {
+                    if (_evt != null)
+                    {
+                        _evt.Set(); //2. set the event, when it exists
+                    }
+                }
+            }
+
+            internal void NotifyCallbackWhenAvailable()
+            {
+                if (_cbMethod != null)
+                {
+                    _cbMethod(this);
+                }
+            }
+        }
+
+        #region " IDisposable Support "
+        private bool _IsDisposed;
+
+        // IDisposable
+        protected override void Dispose(bool disposing)
+        {
+            if (!_IsDisposed)
+            {
+                if (disposing)
+                {
+                    if (inputStream != null)
+                        inputStream.Dispose();
+                    if (outputStream != null)
+                        outputStream.Dispose();
+                }
+            }
+            _IsDisposed = true;
+        }
+        #endregion
+    }
+}
diff --git a/lib/csharp/src/Transport/THttpHandler.cs b/lib/csharp/src/Transport/THttpHandler.cs
new file mode 100644
index 0000000..4115ef9
--- /dev/null
+++ b/lib/csharp/src/Transport/THttpHandler.cs
@@ -0,0 +1,102 @@
+/**
+ * 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.Web;
+using System.Net;
+using System.IO;
+
+using Thrift.Protocol;
+
+namespace Thrift.Transport
+{
+    public class THttpHandler : IHttpHandler
+    {
+        protected TProcessor processor;
+
+        protected TProtocolFactory inputProtocolFactory;
+        protected TProtocolFactory outputProtocolFactory;
+
+        protected const string contentType = "application/x-thrift";
+        protected System.Text.Encoding encoding = System.Text.Encoding.UTF8;
+
+        public THttpHandler(TProcessor processor)
+            : this(processor, new TBinaryProtocol.Factory())
+        {
+
+        }
+
+        public THttpHandler(TProcessor processor, TProtocolFactory protocolFactory)
+            : this(processor, protocolFactory, protocolFactory)
+        {
+
+        }
+
+        public THttpHandler(TProcessor processor, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory)
+        {
+            this.processor = processor;
+            this.inputProtocolFactory = inputProtocolFactory;
+            this.outputProtocolFactory = outputProtocolFactory;
+        }
+
+        public void ProcessRequest(HttpListenerContext context)
+        {
+            context.Response.ContentType = contentType;
+            context.Response.ContentEncoding = encoding;
+            ProcessRequest(context.Request.InputStream, context.Response.OutputStream);
+        }
+
+        public void ProcessRequest(HttpContext context)
+        {
+            context.Response.ContentType = contentType;
+            context.Response.ContentEncoding = encoding;
+            ProcessRequest(context.Request.InputStream, context.Response.OutputStream);
+        }
+
+        public void ProcessRequest(Stream input, Stream output)
+        {
+            TTransport transport = new TStreamTransport(input,output);
+
+            try
+            {
+                var inputProtocol = inputProtocolFactory.GetProtocol(transport);
+                var outputProtocol = outputProtocolFactory.GetProtocol(transport);
+
+                while (processor.Process(inputProtocol, outputProtocol))
+                {
+                }
+            }
+            catch (TTransportException)
+            {
+                // Client died, just move on
+            }
+            finally
+            {
+                transport.Close();
+            }
+        }
+
+        public bool IsReusable
+        {
+            get { return true; }
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs b/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs
new file mode 100644
index 0000000..e491f32
--- /dev/null
+++ b/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs
@@ -0,0 +1,97 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System.Threading.Tasks;
+using System.Web;
+using Thrift.Protocol;
+
+namespace Thrift.Transport
+{
+    /// <summary>
+    /// An async task based HTTP handler for processing thrift services.
+    /// </summary>
+    public class THttpTaskAsyncHandler : HttpTaskAsyncHandler
+    {
+        private readonly TAsyncProcessor _processor;
+        private readonly TProtocolFactory _inputProtocolFactory;
+        private readonly TProtocolFactory _outputProtocolFactory;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class
+        /// using the <see cref="TBinaryProtocol.Factory"/> for both input and output streams.
+        /// </summary>
+        /// <param name="processor">The async processor implementation.</param>
+        public THttpTaskAsyncHandler(TAsyncProcessor processor)
+            : this(processor, new TBinaryProtocol.Factory())
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class
+        /// using <paramref name="protocolFactory"/> for both input and output streams.
+        /// </summary>
+        /// <param name="processor">The async processor implementation.</param>
+        /// <param name="protocolFactory">The protocol factory.</param>
+        public THttpTaskAsyncHandler(TAsyncProcessor processor, TProtocolFactory protocolFactory)
+            : this(processor, protocolFactory, protocolFactory)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class.
+        /// </summary>
+        /// <param name="processor">The async processor implementation.</param>
+        /// <param name="inputProtocolFactory">The input protocol factory.</param>
+        /// <param name="outputProtocolFactory">The output protocol factory.</param>
+        public THttpTaskAsyncHandler(TAsyncProcessor processor, TProtocolFactory inputProtocolFactory,
+            TProtocolFactory outputProtocolFactory)
+        {
+            _processor = processor;
+            _inputProtocolFactory = inputProtocolFactory;
+            _outputProtocolFactory = outputProtocolFactory;
+        }
+
+        public override async Task ProcessRequestAsync(HttpContext context)
+        {
+            var transport = new TStreamTransport(context.Request.InputStream, context.Response.OutputStream);
+
+            try
+            {
+                var input = _inputProtocolFactory.GetProtocol(transport);
+                var output = _outputProtocolFactory.GetProtocol(transport);
+
+                while (await _processor.ProcessAsync(input, output))
+                {
+                }
+            }
+            catch (TTransportException)
+            {
+                // Client died, just move on
+            }
+            finally
+            {
+                transport.Close();
+            }
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TMemoryBuffer.cs b/lib/csharp/src/Transport/TMemoryBuffer.cs
new file mode 100644
index 0000000..303d083
--- /dev/null
+++ b/lib/csharp/src/Transport/TMemoryBuffer.cs
@@ -0,0 +1,117 @@
+/**
+ * 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.IO;
+using System.Reflection;
+using Thrift.Protocol;
+
+namespace Thrift.Transport
+{
+    public class TMemoryBuffer : TTransport
+    {
+
+        private readonly MemoryStream byteStream;
+
+        public TMemoryBuffer()
+        {
+            byteStream = new MemoryStream();
+        }
+
+        public TMemoryBuffer(byte[] buf)
+        {
+            byteStream = new MemoryStream(buf);
+        }
+
+        public override void Open()
+        {
+            /** do nothing **/
+        }
+
+        public override void Close()
+        {
+            /** do nothing **/
+        }
+
+        public override int Read(byte[] buf, int off, int len)
+        {
+            return byteStream.Read(buf, off, len);
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            byteStream.Write(buf, off, len);
+        }
+
+        public byte[] GetBuffer()
+        {
+            return byteStream.ToArray();
+        }
+
+
+        public override bool IsOpen
+        {
+            get { return true; }
+        }
+
+        public static byte[] Serialize(TAbstractBase s)
+        {
+            var t = new TMemoryBuffer();
+            var p = new TBinaryProtocol(t);
+
+            s.Write(p);
+
+            return t.GetBuffer();
+        }
+
+        public static T DeSerialize<T>(byte[] buf) where T : TAbstractBase
+        {
+            var trans = new TMemoryBuffer(buf);
+            var p = new TBinaryProtocol(trans);
+            if (typeof(TBase).IsAssignableFrom(typeof(T)))
+            {
+                var method = typeof(T).GetMethod("Read", BindingFlags.Instance | BindingFlags.Public);
+                var t = Activator.CreateInstance<T>();
+                method.Invoke(t, new object[] { p });
+                return t;
+            }
+            else
+            {
+                var method = typeof(T).GetMethod("Read", BindingFlags.Static | BindingFlags.Public);
+                return (T)method.Invoke(null, new object[] { p });
+            }
+        }
+
+        private bool _IsDisposed;
+
+        // IDisposable
+        protected override void Dispose(bool disposing)
+        {
+            if (!_IsDisposed)
+            {
+                if (disposing)
+                {
+                    if (byteStream != null)
+                        byteStream.Dispose();
+                }
+            }
+            _IsDisposed = true;
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TNamedPipeClientTransport.cs b/lib/csharp/src/Transport/TNamedPipeClientTransport.cs
new file mode 100644
index 0000000..49a50aa
--- /dev/null
+++ b/lib/csharp/src/Transport/TNamedPipeClientTransport.cs
@@ -0,0 +1,111 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.IO.Pipes;
+using System.Threading;
+
+namespace Thrift.Transport
+{
+    public class TNamedPipeClientTransport : TTransport
+    {
+        private NamedPipeClientStream client;
+        private string ServerName;
+        private string PipeName;
+        private int ConnectTimeout;
+
+        public TNamedPipeClientTransport(string pipe, int timeout = Timeout.Infinite)
+        {
+            ServerName = ".";
+            PipeName = pipe;
+            ConnectTimeout = timeout;
+        }
+
+        public TNamedPipeClientTransport(string server, string pipe, int timeout = Timeout.Infinite)
+        {
+            ServerName = (server != "") ? server : ".";
+            PipeName = pipe;
+            ConnectTimeout = timeout;
+        }
+
+        public override bool IsOpen
+        {
+            get { return client != null && client.IsConnected; }
+        }
+
+        public override void Open()
+        {
+            if (IsOpen)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen);
+            }
+            client = new NamedPipeClientStream(ServerName, PipeName, PipeDirection.InOut, PipeOptions.None);
+            client.Connect(ConnectTimeout);
+        }
+
+        public override void Close()
+        {
+            if (client != null)
+            {
+                client.Close();
+                client = null;
+            }
+        }
+
+        public override int Read(byte[] buf, int off, int len)
+        {
+            if (client == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+            }
+
+            return client.Read(buf, off, len);
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            if (client == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+            }
+
+            // if necessary, send the data in chunks
+            // there's a system limit around 0x10000 bytes that we hit otherwise
+            // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section."
+            var nBytes = Math.Min(len, 15 * 4096);  // 16 would exceed the limit
+            while (nBytes > 0)
+            {
+                client.Write(buf, off, nBytes);
+
+                off += nBytes;
+                len -= nBytes;
+                nBytes = Math.Min(len, nBytes);
+            }
+        }
+
+        protected override void Dispose(bool disposing)
+        {
+            client.Dispose();
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TNamedPipeServerTransport.cs b/lib/csharp/src/Transport/TNamedPipeServerTransport.cs
new file mode 100644
index 0000000..32215cf
--- /dev/null
+++ b/lib/csharp/src/Transport/TNamedPipeServerTransport.cs
@@ -0,0 +1,296 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.IO.Pipes;
+using System.Threading;
+using System.Security.Principal;
+
+namespace Thrift.Transport
+{
+    public class TNamedPipeServerTransport : TServerTransport
+    {
+        /// <summary>
+        /// This is the address of the Pipe on the localhost.
+        /// </summary>
+        private readonly string pipeAddress;
+        private NamedPipeServerStream stream = null;
+        private bool asyncMode = true;
+
+        public TNamedPipeServerTransport(string pipeAddress)
+        {
+            this.pipeAddress = pipeAddress;
+        }
+
+        public override void Listen()
+        {
+            // nothing to do here
+        }
+
+        public override void Close()
+        {
+            if (stream != null)
+            {
+                try
+                {
+                    stream.Close();
+                    stream.Dispose();
+                }
+                finally
+                {
+                    stream = null;
+                }
+            }
+        }
+
+        private void EnsurePipeInstance()
+        {
+            if (stream == null)
+            {
+                var direction = PipeDirection.InOut;
+                var maxconn = NamedPipeServerStream.MaxAllowedServerInstances;
+                var mode = PipeTransmissionMode.Byte;
+                var options = asyncMode ? PipeOptions.Asynchronous : PipeOptions.None;
+                const int INBUF_SIZE = 4096;
+                const int OUTBUF_SIZE = 4096;
+
+                // security
+                var security = new PipeSecurity();
+                security.AddAccessRule(
+                    new PipeAccessRule(
+                        new SecurityIdentifier(WellKnownSidType.WorldSid, null),
+                        PipeAccessRights.Read | PipeAccessRights.Write | PipeAccessRights.Synchronize | PipeAccessRights.CreateNewInstance,
+                        System.Security.AccessControl.AccessControlType.Allow
+                    )
+                );
+
+                try
+                {
+                    stream = new NamedPipeServerStream(pipeAddress, direction, maxconn, mode, options, INBUF_SIZE, OUTBUF_SIZE, security);
+                }
+                catch (NotImplementedException)  // Mono still does not support async, fallback to sync
+                {
+                    if (asyncMode)
+                    {
+                        options &= (~PipeOptions.Asynchronous);
+                        stream = new NamedPipeServerStream(pipeAddress, direction, maxconn, mode, options, INBUF_SIZE, OUTBUF_SIZE, security);
+                        asyncMode = false;
+                    }
+                    else
+                    {
+                        throw;
+                    }
+                }
+
+            }
+        }
+
+        protected override TTransport AcceptImpl()
+        {
+            try
+            {
+                EnsurePipeInstance();
+
+                if (asyncMode)
+                {
+                    var evt = new ManualResetEvent(false);
+                    Exception eOuter = null;
+
+                    stream.BeginWaitForConnection(asyncResult =>
+                    {
+                        try
+                        {
+                            if (stream != null)
+                                stream.EndWaitForConnection(asyncResult);
+                            else
+                                eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted);
+                        }
+                        catch (Exception e)
+                        {
+                            if (stream != null)
+                                eOuter = e;
+                            else
+                                eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted, e.Message, e);
+                        }
+                        evt.Set();
+                    }, null);
+
+                    evt.WaitOne();
+
+                    if (eOuter != null)
+                        throw eOuter; // rethrow exception
+                }
+                else
+                {
+                    stream.WaitForConnection();
+                }
+
+                var trans = new ServerTransport(stream,asyncMode);
+                stream = null;  // pass ownership to ServerTransport
+                return trans;
+            }
+            catch (TTransportException)
+            {
+                Close();
+                throw;
+            }
+            catch (Exception e)
+            {
+                Close();
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, e.Message, e);
+            }
+        }
+
+        private class ServerTransport : TTransport
+        {
+            private NamedPipeServerStream stream;
+            private bool asyncMode;
+
+            public ServerTransport(NamedPipeServerStream stream, bool asyncMode)
+            {
+                this.stream = stream;
+                this.asyncMode = asyncMode;
+            }
+
+            public override bool IsOpen
+            {
+                get { return stream != null && stream.IsConnected; }
+            }
+
+            public override void Open()
+            {
+            }
+
+            public override void Close()
+            {
+                if (stream != null)
+                    stream.Close();
+            }
+
+            public override int Read(byte[] buf, int off, int len)
+            {
+                if (stream == null)
+                {
+                    throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+                }
+
+                if (asyncMode)
+                {
+                    Exception eOuter = null;
+                    var evt = new ManualResetEvent(false);
+                    int retval = 0;
+
+                    stream.BeginRead(buf, off, len, asyncResult =>
+                    {
+                        try
+                        {
+                            if (stream != null)
+                                retval = stream.EndRead(asyncResult);
+                            else
+                                eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted);
+                        }
+                        catch (Exception e)
+                        {
+                            if (stream != null)
+                                eOuter = e;
+                            else
+                                eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted, e.Message, e);
+                        }
+                        evt.Set();
+                    }, null);
+
+                    evt.WaitOne();
+
+                    if (eOuter != null)
+                        throw eOuter; // rethrow exception
+                    else
+                        return retval;
+                }
+                else
+                {
+                    return stream.Read(buf, off, len);
+                }
+            }
+
+            public override void Write(byte[] buf, int off, int len)
+            {
+                if (stream == null)
+                {
+                    throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+                }
+
+                // if necessary, send the data in chunks
+                // there's a system limit around 0x10000 bytes that we hit otherwise
+                // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section."
+                var nBytes = Math.Min(len, 15 * 4096);  // 16 would exceed the limit
+                while (nBytes > 0)
+                {
+
+                    if (asyncMode)
+                    {
+                        Exception eOuter = null;
+                        var evt = new ManualResetEvent(false);
+
+                        stream.BeginWrite(buf, off, nBytes, asyncResult =>
+                        {
+                            try
+                            {
+                                if (stream != null)
+                                    stream.EndWrite(asyncResult);
+                                else
+                                    eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted);
+                            }
+                            catch (Exception e)
+                            {
+                                if (stream != null)
+                                    eOuter = e;
+                                else
+                                    eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted, e.Message, e);
+                            }
+                            evt.Set();
+                        }, null);
+
+                        evt.WaitOne();
+
+                        if (eOuter != null)
+                            throw eOuter; // rethrow exception
+                    }
+                    else
+                    {
+                        stream.Write(buf, off, nBytes);
+                    }
+
+                    off += nBytes;
+                    len -= nBytes;
+                    nBytes = Math.Min(len, nBytes);
+                }
+            }
+
+            protected override void Dispose(bool disposing)
+            {
+                if (stream != null)
+                    stream.Dispose();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/csharp/src/Transport/TServerSocket.cs b/lib/csharp/src/Transport/TServerSocket.cs
new file mode 100644
index 0000000..d8ec62a
--- /dev/null
+++ b/lib/csharp/src/Transport/TServerSocket.cs
@@ -0,0 +1,176 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Net.Sockets;
+
+
+namespace Thrift.Transport
+{
+    public class TServerSocket : TServerTransport
+    {
+        /// <summary>
+        /// Underlying server with socket.
+        /// </summary>
+        private TcpListener server = null;
+
+        /// <summary>
+        /// Port to listen on.
+        /// </summary>
+        private int port = 0;
+
+        /// <summary>
+        /// Timeout for client sockets from accept.
+        /// </summary>
+        private int clientTimeout = 0;
+
+        /// <summary>
+        /// Whether or not to wrap new TSocket connections in buffers.
+        /// </summary>
+        private bool useBufferedSockets = false;
+
+        /// <summary>
+        /// Creates a server socket from underlying socket object.
+        /// </summary>
+        public TServerSocket(TcpListener listener)
+            : this(listener, 0)
+        {
+        }
+
+        /// <summary>
+        /// Creates a server socket from underlying socket object.
+        /// </summary>
+        public TServerSocket(TcpListener listener, int clientTimeout)
+        {
+            this.server = listener;
+            this.clientTimeout = clientTimeout;
+        }
+
+        /// <summary>
+        /// Creates just a port listening server socket.
+        /// </summary>
+        public TServerSocket(int port)
+            : this(port, 0)
+        {
+        }
+
+        /// <summary>
+        /// Creates just a port listening server socket.
+        /// </summary>
+        public TServerSocket(int port, int clientTimeout)
+            : this(port, clientTimeout, false)
+        {
+        }
+
+        public TServerSocket(int port, int clientTimeout, bool useBufferedSockets)
+        {
+            this.port = port;
+            this.clientTimeout = clientTimeout;
+            this.useBufferedSockets = useBufferedSockets;
+            try
+            {
+                // Make server socket
+                this.server = TSocketVersionizer.CreateTcpListener(this.port);
+                this.server.Server.NoDelay = true;
+            }
+            catch (Exception ex)
+            {
+                server = null;
+                throw new TTransportException("Could not create ServerSocket on port " + this.port + ".", ex);
+            }
+        }
+
+        public override void Listen()
+        {
+            // Make sure not to block on accept
+            if (server != null)
+            {
+                try
+                {
+                    server.Start();
+                }
+                catch (SocketException sx)
+                {
+                    throw new TTransportException("Could not accept on listening socket: " + sx.Message, sx);
+                }
+            }
+        }
+
+        protected override TTransport AcceptImpl()
+        {
+            if (server == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
+            }
+            try
+            {
+                TSocket result2 = null;
+                TcpClient result = server.AcceptTcpClient();
+                try
+                {
+                    result2 = new TSocket(result);
+                    result2.Timeout = clientTimeout;
+                    if (useBufferedSockets)
+                    {
+                        TBufferedTransport result3 = new TBufferedTransport(result2);
+                        return result3;
+                    }
+                    else
+                    {
+                        return result2;
+                    }
+                }
+                catch (System.Exception)
+                {
+                    // If a TSocket was successfully created, then let
+                    // it do proper cleanup of the TcpClient object.
+                    if (result2 != null)
+                        result2.Dispose();
+                    else //  Otherwise, clean it up ourselves.
+                        ((IDisposable)result).Dispose();
+                    throw;
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new TTransportException(ex.ToString(), ex);
+            }
+        }
+
+        public override void Close()
+        {
+            if (server != null)
+            {
+                try
+                {
+                    server.Stop();
+                }
+                catch (Exception ex)
+                {
+                    throw new TTransportException("WARNING: Could not close server socket: " + ex, ex);
+                }
+                server = null;
+            }
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TServerTransport.cs b/lib/csharp/src/Transport/TServerTransport.cs
new file mode 100644
index 0000000..e63880b
--- /dev/null
+++ b/lib/csharp/src/Transport/TServerTransport.cs
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift.Transport
+{
+    public abstract class TServerTransport
+    {
+        public abstract void Listen();
+        public abstract void Close();
+        protected abstract TTransport AcceptImpl();
+
+        public TTransport Accept()
+        {
+            TTransport transport = AcceptImpl();
+            if (transport == null)
+            {
+                throw new TTransportException("accept() may not return NULL");
+            }
+            return transport;
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TSilverlightSocket.cs b/lib/csharp/src/Transport/TSilverlightSocket.cs
new file mode 100644
index 0000000..40469ab
--- /dev/null
+++ b/lib/csharp/src/Transport/TSilverlightSocket.cs
@@ -0,0 +1,393 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+/* only for silverlight */
+#if SILVERLIGHT
+
+using System;
+using System.Net.Sockets;
+using System.IO;
+using System.Net;
+using System.Threading;
+
+namespace Thrift.Transport
+{
+    public class TSilverlightSocket : TTransport
+    {
+        Socket socket = null;
+        static ManualResetEvent readAsyncComplete = new ManualResetEvent(false);
+        public event EventHandler<SocketAsyncEventArgs> connectHandler = null;
+
+        // memory stream for write cache.
+        private MemoryStream outputStream = new MemoryStream();
+
+        private string host = null;
+        private int port = 0;
+        private int timeout = 0;
+
+        // constructor
+        public TSilverlightSocket(string host, int port)
+            : this(host, port, 0)
+        {
+        }
+
+        // constructor
+        public TSilverlightSocket(string host, int port, int timeout)
+        {
+            this.host = host;
+            this.port = port;
+            this.timeout = timeout;
+
+            InitSocket();
+        }
+
+        private void InitSocket()
+        {
+            // Create a stream-based, TCP socket using the InterNetwork Address Family.
+            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+            socket.NoDelay = true;
+        }
+
+        public int Timeout
+        {
+            set
+            {
+                timeout = value;
+            }
+        }
+
+        public string Host
+        {
+            get
+            {
+                return host;
+            }
+        }
+
+        public int Port
+        {
+            get
+            {
+                return port;
+            }
+        }
+
+        public override bool IsOpen
+        {
+            get
+            {
+                if (socket == null)
+                {
+                    return false;
+                }
+
+                return socket.Connected;
+            }
+        }
+
+        public override void Open()
+        {
+            if (IsOpen)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
+            }
+
+            if (string.IsNullOrEmpty(host))
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
+            }
+
+            if (port <= 0)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
+            }
+
+            if (socket == null)
+            {
+                InitSocket();
+            }
+
+            if (timeout == 0)     // no timeout -> infinite
+            {
+                timeout = 10000;  // set a default timeout for WP.
+            }
+
+            {
+                // Create DnsEndPoint. The hostName and port are passed in to this method.
+                DnsEndPoint hostEntry = new DnsEndPoint(this.host, this.port);
+
+                // Create a SocketAsyncEventArgs object to be used in the connection request
+                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
+                socketEventArg.RemoteEndPoint = hostEntry;
+
+                // Inline event handler for the Completed event.
+                // Note: This event handler was implemented inline in order to make this method self-contained.
+                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
+                {
+                    if (connectHandler != null)
+                    {
+                        connectHandler(this, e);
+                    }
+                });
+
+                // Make an asynchronous Connect request over the socket
+                socket.ConnectAsync(socketEventArg);
+            }
+        }
+
+        public override int Read(byte[] buf, int off, int len)
+        {
+            bool _timeout = true;
+            string _error = null;
+            int _recvBytes = -1;
+
+            if (socket == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Socket is not open");
+            }
+
+            // Create SocketAsyncEventArgs context object
+            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
+            socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
+
+            // Setup the buffer to receive the data
+            socketEventArg.SetBuffer(buf, off, len);
+
+            // Inline event handler for the Completed event.
+            // Note: This even handler was implemented inline in order to make
+            // this method self-contained.
+            socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
+            {
+                _timeout = false;
+
+                if (e.SocketError == SocketError.Success)
+                {
+                    _recvBytes = e.BytesTransferred;
+                }
+                else
+                {
+                    _error = e.SocketError.ToString();
+                }
+
+                readAsyncComplete.Set();
+            });
+
+            // Sets the state of the event to nonsignaled, causing threads to block
+            readAsyncComplete.Reset();
+
+            // Make an asynchronous Receive request over the socket
+            socket.ReceiveAsync(socketEventArg);
+
+            // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
+            // If no response comes back within this time then proceed
+            readAsyncComplete.WaitOne(this.timeout);
+
+            if (_timeout)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Socket recv timeout");
+            }
+
+            if (_error != null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.Unknown, _error);
+            }
+
+            return _recvBytes;
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            outputStream.Write(buf, off, len);
+        }
+
+        private void beginFlush_Completed(object sender, SocketAsyncEventArgs e)
+        {
+            FlushAsyncResult flushAsyncResult = e.UserToken as FlushAsyncResult;
+            flushAsyncResult.UpdateStatusToComplete();
+            flushAsyncResult.NotifyCallbackWhenAvailable();
+
+            if (e.SocketError != SocketError.Success)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.Unknown, e.SocketError.ToString());
+            }
+        }
+
+        public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+        {
+            // Extract request and reset buffer
+            byte[] data = outputStream.ToArray();
+
+            FlushAsyncResult flushAsyncResult = new FlushAsyncResult(callback, state);
+
+            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
+            socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
+            socketEventArg.UserToken = flushAsyncResult;
+
+            socketEventArg.Completed += beginFlush_Completed;
+            socketEventArg.SetBuffer(data, 0, data.Length);
+
+            socket.SendAsync(socketEventArg);
+
+            return flushAsyncResult;
+        }
+
+        public override void EndFlush(IAsyncResult asyncResult)
+        {
+            try
+            {
+                var flushAsyncResult = (FlushAsyncResult)asyncResult;
+
+                if (!flushAsyncResult.IsCompleted)
+                {
+                    var waitHandle = flushAsyncResult.AsyncWaitHandle;
+                    waitHandle.WaitOne();
+                    waitHandle.Close();
+                }
+
+                if (flushAsyncResult.AsyncException != null)
+                {
+                    throw flushAsyncResult.AsyncException;
+                }
+            }
+            finally
+            {
+                outputStream = new MemoryStream();
+            }
+        }
+
+        // Copy from impl from THttpClient.cs
+        // Based on http://msmvps.com/blogs/luisabreu/archive/2009/06/15/multithreading-implementing-the-iasyncresult-interface.aspx
+        class FlushAsyncResult : IAsyncResult
+        {
+            private volatile Boolean _isCompleted;
+            private ManualResetEvent _evt;
+            private readonly AsyncCallback _cbMethod;
+            private readonly object _state;
+
+            public FlushAsyncResult(AsyncCallback cbMethod, object state)
+            {
+                _cbMethod = cbMethod;
+                _state = state;
+            }
+
+            internal byte[] Data { get; set; }
+            internal Socket Connection { get; set; }
+            internal TTransportException AsyncException { get; set; }
+
+            public object AsyncState
+            {
+                get { return _state; }
+            }
+
+            public WaitHandle AsyncWaitHandle
+            {
+                get { return GetEvtHandle(); }
+            }
+
+            public bool CompletedSynchronously
+            {
+                get { return false; }
+            }
+
+            public bool IsCompleted
+            {
+                get { return _isCompleted; }
+            }
+
+            private readonly object _locker = new object();
+
+            private ManualResetEvent GetEvtHandle()
+            {
+                lock (_locker)
+                {
+                    if (_evt == null)
+                    {
+                        _evt = new ManualResetEvent(false);
+                    }
+                    if (_isCompleted)
+                    {
+                        _evt.Set();
+                    }
+                }
+                return _evt;
+            }
+
+            internal void UpdateStatusToComplete()
+            {
+                _isCompleted = true; //1. set _iscompleted to true
+                lock (_locker)
+                {
+                    if (_evt != null)
+                    {
+                        _evt.Set(); //2. set the event, when it exists
+                    }
+                }
+            }
+
+            internal void NotifyCallbackWhenAvailable()
+            {
+                if (_cbMethod != null)
+                {
+                    _cbMethod(this);
+                }
+            }
+        }
+
+        public override void Close()
+        {
+            if (socket != null)
+            {
+                socket.Close();
+                socket = null;
+            }
+        }
+
+#region " IDisposable Support "
+        private bool _IsDisposed;
+
+        // IDisposable
+        protected override void Dispose(bool disposing)
+        {
+            if (!_IsDisposed)
+            {
+                if (disposing)
+                {
+                    if (outputStream != null)
+                    {
+                        outputStream.Dispose();
+                    }
+                    outputStream = null;
+                    if (socket != null)
+                    {
+                        ((IDisposable)socket).Dispose();
+                    }
+                }
+            }
+            _IsDisposed = true;
+        }
+#endregion
+    }
+}
+
+
+#endif
diff --git a/lib/csharp/src/Transport/TSocket.cs b/lib/csharp/src/Transport/TSocket.cs
new file mode 100644
index 0000000..d8fa335
--- /dev/null
+++ b/lib/csharp/src/Transport/TSocket.cs
@@ -0,0 +1,245 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Net.Sockets;
+
+namespace Thrift.Transport
+{
+    public class TSocket : TStreamTransport
+    {
+        private TcpClient client = null;
+        private string host = null;
+        private int port = 0;
+        private int timeout = 0;
+
+        public TSocket(TcpClient client)
+        {
+            this.client = client;
+
+            if (IsOpen)
+            {
+                inputStream = client.GetStream();
+                outputStream = client.GetStream();
+            }
+        }
+
+        public TSocket(string host, int port)
+            : this(host, port, 0)
+        {
+        }
+
+        public TSocket(string host, int port, int timeout)
+        {
+            this.host = host;
+            this.port = port;
+            this.timeout = timeout;
+
+            InitSocket();
+        }
+
+        private void InitSocket()
+        {
+            this.client = TSocketVersionizer.CreateTcpClient();
+            this.client.ReceiveTimeout = client.SendTimeout = timeout;
+            this.client.Client.NoDelay = true;
+        }
+
+        public int Timeout
+        {
+            set
+            {
+                client.ReceiveTimeout = client.SendTimeout = timeout = value;
+            }
+        }
+
+        public TcpClient TcpClient
+        {
+            get
+            {
+                return client;
+            }
+        }
+
+        public string Host
+        {
+            get
+            {
+                return host;
+            }
+        }
+
+        public int Port
+        {
+            get
+            {
+                return port;
+            }
+        }
+
+        public override bool IsOpen
+        {
+            get
+            {
+                if (client == null)
+                {
+                    return false;
+                }
+
+                return client.Connected;
+            }
+        }
+
+        public override void Open()
+        {
+            if (IsOpen)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
+            }
+
+            if (string.IsNullOrEmpty(host))
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
+            }
+
+            if (port <= 0)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
+            }
+
+            if (client == null)
+            {
+                InitSocket();
+            }
+
+            if (timeout == 0)            // no timeout -> infinite
+            {
+                client.Connect(host, port);
+            }
+            else                        // we have a timeout -> use it
+            {
+                ConnectHelper hlp = new ConnectHelper(client);
+                IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
+                bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
+                if (!bConnected)
+                {
+                    lock (hlp.Mutex)
+                    {
+                        if (hlp.CallbackDone)
+                        {
+                            asyncres.AsyncWaitHandle.Close();
+                            client.Close();
+                        }
+                        else
+                        {
+                            hlp.DoCleanup = true;
+                            client = null;
+                        }
+                    }
+                    throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
+                }
+            }
+
+            inputStream = client.GetStream();
+            outputStream = client.GetStream();
+        }
+
+
+        static void ConnectCallback(IAsyncResult asyncres)
+        {
+            ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
+            lock (hlp.Mutex)
+            {
+                hlp.CallbackDone = true;
+
+                try
+                {
+                    if (hlp.Client.Client != null)
+                        hlp.Client.EndConnect(asyncres);
+                }
+                catch (Exception)
+                {
+                    // catch that away
+                }
+
+                if (hlp.DoCleanup)
+                {
+                    try
+                    {
+                        asyncres.AsyncWaitHandle.Close();
+                    }
+                    catch (Exception) { }
+
+                    try
+                    {
+                        if (hlp.Client is IDisposable)
+                            ((IDisposable)hlp.Client).Dispose();
+                    }
+                    catch (Exception) { }
+                    hlp.Client = null;
+                }
+            }
+        }
+
+        private class ConnectHelper
+        {
+            public object Mutex = new object();
+            public bool DoCleanup = false;
+            public bool CallbackDone = false;
+            public TcpClient Client;
+            public ConnectHelper(TcpClient client)
+            {
+                Client = client;
+            }
+        }
+
+        public override void Close()
+        {
+            base.Close();
+            if (client != null)
+            {
+                client.Close();
+                client = null;
+            }
+        }
+
+        #region " IDisposable Support "
+        private bool _IsDisposed;
+
+        // IDisposable
+        protected override void Dispose(bool disposing)
+        {
+            if (!_IsDisposed)
+            {
+                if (disposing)
+                {
+                    if (client != null)
+                        ((IDisposable)client).Dispose();
+                    base.Dispose(disposing);
+                }
+            }
+            _IsDisposed = true;
+        }
+        #endregion
+    }
+}
diff --git a/lib/csharp/src/Transport/TSocketVersionizer.cs b/lib/csharp/src/Transport/TSocketVersionizer.cs
new file mode 100644
index 0000000..8c2f8e9
--- /dev/null
+++ b/lib/csharp/src/Transport/TSocketVersionizer.cs
@@ -0,0 +1,78 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Text;
+#if NET45
+using System.Threading.Tasks;
+#endif
+
+namespace Thrift.Transport
+{
+    /// <summary>
+    /// PropertyInfo for the DualMode property of the System.Net.Sockets.Socket class. Used to determine if the sockets are capable of
+    /// automatic IPv4 and IPv6 handling. If DualMode is present the sockets automatically handle IPv4 and IPv6 connections.
+    /// If the DualMode is not available the system configuration determines whether IPv4 or IPv6 is used.
+    /// </summary>
+    internal static class TSocketVersionizer
+    {
+        /// <summary>
+        /// Creates a TcpClient according to the capabilities of the used framework.
+        /// </summary>
+        internal static TcpClient CreateTcpClient()
+        {
+            TcpClient client = null;
+
+#if NET45
+            client = new TcpClient(AddressFamily.InterNetworkV6);
+            client.Client.DualMode = true;
+#else
+            client = new TcpClient(AddressFamily.InterNetwork);
+#endif
+
+            return client;
+        }
+
+        /// <summary>
+        /// Creates a TcpListener according to the capabilities of the used framework.
+        /// </summary>
+        internal static TcpListener CreateTcpListener(Int32 port)
+        {
+            TcpListener listener = null;
+
+#if NET45
+            listener = new TcpListener(System.Net.IPAddress.IPv6Any, port);
+            listener.Server.DualMode = true;
+#else
+
+            listener = new TcpListener(System.Net.IPAddress.Any, port);
+#endif
+
+            return listener;
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TStreamTransport.cs b/lib/csharp/src/Transport/TStreamTransport.cs
new file mode 100644
index 0000000..304599f
--- /dev/null
+++ b/lib/csharp/src/Transport/TStreamTransport.cs
@@ -0,0 +1,128 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.IO;
+
+namespace Thrift.Transport
+{
+    public class TStreamTransport : TTransport
+    {
+        protected Stream inputStream;
+        protected Stream outputStream;
+
+        protected TStreamTransport()
+        {
+        }
+
+        public TStreamTransport(Stream inputStream, Stream outputStream)
+        {
+            this.inputStream = inputStream;
+            this.outputStream = outputStream;
+        }
+
+        public Stream OutputStream
+        {
+            get { return outputStream; }
+        }
+
+        public Stream InputStream
+        {
+            get { return inputStream; }
+        }
+
+        public override bool IsOpen
+        {
+            get { return true; }
+        }
+
+        public override void Open()
+        {
+        }
+
+        public override void Close()
+        {
+            if (inputStream != null)
+            {
+                inputStream.Close();
+                inputStream = null;
+            }
+            if (outputStream != null)
+            {
+                outputStream.Close();
+                outputStream = null;
+            }
+        }
+
+        public override int Read(byte[] buf, int off, int len)
+        {
+            if (inputStream == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot read from null inputstream");
+            }
+
+            return inputStream.Read(buf, off, len);
+        }
+
+        public override void Write(byte[] buf, int off, int len)
+        {
+            if (outputStream == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot write to null outputstream");
+            }
+
+            outputStream.Write(buf, off, len);
+        }
+
+        public override void Flush()
+        {
+            if (outputStream == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot flush null outputstream");
+            }
+
+            outputStream.Flush();
+        }
+
+
+        #region " IDisposable Support "
+        private bool _IsDisposed;
+
+        // IDisposable
+        protected override void Dispose(bool disposing)
+        {
+            if (!_IsDisposed)
+            {
+                if (disposing)
+                {
+                    if (InputStream != null)
+                        InputStream.Dispose();
+                    if (OutputStream != null)
+                        OutputStream.Dispose();
+                }
+            }
+            _IsDisposed = true;
+        }
+        #endregion
+    }
+}
diff --git a/lib/csharp/src/Transport/TTLSServerSocket.cs b/lib/csharp/src/Transport/TTLSServerSocket.cs
new file mode 100644
index 0000000..716a97c
--- /dev/null
+++ b/lib/csharp/src/Transport/TTLSServerSocket.cs
@@ -0,0 +1,223 @@
+/**
+ * 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.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Thrift.Transport
+{
+    /// <summary>
+    /// SSL Server Socket Wrapper Class
+    /// </summary>
+    public class TTLSServerSocket : TServerTransport
+    {
+        /// <summary>
+        /// Underlying tcp server
+        /// </summary>
+        private TcpListener server = null;
+
+        /// <summary>
+        /// The port where the socket listen
+        /// </summary>
+        private int port = 0;
+
+        /// <summary>
+        /// Timeout for the created server socket
+        /// </summary>
+        private readonly int clientTimeout;
+
+        /// <summary>
+        /// Whether or not to wrap new TSocket connections in buffers
+        /// </summary>
+        private bool useBufferedSockets = false;
+
+        /// <summary>
+        /// The servercertificate with the private- and public-key
+        /// </summary>
+        private X509Certificate serverCertificate;
+
+        /// <summary>
+        /// The function to validate the client certificate.
+        /// </summary>
+        private RemoteCertificateValidationCallback clientCertValidator;
+
+        /// <summary>
+        /// The function to determine which certificate to use.
+        /// </summary>
+        private LocalCertificateSelectionCallback localCertificateSelectionCallback;
+
+        /// <summary>
+        /// The SslProtocols value that represents the protocol used for authentication.
+        /// </summary>
+        private readonly SslProtocols sslProtocols;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TTLSServerSocket" /> class.
+        /// </summary>
+        /// <param name="port">The port where the server runs.</param>
+        /// <param name="certificate">The certificate object.</param>
+        public TTLSServerSocket(int port, X509Certificate2 certificate)
+            : this(port, 0, certificate)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TTLSServerSocket" /> class.
+        /// </summary>
+        /// <param name="port">The port where the server runs.</param>
+        /// <param name="clientTimeout">Send/receive timeout.</param>
+        /// <param name="certificate">The certificate object.</param>
+        public TTLSServerSocket(int port, int clientTimeout, X509Certificate2 certificate)
+            : this(port, clientTimeout, false, certificate)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TTLSServerSocket" /> class.
+        /// </summary>
+        /// <param name="port">The port where the server runs.</param>
+        /// <param name="clientTimeout">Send/receive timeout.</param>
+        /// <param name="useBufferedSockets">If set to <c>true</c> [use buffered sockets].</param>
+        /// <param name="certificate">The certificate object.</param>
+        /// <param name="clientCertValidator">The certificate validator.</param>
+        /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+        /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+        public TTLSServerSocket(
+            int port,
+            int clientTimeout,
+            bool useBufferedSockets,
+            X509Certificate2 certificate,
+            RemoteCertificateValidationCallback clientCertValidator = null,
+            LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+            // TODO: Enable Tls11 and Tls12 (TLS 1.1 and 1.2) by default once we start using .NET 4.5+.
+            SslProtocols sslProtocols = SslProtocols.Tls)
+        {
+            if (!certificate.HasPrivateKey)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.Unknown, "Your server-certificate needs to have a private key");
+            }
+
+            this.port = port;
+            this.clientTimeout = clientTimeout;
+            this.serverCertificate = certificate;
+            this.useBufferedSockets = useBufferedSockets;
+            this.clientCertValidator = clientCertValidator;
+            this.localCertificateSelectionCallback = localCertificateSelectionCallback;
+            this.sslProtocols = sslProtocols;
+            try
+            {
+                // Create server socket
+                this.server = TSocketVersionizer.CreateTcpListener(this.port);
+                this.server.Server.NoDelay = true;
+            }
+            catch (Exception ex)
+            {
+                server = null;
+                throw new TTransportException("Could not create ServerSocket on port " + this.port + ".", ex);
+            }
+        }
+
+        /// <summary>
+        /// Starts the server.
+        /// </summary>
+        public override void Listen()
+        {
+            // Make sure accept is not blocking
+            if (this.server != null)
+            {
+                try
+                {
+                    this.server.Start();
+                }
+                catch (SocketException sx)
+                {
+                    throw new TTransportException("Could not accept on listening socket: " + sx.Message, sx);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Callback for Accept Implementation
+        /// </summary>
+        /// <returns>
+        /// TTransport-object.
+        /// </returns>
+        protected override TTransport AcceptImpl()
+        {
+            if (this.server == null)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
+            }
+
+            try
+            {
+                TcpClient client = this.server.AcceptTcpClient();
+                client.SendTimeout = client.ReceiveTimeout = this.clientTimeout;
+
+                //wrap the client in an SSL Socket passing in the SSL cert
+                TTLSSocket socket = new TTLSSocket(
+                    client,
+                    this.serverCertificate,
+                    true,
+                    this.clientCertValidator,
+                    this.localCertificateSelectionCallback,
+                    this.sslProtocols);
+
+                socket.setupTLS();
+
+                if (useBufferedSockets)
+                {
+                    TBufferedTransport trans = new TBufferedTransport(socket);
+                    return trans;
+                }
+                else
+                {
+                    return socket;
+                }
+
+            }
+            catch (Exception ex)
+            {
+                throw new TTransportException(ex.ToString(), ex);
+            }
+        }
+
+        /// <summary>
+        /// Stops the Server
+        /// </summary>
+        public override void Close()
+        {
+            if (this.server != null)
+            {
+                try
+                {
+                    this.server.Stop();
+                }
+                catch (Exception ex)
+                {
+                    throw new TTransportException("WARNING: Could not close server socket: " + ex, ex);
+                }
+                this.server = null;
+            }
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TTLSSocket.cs b/lib/csharp/src/Transport/TTLSSocket.cs
new file mode 100644
index 0000000..06286dc
--- /dev/null
+++ b/lib/csharp/src/Transport/TTLSSocket.cs
@@ -0,0 +1,445 @@
+/**
+ * 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.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Thrift.Transport
+{
+    /// <summary>
+    /// SSL Socket Wrapper class
+    /// </summary>
+    public class TTLSSocket : TStreamTransport
+    {
+        /// <summary>
+        /// Internal TCP Client
+        /// </summary>
+        private TcpClient client;
+
+        /// <summary>
+        /// The host
+        /// </summary>
+        private string host;
+
+        /// <summary>
+        /// The port
+        /// </summary>
+        private int port;
+
+        /// <summary>
+        /// The timeout for the connection
+        /// </summary>
+        private int timeout;
+
+        /// <summary>
+        /// Internal SSL Stream for IO
+        /// </summary>
+        private SslStream secureStream;
+
+        /// <summary>
+        /// Defines wheter or not this socket is a server socket<br/>
+        /// This is used for the TLS-authentication
+        /// </summary>
+        private bool isServer;
+
+        /// <summary>
+        /// The certificate
+        /// </summary>
+        private X509Certificate certificate;
+
+        /// <summary>
+        /// User defined certificate validator.
+        /// </summary>
+        private RemoteCertificateValidationCallback certValidator;
+
+        /// <summary>
+        /// The function to determine which certificate to use.
+        /// </summary>
+        private LocalCertificateSelectionCallback localCertificateSelectionCallback;
+
+        /// <summary>
+        /// The SslProtocols value that represents the protocol used for authentication.SSL protocols to be used.
+        /// </summary>
+        private readonly SslProtocols sslProtocols;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TTLSSocket"/> class.
+        /// </summary>
+        /// <param name="client">An already created TCP-client</param>
+        /// <param name="certificate">The certificate.</param>
+        /// <param name="isServer">if set to <c>true</c> [is server].</param>
+        /// <param name="certValidator">User defined cert validator.</param>
+        /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+        /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+        public TTLSSocket(
+            TcpClient client,
+            X509Certificate certificate,
+            bool isServer = false,
+            RemoteCertificateValidationCallback certValidator = null,
+            LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+            // TODO: Enable Tls11 and Tls12 (TLS 1.1 and 1.2) by default once we start using .NET 4.5+.
+            SslProtocols sslProtocols = SslProtocols.Tls)
+        {
+            this.client = client;
+            this.certificate = certificate;
+            this.certValidator = certValidator;
+            this.localCertificateSelectionCallback = localCertificateSelectionCallback;
+            this.sslProtocols = sslProtocols;
+            this.isServer = isServer;
+            if (isServer && certificate == null)
+            {
+                throw new ArgumentException("TTLSSocket needs certificate to be used for server", "certificate");
+            }
+
+            if (IsOpen)
+            {
+                base.inputStream = client.GetStream();
+                base.outputStream = client.GetStream();
+            }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TTLSSocket"/> class.
+        /// </summary>
+        /// <param name="host">The host, where the socket should connect to.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="certificatePath">The certificate path.</param>
+        /// <param name="certValidator">User defined cert validator.</param>
+        /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+        /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+        public TTLSSocket(
+            string host,
+            int port,
+            string certificatePath,
+            RemoteCertificateValidationCallback certValidator = null,
+            LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+            SslProtocols sslProtocols = SslProtocols.Tls)
+            : this(host, port, 0, X509Certificate.CreateFromCertFile(certificatePath), certValidator, localCertificateSelectionCallback, sslProtocols)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TTLSSocket"/> class.
+        /// </summary>
+        /// <param name="host">The host, where the socket should connect to.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="certificate">The certificate.</param>
+        /// <param name="certValidator">User defined cert validator.</param>
+        /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+        /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+        public TTLSSocket(
+            string host,
+            int port,
+            X509Certificate certificate = null,
+            RemoteCertificateValidationCallback certValidator = null,
+            LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+            SslProtocols sslProtocols = SslProtocols.Tls)
+            : this(host, port, 0, certificate, certValidator, localCertificateSelectionCallback, sslProtocols)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TTLSSocket"/> class.
+        /// </summary>
+        /// <param name="host">The host, where the socket should connect to.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="timeout">The timeout.</param>
+        /// <param name="certificate">The certificate.</param>
+        /// <param name="certValidator">User defined cert validator.</param>
+        /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+        /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+        public TTLSSocket(
+            string host,
+            int port,
+            int timeout,
+            X509Certificate certificate,
+            RemoteCertificateValidationCallback certValidator = null,
+            LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+            SslProtocols sslProtocols = SslProtocols.Tls)
+        {
+            this.host = host;
+            this.port = port;
+            this.timeout = timeout;
+            this.certificate = certificate;
+            this.certValidator = certValidator;
+            this.localCertificateSelectionCallback = localCertificateSelectionCallback;
+            this.sslProtocols = sslProtocols;
+
+            InitSocket();
+        }
+
+        /// <summary>
+        /// Creates the TcpClient and sets the timeouts
+        /// </summary>
+        private void InitSocket()
+        {
+            client = TSocketVersionizer.CreateTcpClient();
+            client.ReceiveTimeout = client.SendTimeout = timeout;
+            client.Client.NoDelay = true;
+        }
+
+        /// <summary>
+        /// Sets Send / Recv Timeout for IO
+        /// </summary>
+        public int Timeout
+        {
+            set
+            {
+                this.client.ReceiveTimeout = this.client.SendTimeout = this.timeout = value;
+            }
+        }
+
+        /// <summary>
+        /// Gets the TCP client.
+        /// </summary>
+        public TcpClient TcpClient
+        {
+            get
+            {
+                return client;
+            }
+        }
+
+        /// <summary>
+        /// Gets the host.
+        /// </summary>
+        public string Host
+        {
+            get
+            {
+                return host;
+            }
+        }
+
+        /// <summary>
+        /// Gets the port.
+        /// </summary>
+        public int Port
+        {
+            get
+            {
+                return port;
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether TCP Client is Cpen
+        /// </summary>
+        public override bool IsOpen
+        {
+            get
+            {
+                if (this.client == null)
+                {
+                    return false;
+                }
+
+                return this.client.Connected;
+            }
+        }
+
+        /// <summary>
+        /// Validates the certificates!<br/>
+        /// </summary>
+        /// <param name="sender">The sender-object.</param>
+        /// <param name="certificate">The used certificate.</param>
+        /// <param name="chain">The certificate chain.</param>
+        /// <param name="sslValidationErrors">An enum, which lists all the errors from the .NET certificate check.</param>
+        /// <returns></returns>
+        private bool DefaultCertificateValidator(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslValidationErrors)
+        {
+            return (sslValidationErrors == SslPolicyErrors.None);
+        }
+
+        /// <summary>
+        /// Connects to the host and starts the routine, which sets up the TLS
+        /// </summary>
+        public override void Open()
+        {
+            if (IsOpen)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
+            }
+
+            if (string.IsNullOrEmpty(host))
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
+            }
+
+            if (port <= 0)
+            {
+                throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
+            }
+
+            if (client == null)
+            {
+                InitSocket();
+            }
+
+            if (timeout == 0)            // no timeout -> infinite
+            {
+                client.Connect(host, port);
+            }
+            else                        // we have a timeout -> use it
+            {
+                ConnectHelper hlp = new ConnectHelper(client);
+                IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
+                bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
+                if (!bConnected)
+                {
+                    lock (hlp.Mutex)
+                    {
+                        if (hlp.CallbackDone)
+                        {
+                            asyncres.AsyncWaitHandle.Close();
+                            client.Close();
+                        }
+                        else
+                        {
+                            hlp.DoCleanup = true;
+                            client = null;
+                        }
+                    }
+                    throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
+                }
+            }
+
+            setupTLS();
+        }
+
+        /// <summary>
+        /// Creates a TLS-stream and lays it over the existing socket
+        /// </summary>
+        public void setupTLS()
+        {
+            RemoteCertificateValidationCallback validator = this.certValidator ?? DefaultCertificateValidator;
+
+            if (this.localCertificateSelectionCallback != null)
+            {
+                this.secureStream = new SslStream(
+                    this.client.GetStream(),
+                    false,
+                    validator,
+                    this.localCertificateSelectionCallback
+                );
+            }
+            else
+            {
+                this.secureStream = new SslStream(
+                    this.client.GetStream(),
+                    false,
+                    validator
+                );
+            }
+
+            try
+            {
+                if (isServer)
+                {
+                    // Server authentication
+                    this.secureStream.AuthenticateAsServer(this.certificate, this.certValidator != null, sslProtocols, true);
+                }
+                else
+                {
+                    // Client authentication
+                    X509CertificateCollection certs = certificate != null ? new X509CertificateCollection { certificate } : new X509CertificateCollection();
+                    this.secureStream.AuthenticateAsClient(host, certs, sslProtocols, true);
+                }
+            }
+            catch (Exception)
+            {
+                this.Close();
+                throw;
+            }
+
+            inputStream = this.secureStream;
+            outputStream = this.secureStream;
+        }
+        
+        static void ConnectCallback(IAsyncResult asyncres)
+        {
+            ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
+            lock (hlp.Mutex)
+            {
+                hlp.CallbackDone = true;
+
+                try
+                {
+                    if (hlp.Client.Client != null)
+                        hlp.Client.EndConnect(asyncres);
+                }
+                catch (Exception)
+                {
+                    // catch that away
+                }
+
+                if (hlp.DoCleanup)
+                {
+                    try
+                    {
+                        asyncres.AsyncWaitHandle.Close();
+                    }
+                    catch (Exception) { }
+
+                    try
+                    {
+                        if (hlp.Client is IDisposable)
+                            ((IDisposable)hlp.Client).Dispose();
+                    }
+                    catch (Exception) { }
+                    hlp.Client = null;
+                }
+            }
+        }
+
+        private class ConnectHelper
+        {
+            public object Mutex = new object();
+            public bool DoCleanup = false;
+            public bool CallbackDone = false;
+            public TcpClient Client;
+            public ConnectHelper(TcpClient client)
+            {
+                Client = client;
+            }
+        }
+
+        /// <summary>
+        /// Closes the SSL Socket
+        /// </summary>
+        public override void Close()
+        {
+            base.Close();
+            if (this.client != null)
+            {
+                this.client.Close();
+                this.client = null;
+            }
+
+            if (this.secureStream != null)
+            {
+                this.secureStream.Close();
+                this.secureStream = null;
+            }
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TTransport.cs b/lib/csharp/src/Transport/TTransport.cs
new file mode 100644
index 0000000..5e4ac22
--- /dev/null
+++ b/lib/csharp/src/Transport/TTransport.cs
@@ -0,0 +1,146 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.IO;
+
+namespace Thrift.Transport
+{
+    public abstract class TTransport : IDisposable
+    {
+        public abstract bool IsOpen
+        {
+            get;
+        }
+
+        private byte[] _peekBuffer = new byte[1];
+        private bool _hasPeekByte;
+
+        public bool Peek()
+        {
+            //If we already have a byte read but not consumed, do nothing.
+            if (_hasPeekByte)
+                return true;
+
+            //If transport closed we can't peek.
+            if (!IsOpen)
+                return false;
+
+            //Try to read one byte. If succeeds we will need to store it for the next read.
+            try
+            {
+                int bytes = Read(_peekBuffer, 0, 1);
+                if (bytes == 0)
+                    return false;
+            }
+            catch (IOException)
+            {
+                return false;
+            }
+
+            _hasPeekByte = true;
+            return true;
+        }
+
+        public abstract void Open();
+
+        public abstract void Close();
+
+        protected static void ValidateBufferArgs(byte[] buf, int off, int len)
+        {
+            if (buf == null)
+                throw new ArgumentNullException("buf");
+            if (off < 0)
+                throw new ArgumentOutOfRangeException("Buffer offset is smaller than zero.");
+            if (len < 0)
+                throw new ArgumentOutOfRangeException("Buffer length is smaller than zero.");
+            if (off + len > buf.Length)
+                throw new ArgumentOutOfRangeException("Not enough data.");
+        }
+
+        public abstract int Read(byte[] buf, int off, int len);
+
+        public int ReadAll(byte[] buf, int off, int len)
+        {
+            ValidateBufferArgs(buf, off, len);
+            int got = 0;
+
+            //If we previously peeked a byte, we need to use that first.
+            if (_hasPeekByte)
+            {
+                buf[off + got++] = _peekBuffer[0];
+                _hasPeekByte = false;
+            }
+
+            while (got < len)
+            {
+                int ret = Read(buf, off + got, len - got);
+                if (ret <= 0)
+                {
+                    throw new TTransportException(
+                        TTransportException.ExceptionType.EndOfFile,
+                        "Cannot read, Remote side has closed");
+                }
+                got += ret;
+            }
+            return got;
+        }
+
+        public virtual void Write(byte[] buf)
+        {
+            Write(buf, 0, buf.Length);
+        }
+
+        public abstract void Write(byte[] buf, int off, int len);
+
+        public virtual void Flush()
+        {
+        }
+
+        public virtual IAsyncResult BeginFlush(AsyncCallback callback, object state)
+        {
+            throw new TTransportException(
+                TTransportException.ExceptionType.Unknown,
+                "Asynchronous operations are not supported by this transport.");
+        }
+
+        public virtual void EndFlush(IAsyncResult asyncResult)
+        {
+            throw new TTransportException(
+                TTransportException.ExceptionType.Unknown,
+                "Asynchronous operations are not supported by this transport.");
+        }
+
+        #region " IDisposable Support "
+        // IDisposable
+        protected abstract void Dispose(bool disposing);
+
+        public void Dispose()
+        {
+            // Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+        #endregion
+    }
+}
diff --git a/lib/csharp/src/Transport/TTransportException.cs b/lib/csharp/src/Transport/TTransportException.cs
new file mode 100644
index 0000000..7f6cc18
--- /dev/null
+++ b/lib/csharp/src/Transport/TTransportException.cs
@@ -0,0 +1,69 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift.Transport
+{
+    public class TTransportException : TException
+    {
+        protected ExceptionType type;
+
+        public TTransportException()
+            : base()
+        {
+        }
+
+        public TTransportException(ExceptionType type)
+            : this()
+        {
+            this.type = type;
+        }
+
+        public TTransportException(ExceptionType type, string message, Exception inner = null)
+            : base(message, inner)
+        {
+            this.type = type;
+        }
+
+        public TTransportException(string message, Exception inner = null)
+            : base(message, inner)
+        {
+        }
+
+        public ExceptionType Type
+        {
+            get { return type; }
+        }
+
+        public enum ExceptionType
+        {
+            Unknown,
+            NotOpen,
+            AlreadyOpen,
+            TimedOut,
+            EndOfFile,
+            Interrupted
+        }
+    }
+}
diff --git a/lib/csharp/src/Transport/TTransportFactory.cs b/lib/csharp/src/Transport/TTransportFactory.cs
new file mode 100644
index 0000000..47a0c62
--- /dev/null
+++ b/lib/csharp/src/Transport/TTransportFactory.cs
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift.Transport
+{
+    /// <summary>
+    /// From Mark Slee &amp; Aditya Agarwal of Facebook:
+    /// Factory class used to create wrapped instance of Transports.
+    /// This is used primarily in servers, which get Transports from
+    /// a ServerTransport and then may want to mutate them (i.e. create
+    /// a BufferedTransport from the underlying base transport)
+    /// </summary>
+    public class TTransportFactory
+    {
+        public virtual TTransport GetTransport(TTransport trans)
+        {
+            return trans;
+        }
+    }
+}