diff --git a/lib/csharp/src/Protocol/TCompactProtocol.cs b/lib/csharp/src/Protocol/TCompactProtocol.cs
new file mode 100644
index 0000000..a5cdf9d
--- /dev/null
+++ b/lib/csharp/src/Protocol/TCompactProtocol.cs
@@ -0,0 +1,850 @@
+/**
+ * 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.Text;
+using Thrift.Transport;
+using System.Collections;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Thrift.Protocol
+{
+    public class TCompactProtocol : TProtocol
+    {
+        private static TStruct ANONYMOUS_STRUCT = new TStruct("");
+        private static TField TSTOP = new TField("", TType.Stop, (short)0);
+
+        private static byte[] ttypeToCompactType = new byte[16];
+
+        private const byte PROTOCOL_ID = 0x82;
+        private const byte VERSION = 1;
+        private const byte VERSION_MASK = 0x1f; // 0001 1111
+        private const byte TYPE_MASK = 0xE0; // 1110 0000
+        private const int TYPE_SHIFT_AMOUNT = 5;
+
+        /**
+         * All of the on-wire type codes.
+         */
+        private static class Types
+        {
+            public const byte STOP = 0x00;
+            public const byte BOOLEAN_TRUE = 0x01;
+            public const byte BOOLEAN_FALSE = 0x02;
+            public const byte BYTE = 0x03;
+            public const byte I16 = 0x04;
+            public const byte I32 = 0x05;
+            public const byte I64 = 0x06;
+            public const byte DOUBLE = 0x07;
+            public const byte BINARY = 0x08;
+            public const byte LIST = 0x09;
+            public const byte SET = 0x0A;
+            public const byte MAP = 0x0B;
+            public const byte STRUCT = 0x0C;
+        }
+
+        /** 
+         * Used to keep track of the last field for the current and previous structs,
+         * so we can do the delta stuff.
+         */
+        private Stack<short> lastField_ = new Stack<short>(15);
+
+        private short lastFieldId_ = 0;
+
+        /**
+         * If we encounter a boolean field begin, save the TField here so it can 
+         * have the value incorporated.
+         */
+        private Nullable<TField> booleanField_;
+
+        /**
+         * If we Read a field header, and it's a boolean field, save the boolean 
+         * value here so that ReadBool can use it.
+         */
+        private  Nullable<Boolean> boolValue_;
+
+
+        #region CompactProtocol Factory
+
+        /**
+		  * Factory
+		  */
+        public class Factory : TProtocolFactory
+        {
+            public Factory() { }
+
+            public TProtocol GetProtocol(TTransport trans)
+            {
+                return new TCompactProtocol(trans);
+            }
+        }
+
+        #endregion
+
+        public TCompactProtocol(TTransport trans)
+            : base(trans)
+        {
+            ttypeToCompactType[(int)TType.Stop] = Types.STOP;
+            ttypeToCompactType[(int)TType.Bool] = Types.BOOLEAN_TRUE;
+            ttypeToCompactType[(int)TType.Byte] = Types.BYTE;
+            ttypeToCompactType[(int)TType.I16] = Types.I16;
+            ttypeToCompactType[(int)TType.I32] = Types.I32;
+            ttypeToCompactType[(int)TType.I64] = Types.I64;
+            ttypeToCompactType[(int)TType.Double] = Types.DOUBLE;
+            ttypeToCompactType[(int)TType.String] = Types.BINARY;
+            ttypeToCompactType[(int)TType.List] = Types.LIST;
+            ttypeToCompactType[(int)TType.Set] = Types.SET;
+            ttypeToCompactType[(int)TType.Map] = Types.MAP;
+            ttypeToCompactType[(int)TType.Struct] = Types.STRUCT;
+        }
+
+        public void reset()
+        {
+            lastField_.Clear();
+            lastFieldId_ = 0;
+        }
+
+        #region Write Methods
+
+
+        /** 
+         * Writes a byte without any possibility of all that field header nonsense. 
+         * Used internally by other writing methods that know they need to Write a byte.
+         */
+        private byte[] byteDirectBuffer = new byte[1];
+        private void WriteByteDirect(byte b)
+        {
+            byteDirectBuffer[0] = b;
+            trans.Write(byteDirectBuffer);
+        }
+
+        /** 
+         * Writes a byte without any possibility of all that field header nonsense.
+         */
+        private void WriteByteDirect(int n)
+        {
+            WriteByteDirect((byte)n);
+        }
+
+        /**
+         * Write an i32 as a varint. Results in 1-5 bytes on the wire.
+         * TODO: make a permanent buffer like WriteVarint64?
+         */
+        byte[] i32buf = new byte[5];
+        private void WriteVarint32(uint n)
+        {
+            int idx = 0;
+            while (true)
+            {
+                if ((n & ~0x7F) == 0)
+                {
+                    i32buf[idx++] = (byte)n;
+                    // WriteByteDirect((byte)n);
+                    break;
+                    // return;
+                }
+                else
+                {
+                    i32buf[idx++] = (byte)((n & 0x7F) | 0x80);
+                    // WriteByteDirect((byte)((n & 0x7F) | 0x80));
+                    n >>= 7;
+                }
+            }
+            trans.Write(i32buf, 0, idx);
+        }
+
+        /**
+        * Write a message header to the wire. Compact Protocol messages contain the
+        * protocol version so we can migrate forwards in the future if need be.
+        */
+        public override void WriteMessageBegin(TMessage message)
+        {
+            WriteByteDirect(PROTOCOL_ID);
+            WriteByteDirect((byte)((VERSION & VERSION_MASK) | ((((uint)message.Type) << TYPE_SHIFT_AMOUNT) & TYPE_MASK)));
+            WriteVarint32((uint)message.SeqID);
+            WriteString(message.Name);
+        }
+
+        /**
+         * Write a struct begin. This doesn't actually put anything on the wire. We 
+         * use it as an opportunity to put special placeholder markers on the field
+         * stack so we can get the field id deltas correct.
+         */
+        public override void WriteStructBegin(TStruct strct)
+        {
+            lastField_.Push(lastFieldId_);
+            lastFieldId_ = 0;
+        }
+
+        /**
+         * Write a struct end. This doesn't actually put anything on the wire. We use
+         * this as an opportunity to pop the last field from the current struct off
+         * of the field stack.
+         */
+        public override void WriteStructEnd()
+        {
+            lastFieldId_ = lastField_.Pop();
+        }
+
+        /**
+         * Write a field header containing the field id and field type. If the
+         * difference between the current field id and the last one is small (< 15),
+         * then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
+         * field id will follow the type header as a zigzag varint.
+         */
+        public override void WriteFieldBegin(TField field)
+        {
+            if (field.Type == TType.Bool)
+            {
+                // we want to possibly include the value, so we'll wait.
+                booleanField_ = field;
+            }
+            else
+            {
+                WriteFieldBeginInternal(field, 0xFF);
+            }
+        }
+
+        /**
+         * The workhorse of WriteFieldBegin. It has the option of doing a 
+         * 'type override' of the type header. This is used specifically in the 
+         * boolean field case.
+         */
+        private void WriteFieldBeginInternal(TField field, byte typeOverride)
+        {
+            // short lastField = lastField_.Pop();
+
+            // if there's a type override, use that.
+            byte typeToWrite = typeOverride == 0xFF ? getCompactType(field.Type) : typeOverride;
+
+            // check if we can use delta encoding for the field id
+            if (field.ID > lastFieldId_ && field.ID - lastFieldId_ <= 15)
+            {
+                // Write them together
+                WriteByteDirect((field.ID - lastFieldId_) << 4 | typeToWrite);
+            }
+            else
+            {
+                // Write them separate
+                WriteByteDirect(typeToWrite);
+                WriteI16(field.ID);
+            }
+
+            lastFieldId_ = field.ID;
+            // lastField_.push(field.id);
+        }
+
+        /**
+         * Write the STOP symbol so we know there are no more fields in this struct.
+         */
+        public override void WriteFieldStop()
+        {
+            WriteByteDirect(Types.STOP);
+        }
+
+        /**
+         * Write a map header. If the map is empty, omit the key and value type 
+         * headers, as we don't need any additional information to skip it.
+         */
+        public override void WriteMapBegin(TMap map)
+        {
+            if (map.Count == 0)
+            {
+                WriteByteDirect(0);
+            }
+            else
+            {
+                WriteVarint32((uint)map.Count);
+                WriteByteDirect(getCompactType(map.KeyType) << 4 | getCompactType(map.ValueType));
+            }
+        }
+
+        /** 
+         * Write a list header.
+         */
+        public override void WriteListBegin(TList list)
+        {
+            WriteCollectionBegin(list.ElementType, list.Count);
+        }
+
+        /**
+         * Write a set header.
+         */
+        public override void WriteSetBegin(TSet set)
+        {
+            WriteCollectionBegin(set.ElementType, set.Count);
+        }
+
+        /**
+         * Write a boolean value. Potentially, this could be a boolean field, in 
+         * which case the field header info isn't written yet. If so, decide what the
+         * right type header is for the value and then Write the field header. 
+         * Otherwise, Write a single byte.
+         */
+        public override void WriteBool(Boolean b)
+        {
+            if (booleanField_ != null)
+            {
+                // we haven't written the field header yet
+                WriteFieldBeginInternal(booleanField_.Value, b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE);
+                booleanField_ = null;
+            }
+            else
+            {
+                // we're not part of a field, so just Write the value.
+                WriteByteDirect(b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE);
+            }
+        }
+
+        /** 
+         * Write a byte. Nothing to see here!
+         */
+        public override void WriteByte(byte b)
+        {
+            WriteByteDirect(b);
+        }
+
+        /**
+         * Write an I16 as a zigzag varint.
+         */
+        public override void WriteI16(short i16)
+        {
+            WriteVarint32(intToZigZag(i16));
+        }
+
+        /**
+         * Write an i32 as a zigzag varint.
+         */
+        public override void WriteI32(int i32)
+        {
+            WriteVarint32(intToZigZag(i32));
+        }
+
+        /**
+         * Write an i64 as a zigzag varint.
+         */
+        public override void WriteI64(long i64)
+        {
+            WriteVarint64(longToZigzag(i64));
+        }
+
+        /**
+         * Write a double to the wire as 8 bytes.
+         */
+        public override void WriteDouble(double dub)
+        {
+            byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
+            fixedLongToBytes(BitConverter.DoubleToInt64Bits(dub), data, 0);
+            trans.Write(data);
+        }
+
+        /**
+         * Write a string to the wire with a varint size preceding.
+         */
+        public override void WriteString(String str)
+        {
+            byte[] bytes = UTF8Encoding.UTF8.GetBytes(str);
+            WriteBinary(bytes, 0, bytes.Length);
+        }
+
+        /**
+         * Write a byte array, using a varint for the size. 
+         */
+        public override void WriteBinary(byte[] bin)
+        {
+            WriteBinary(bin, 0, bin.Length);
+        }
+
+        private void WriteBinary(byte[] buf, int offset, int length)
+        {
+            WriteVarint32((uint)length);
+            trans.Write(buf, offset, length);
+        }
+
+        //
+        // These methods are called by structs, but don't actually have any wire 
+        // output or purpose.
+        // 
+
+        public override void WriteMessageEnd() { }
+        public override void WriteMapEnd() { }
+        public override void WriteListEnd() { }
+        public override void WriteSetEnd() { }
+        public override void WriteFieldEnd() { }
+
+        //
+        // Internal writing methods
+        //
+
+        /**
+         * Abstract method for writing the start of lists and sets. List and sets on 
+         * the wire differ only by the type indicator.
+         */
+        protected void WriteCollectionBegin(TType elemType, int size)
+        {
+            if (size <= 14)
+            {
+                WriteByteDirect(size << 4 | getCompactType(elemType));
+            }
+            else
+            {
+                WriteByteDirect(0xf0 | getCompactType(elemType));
+                WriteVarint32((uint)size);
+            }
+        }
+
+        /**
+         * Write an i64 as a varint. Results in 1-10 bytes on the wire.
+         */
+        byte[] varint64out = new byte[10];
+        private void WriteVarint64(ulong n)
+        {
+            int idx = 0;
+            while (true)
+            {
+                if ((n & ~(ulong)0x7FL) == 0)
+                {
+                    varint64out[idx++] = (byte)n;
+                    break;
+                }
+                else
+                {
+                    varint64out[idx++] = ((byte)((n & 0x7F) | 0x80));
+                    n >>= 7;
+                }
+            }
+            trans.Write(varint64out, 0, idx);
+        }
+
+        /**
+         * Convert l into a zigzag long. This allows negative numbers to be 
+         * represented compactly as a varint.
+         */
+        private ulong longToZigzag(long n)
+        {
+            return (ulong)(((ulong)n << 1) ^ ((ulong)n >> 63));
+        }
+
+        /**
+         * Convert n into a zigzag int. This allows negative numbers to be 
+         * represented compactly as a varint.
+         */
+        private uint intToZigZag(int n)
+        {
+            return (uint)(((uint)n << 1) ^ ((uint)n >> 31));
+        }
+
+        /**
+         * Convert a long into little-endian bytes in buf starting at off and going 
+         * until off+7.
+         */
+        private void fixedLongToBytes(long n, byte[] buf, int off)
+        {
+            buf[off + 0] = (byte)(n & 0xff);
+            buf[off + 1] = (byte)((n >> 8) & 0xff);
+            buf[off + 2] = (byte)((n >> 16) & 0xff);
+            buf[off + 3] = (byte)((n >> 24) & 0xff);
+            buf[off + 4] = (byte)((n >> 32) & 0xff);
+            buf[off + 5] = (byte)((n >> 40) & 0xff);
+            buf[off + 6] = (byte)((n >> 48) & 0xff);
+            buf[off + 7] = (byte)((n >> 56) & 0xff);
+        }
+
+        #endregion
+
+        #region ReadMethods
+
+        /**
+   * Read a message header. 
+   */
+        public override TMessage ReadMessageBegin()
+        {
+            byte protocolId = ReadByte();
+            if (protocolId != PROTOCOL_ID)
+            {
+                throw new TProtocolException("Expected protocol id " + PROTOCOL_ID.ToString("X") + " but got " + protocolId.ToString("X"));
+            }
+            byte versionAndType = ReadByte();
+            byte version = (byte)(versionAndType & VERSION_MASK);
+            if (version != VERSION)
+            {
+                throw new TProtocolException("Expected version " + VERSION + " but got " + version);
+            }
+            byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03);
+            int seqid = (int)ReadVarint32();
+            String messageName = ReadString();
+            return new TMessage(messageName, (TMessageType)type, seqid);
+        }
+
+        /**
+         * Read a struct begin. There's nothing on the wire for this, but it is our
+         * opportunity to push a new struct begin marker onto the field stack.
+         */
+        public override TStruct ReadStructBegin()
+        {
+            lastField_.Push(lastFieldId_);
+            lastFieldId_ = 0;
+            return ANONYMOUS_STRUCT;
+        }
+
+        /**
+         * Doesn't actually consume any wire data, just removes the last field for 
+         * this struct from the field stack.
+         */
+        public override void ReadStructEnd()
+        {
+            // consume the last field we Read off the wire.
+            lastFieldId_ = lastField_.Pop();
+        }
+
+        /**
+         * Read a field header off the wire. 
+         */
+        public override TField ReadFieldBegin()
+        {
+            byte type = ReadByte();
+
+            // if it's a stop, then we can return immediately, as the struct is over.
+            if (type == Types.STOP)
+            {
+                return TSTOP;
+            }
+
+            short fieldId;
+
+            // mask off the 4 MSB of the type header. it could contain a field id delta.
+            short modifier = (short)((type & 0xf0) >> 4);
+            if (modifier == 0)
+            {
+                // not a delta. look ahead for the zigzag varint field id.
+                fieldId = ReadI16();
+            }
+            else
+            {
+                // has a delta. add the delta to the last Read field id.
+                fieldId = (short)(lastFieldId_ + modifier);
+            }
+
+            TField field = new TField("", getTType((byte)(type & 0x0f)), fieldId);
+
+            // if this happens to be a boolean field, the value is encoded in the type
+            if (isBoolType(type))
+            {
+                // save the boolean value in a special instance variable.
+                boolValue_ = (byte)(type & 0x0f) == Types.BOOLEAN_TRUE ? true : false;
+            }
+
+            // push the new field onto the field stack so we can keep the deltas going.
+            lastFieldId_ = field.ID;
+            return field;
+        }
+
+        /** 
+         * Read a map header off the wire. If the size is zero, skip Reading the key
+         * and value type. This means that 0-length maps will yield TMaps without the
+         * "correct" types.
+         */
+        public override TMap ReadMapBegin()
+        {
+            int size = (int)ReadVarint32();
+            byte keyAndValueType = size == 0 ? (byte)0 : ReadByte();
+            return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
+        }
+
+        /**
+         * Read a list header off the wire. If the list size is 0-14, the size will 
+         * be packed into the element type header. If it's a longer list, the 4 MSB
+         * of the element type header will be 0xF, and a varint will follow with the
+         * true size.
+         */
+        public override TList ReadListBegin()
+        {
+            byte size_and_type = ReadByte();
+            int size = (size_and_type >> 4) & 0x0f;
+            if (size == 15)
+            {
+                size = (int)ReadVarint32();
+            }
+            TType type = getTType(size_and_type);
+            return new TList(type, size);
+        }
+
+        /**
+         * Read a set header off the wire. If the set size is 0-14, the size will 
+         * be packed into the element type header. If it's a longer set, the 4 MSB
+         * of the element type header will be 0xF, and a varint will follow with the
+         * true size.
+         */
+        public override TSet ReadSetBegin()
+        {
+            return new TSet(ReadListBegin());
+        }
+
+        /**
+         * Read a boolean off the wire. If this is a boolean field, the value should
+         * already have been Read during ReadFieldBegin, so we'll just consume the
+         * pre-stored value. Otherwise, Read a byte.
+         */
+        public override Boolean ReadBool()
+        {
+            if (boolValue_ != null)
+            {
+                bool result = boolValue_.Value;
+                boolValue_ = null;
+                return result;
+            }
+            return ReadByte() == Types.BOOLEAN_TRUE;
+        }
+
+        byte[] byteRawBuf = new byte[1];
+        /**
+         * Read a single byte off the wire. Nothing interesting here.
+         */
+        public override byte ReadByte()
+        {
+            trans.ReadAll(byteRawBuf, 0, 1);
+            return byteRawBuf[0];
+        }
+
+        /**
+         * Read an i16 from the wire as a zigzag varint.
+         */
+        public override short ReadI16()
+        {
+            return (short)zigzagToInt(ReadVarint32());
+        }
+
+        /**
+         * Read an i32 from the wire as a zigzag varint.
+         */
+        public override int ReadI32()
+        {
+            return zigzagToInt(ReadVarint32());
+        }
+
+        /**
+         * Read an i64 from the wire as a zigzag varint.
+         */
+        public override long ReadI64()
+        {
+            return zigzagToLong(ReadVarint64());
+        }
+
+        /**
+         * No magic here - just Read a double off the wire.
+         */
+        public override double ReadDouble()
+        {
+            byte[] longBits = new byte[8];
+            trans.ReadAll(longBits, 0, 8);
+            return BitConverter.Int64BitsToDouble(bytesToLong(longBits));
+        }
+
+        /**
+         * Reads a byte[] (via ReadBinary), and then UTF-8 decodes it.
+         */
+        public override String ReadString()
+        {
+            int length = (int)ReadVarint32();
+
+            if (length == 0)
+            {
+                return "";
+            }
+
+            return Encoding.UTF8.GetString(ReadBinary(length));
+        }
+
+        /**
+         * Read a byte[] from the wire. 
+         */
+        public override byte[] ReadBinary()
+        {
+            int length = (int)ReadVarint32();
+            if (length == 0) return new byte[0];
+
+            byte[] buf = new byte[length];
+            trans.ReadAll(buf, 0, length);
+            return buf;
+        }
+
+        /**
+         * Read a byte[] of a known length from the wire. 
+         */
+        private byte[] ReadBinary(int length)
+        {
+            if (length == 0) return new byte[0];
+
+            byte[] buf = new byte[length];
+            trans.ReadAll(buf, 0, length);
+            return buf;
+        }
+
+        //
+        // These methods are here for the struct to call, but don't have any wire 
+        // encoding.
+        //
+        public override void ReadMessageEnd() { }
+        public override void ReadFieldEnd() { }
+        public override void ReadMapEnd() { }
+        public override void ReadListEnd() { }
+        public override void ReadSetEnd() { }
+
+        //
+        // Internal Reading methods
+        //
+
+        /**
+         * Read an i32 from the wire as a varint. The MSB of each byte is set
+         * if there is another byte to follow. This can Read up to 5 bytes.
+         */
+        private uint ReadVarint32()
+        {
+            uint result = 0;
+            int shift = 0;
+            while (true)
+            {
+                byte b = ReadByte();
+                result |= (uint)(b & 0x7f) << shift;
+                if ((b & 0x80) != 0x80) break;
+                shift += 7;
+            }
+            return result;
+        }
+
+        /**
+         * Read an i64 from the wire as a proper varint. The MSB of each byte is set 
+         * if there is another byte to follow. This can Read up to 10 bytes.
+         */
+        private ulong ReadVarint64()
+        {
+            int shift = 0;
+            ulong result = 0;
+            while (true)
+            {
+                byte b = ReadByte();
+                result |= (ulong)(b & 0x7f) << shift;
+                if ((b & 0x80) != 0x80) break;
+                shift += 7;
+            }
+			
+            return result;
+        }
+
+        #endregion
+
+        //
+        // encoding helpers
+        //
+
+        /**
+         * Convert from zigzag int to int.
+         */
+        private int zigzagToInt(uint n)
+        {
+            return (int)(n >> 1) ^ (-(int)(n & 1));
+        }
+
+        /** 
+         * Convert from zigzag long to long.
+         */
+        private long zigzagToLong(ulong n)
+        {
+            return (long)(n >> 1) ^ (-(long)(n & 1));
+        }
+
+        /**
+         * Note that it's important that the mask bytes are long literals, 
+         * otherwise they'll default to ints, and when you shift an int left 56 bits,
+         * you just get a messed up int.
+         */
+        private long bytesToLong(byte[] bytes)
+        {
+            return
+              ((bytes[7] & 0xffL) << 56) |
+              ((bytes[6] & 0xffL) << 48) |
+              ((bytes[5] & 0xffL) << 40) |
+              ((bytes[4] & 0xffL) << 32) |
+              ((bytes[3] & 0xffL) << 24) |
+              ((bytes[2] & 0xffL) << 16) |
+              ((bytes[1] & 0xffL) << 8) |
+              ((bytes[0] & 0xffL));
+        }
+
+        //
+        // type testing and converting
+        //
+
+        private Boolean isBoolType(byte b)
+        {
+            int lowerNibble = b & 0x0f;
+            return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE;
+        }
+
+        /**
+         * Given a TCompactProtocol.Types constant, convert it to its corresponding 
+         * TType value.
+         */
+        private TType getTType(byte type)
+        {
+            switch ((byte)(type & 0x0f))
+            {
+                case Types.STOP:
+                    return TType.Stop;
+                case Types.BOOLEAN_FALSE:
+                case Types.BOOLEAN_TRUE:
+                    return TType.Bool;
+                case Types.BYTE:
+                    return TType.Byte;
+                case Types.I16:
+                    return TType.I16;
+                case Types.I32:
+                    return TType.I32;
+                case Types.I64:
+                    return TType.I64;
+                case Types.DOUBLE:
+                    return TType.Double;
+                case Types.BINARY:
+                    return TType.String;
+                case Types.LIST:
+                    return TType.List;
+                case Types.SET:
+                    return TType.Set;
+                case Types.MAP:
+                    return TType.Map;
+                case Types.STRUCT:
+                    return TType.Struct;
+                default:
+                    throw new TProtocolException("don't know what type: " + (byte)(type & 0x0f));
+            }
+        }
+
+        /**
+         * Given a TType value, find the appropriate TCompactProtocol.Types constant.
+         */
+        private byte getCompactType(TType ttype)
+        {
+            return ttypeToCompactType[(int)ttype];
+        }
+    }
+}
