diff --git a/lib/go/thrift/Makefile b/lib/go/thrift/Makefile
new file mode 100644
index 0000000..59f7862
--- /dev/null
+++ b/lib/go/thrift/Makefile
@@ -0,0 +1,58 @@
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include $(GOROOT)/src/Make.inc
+
+TARG=thrift
+GOFILES=\
+        tapplication_exception.go\
+        tbase.go\
+        tbinary_protocol.go\
+        tcompact_protocol.go\
+        tcompare.go\
+        tcontainer.go\
+        texception.go\
+        tfield.go\
+        tframed_transport.go\
+        thttp_client.go\
+        tiostream_transport.go\
+        tlist.go\
+        tjson_protocol.go\
+        tmap.go\
+        tmemory_buffer.go\
+        tmessage.go\
+        tmessagetype.go\
+        tnonblocking_server.go\
+        tnonblocking_server_socket.go\
+        tnonblocking_socket.go\
+        tnonblocking_transport.go\
+        tnumeric.go\
+        tprocessor.go\
+        tprocessor_factory.go\
+        tprotocol.go\
+        tprotocol_exception.go\
+        tprotocol_factory.go\
+        tserver.go\
+        tserver_socket.go\
+        tserver_transport.go\
+        tset.go\
+        tsimple_server.go\
+        tsimple_json_protocol.go\
+        tsocket.go\
+        tstruct.go\
+        ttransport.go\
+        ttransport_exception.go\
+        ttransport_factory.go\
+        ttype.go
+
+DIRS=\
+
+include $(GOROOT)/src/Make.pkg
+
+check:
+	gomake test
+
+-include ../Make.deps
+
+
diff --git a/lib/go/thrift/_testmain.go b/lib/go/thrift/_testmain.go
new file mode 100644
index 0000000..3b0abfb
--- /dev/null
+++ b/lib/go/thrift/_testmain.go
@@ -0,0 +1,68 @@
+package main
+
+import "./_xtest_"
+import "testing"
+import __regexp__ "regexp"
+
+var tests = []testing.InternalTest{
+	{"thrift_test.TestTApplicationException", thrift_test.TestTApplicationException},
+	{"thrift_test.TestReadWriteBinaryProtocol", thrift_test.TestReadWriteBinaryProtocol},
+	{"thrift_test.TestReadWriteCompactProtocol", thrift_test.TestReadWriteCompactProtocol},
+	{"thrift_test.TestTException", thrift_test.TestTException},
+	{"thrift_test.TestFramedTransport", thrift_test.TestFramedTransport},
+	{"thrift_test.TestHttpClient", thrift_test.TestHttpClient},
+	{"thrift_test.TestIOStreamTransport", thrift_test.TestIOStreamTransport},
+	{"thrift_test.TestWriteJSONProtocolBool", thrift_test.TestWriteJSONProtocolBool},
+	{"thrift_test.TestReadJSONProtocolBool", thrift_test.TestReadJSONProtocolBool},
+	{"thrift_test.TestWriteJSONProtocolByte", thrift_test.TestWriteJSONProtocolByte},
+	{"thrift_test.TestReadJSONProtocolByte", thrift_test.TestReadJSONProtocolByte},
+	{"thrift_test.TestWriteJSONProtocolI16", thrift_test.TestWriteJSONProtocolI16},
+	{"thrift_test.TestReadJSONProtocolI16", thrift_test.TestReadJSONProtocolI16},
+	{"thrift_test.TestWriteJSONProtocolI32", thrift_test.TestWriteJSONProtocolI32},
+	{"thrift_test.TestReadJSONProtocolI32", thrift_test.TestReadJSONProtocolI32},
+	{"thrift_test.TestWriteJSONProtocolI64", thrift_test.TestWriteJSONProtocolI64},
+	{"thrift_test.TestReadJSONProtocolI64", thrift_test.TestReadJSONProtocolI64},
+	{"thrift_test.TestWriteJSONProtocolDouble", thrift_test.TestWriteJSONProtocolDouble},
+	{"thrift_test.TestReadJSONProtocolDouble", thrift_test.TestReadJSONProtocolDouble},
+	{"thrift_test.TestWriteJSONProtocolString", thrift_test.TestWriteJSONProtocolString},
+	{"thrift_test.TestReadJSONProtocolString", thrift_test.TestReadJSONProtocolString},
+	{"thrift_test.TestWriteJSONProtocolBinary", thrift_test.TestWriteJSONProtocolBinary},
+	{"thrift_test.TestReadJSONProtocolBinary", thrift_test.TestReadJSONProtocolBinary},
+	{"thrift_test.TestWriteJSONProtocolList", thrift_test.TestWriteJSONProtocolList},
+	{"thrift_test.TestWriteJSONProtocolSet", thrift_test.TestWriteJSONProtocolSet},
+	{"thrift_test.TestWriteJSONProtocolMap", thrift_test.TestWriteJSONProtocolMap},
+	{"thrift_test.TestReadWriteJSONStruct", thrift_test.TestReadWriteJSONStruct},
+	{"thrift_test.TestReadWriteJSONProtocol", thrift_test.TestReadWriteJSONProtocol},
+	{"thrift_test.TestMemoryBuffer", thrift_test.TestMemoryBuffer},
+	{"thrift_test.TestNonblockingTransportServerToClient", thrift_test.TestNonblockingTransportServerToClient},
+	{"thrift_test.TestNonblockingTransportClientToServer", thrift_test.TestNonblockingTransportClientToServer},
+	{"thrift_test.TestNothing", thrift_test.TestNothing},
+	{"thrift_test.TestWriteSimpleJSONProtocolBool", thrift_test.TestWriteSimpleJSONProtocolBool},
+	{"thrift_test.TestReadSimpleJSONProtocolBool", thrift_test.TestReadSimpleJSONProtocolBool},
+	{"thrift_test.TestWriteSimpleJSONProtocolByte", thrift_test.TestWriteSimpleJSONProtocolByte},
+	{"thrift_test.TestReadSimpleJSONProtocolByte", thrift_test.TestReadSimpleJSONProtocolByte},
+	{"thrift_test.TestWriteSimpleJSONProtocolI16", thrift_test.TestWriteSimpleJSONProtocolI16},
+	{"thrift_test.TestReadSimpleJSONProtocolI16", thrift_test.TestReadSimpleJSONProtocolI16},
+	{"thrift_test.TestWriteSimpleJSONProtocolI32", thrift_test.TestWriteSimpleJSONProtocolI32},
+	{"thrift_test.TestReadSimpleJSONProtocolI32", thrift_test.TestReadSimpleJSONProtocolI32},
+	{"thrift_test.TestWriteSimpleJSONProtocolI64", thrift_test.TestWriteSimpleJSONProtocolI64},
+	{"thrift_test.TestReadSimpleJSONProtocolI64", thrift_test.TestReadSimpleJSONProtocolI64},
+	{"thrift_test.TestWriteSimpleJSONProtocolDouble", thrift_test.TestWriteSimpleJSONProtocolDouble},
+	{"thrift_test.TestReadSimpleJSONProtocolDouble", thrift_test.TestReadSimpleJSONProtocolDouble},
+	{"thrift_test.TestWriteSimpleJSONProtocolString", thrift_test.TestWriteSimpleJSONProtocolString},
+	{"thrift_test.TestReadSimpleJSONProtocolString", thrift_test.TestReadSimpleJSONProtocolString},
+	{"thrift_test.TestWriteSimpleJSONProtocolBinary", thrift_test.TestWriteSimpleJSONProtocolBinary},
+	{"thrift_test.TestReadSimpleJSONProtocolBinary", thrift_test.TestReadSimpleJSONProtocolBinary},
+	{"thrift_test.TestWriteSimpleJSONProtocolList", thrift_test.TestWriteSimpleJSONProtocolList},
+	{"thrift_test.TestWriteSimpleJSONProtocolSet", thrift_test.TestWriteSimpleJSONProtocolSet},
+	{"thrift_test.TestWriteSimpleJSONProtocolMap", thrift_test.TestWriteSimpleJSONProtocolMap},
+	{"thrift_test.TestReadWriteSimpleJSONStruct", thrift_test.TestReadWriteSimpleJSONStruct},
+	{"thrift_test.TestReadWriteSimpleJSONProtocol", thrift_test.TestReadWriteSimpleJSONProtocol},
+}
+var benchmarks = []testing.InternalBenchmark{ //
+}
+
+func main() {
+	testing.Main(__regexp__.MatchString, tests)
+	testing.RunBenchmarks(__regexp__.MatchString, benchmarks)
+}
diff --git a/lib/go/thrift/tapplication_exception.go b/lib/go/thrift/tapplication_exception.go
new file mode 100644
index 0000000..fc8bf2e
--- /dev/null
+++ b/lib/go/thrift/tapplication_exception.go
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "os"
+)
+
+const (
+  UNKNOWN_APPLICATION_EXCEPTION  = 0
+  UNKNOWN_METHOD                 = 1
+  INVALID_MESSAGE_TYPE_EXCEPTION = 2
+  WRONG_METHOD_NAME              = 3
+  BAD_SEQUENCE_ID                = 4
+  MISSING_RESULT                 = 5
+  INTERNAL_ERROR                 = 6
+  PROTOCOL_ERROR                 = 7
+)
+
+
+/**
+ * Application level exception
+ *
+ */
+type TApplicationException interface {
+  TException
+  TypeId() int32
+  Read(iprot TProtocol) (TApplicationException, os.Error)
+  Write(oprot TProtocol) os.Error
+}
+
+type tApplicationException struct {
+  TException
+  type_ int32
+}
+
+func NewTApplicationExceptionDefault() TApplicationException {
+  return NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "UNKNOWN")
+}
+
+func NewTApplicationExceptionType(type_ int32) TApplicationException {
+  return NewTApplicationException(type_, "UNKNOWN")
+}
+
+func NewTApplicationException(type_ int32, message string) TApplicationException {
+  return &tApplicationException{TException: NewTException(message), type_: type_}
+}
+
+func NewTApplicationExceptionMessage(message string) TApplicationException {
+  return NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, message)
+}
+
+func (p *tApplicationException) TypeId() int32 {
+  return p.type_
+}
+
+func (p *tApplicationException) Read(iprot TProtocol) (error TApplicationException, err os.Error) {
+  _, err = iprot.ReadStructBegin()
+  if err != nil {
+    return
+  }
+
+  message := ""
+  type_ := int32(UNKNOWN_APPLICATION_EXCEPTION)
+
+  for {
+    _, ttype, id, err := iprot.ReadFieldBegin()
+    if err != nil {
+      return
+    }
+    if ttype == STOP {
+      break
+    }
+    switch id {
+    case 1:
+      if ttype == STRING {
+        message, err = iprot.ReadString()
+        if err != nil {
+          return
+        }
+      } else {
+        err = SkipDefaultDepth(iprot, ttype)
+        if err != nil {
+          return
+        }
+      }
+      break
+    case 2:
+      if ttype == I32 {
+        type_, err = iprot.ReadI32()
+        if err != nil {
+          return
+        }
+      } else {
+        err = SkipDefaultDepth(iprot, ttype)
+        if err != nil {
+          return
+        }
+      }
+      break
+    default:
+      err = SkipDefaultDepth(iprot, ttype)
+      if err != nil {
+        return
+      }
+      break
+    }
+    err = iprot.ReadFieldEnd()
+    if err != nil {
+      return
+    }
+  }
+  err = iprot.ReadStructEnd()
+  error = NewTApplicationException(type_, message)
+  return
+}
+
+func (p *tApplicationException) Write(oprot TProtocol) (err os.Error) {
+  err = oprot.WriteStructBegin("TApplicationException")
+  if len(p.String()) > 0 {
+    err = oprot.WriteFieldBegin("message", STRING, 1)
+    if err != nil {
+      return
+    }
+    err = oprot.WriteString(p.String())
+    if err != nil {
+      return
+    }
+    err = oprot.WriteFieldEnd()
+    if err != nil {
+      return
+    }
+  }
+  err = oprot.WriteFieldBegin("type", I32, 2)
+  if err != nil {
+    return
+  }
+  err = oprot.WriteI32(p.type_)
+  if err != nil {
+    return
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return
+  }
+  err = oprot.WriteFieldStop()
+  if err != nil {
+    return
+  }
+  err = oprot.WriteStructEnd()
+  return
+}
diff --git a/lib/go/thrift/tapplication_exception_test.go b/lib/go/thrift/tapplication_exception_test.go
new file mode 100644
index 0000000..d9572f4
--- /dev/null
+++ b/lib/go/thrift/tapplication_exception_test.go
@@ -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.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+)
+
+func TestTApplicationException(t *testing.T) {
+  exc := NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "")
+  if exc.String() != "" {
+    t.Fatalf("Expected empty string for exception but found '%s'", exc.String())
+  }
+  if exc.TypeId() != UNKNOWN_APPLICATION_EXCEPTION {
+    t.Fatalf("Expected type UNKNOWN for exception but found '%s'", exc.TypeId())
+  }
+  exc = NewTApplicationException(WRONG_METHOD_NAME, "junk_method")
+  if exc.String() != "junk_method" {
+    t.Fatalf("Expected 'junk_method' for exception but found '%s'", exc.String())
+  }
+  if exc.TypeId() != WRONG_METHOD_NAME {
+    t.Fatalf("Expected type WRONG_METHOD_NAME for exception but found '%s'", exc.TypeId())
+  }
+}
diff --git a/lib/go/thrift/tbase.go b/lib/go/thrift/tbase.go
new file mode 100644
index 0000000..adc52d0
--- /dev/null
+++ b/lib/go/thrift/tbase.go
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * Generic base interface for generated Thrift objects.
+ *
+ */
+type TBase interface {
+
+  /**
+   * Reads the TObject from the given input protocol
+   *
+   * @param iprot Input protocol
+   */
+  Read(iprot TProtocol) (err TException)
+
+  /**
+   * Writes the objects out to the protocol
+   *
+   * @param oprot Output protocol
+   */
+  Write(oprot TProtocol) (err TException)
+
+  /**
+   * Check if a field is currently set or unset.
+   *
+   * @param field
+   */
+  IsSet(field TField) bool
+
+  /**
+   * Get a field's value by field variable. Primitive types will be wrapped in 
+   * the appropriate "boxed" types.
+   *
+   * @param field
+   */
+  FieldValue(field TField) interface{}
+
+  /**
+   * Set a field's value by field variable. Primitive types must be "boxed" in
+   * the appropriate object wrapper type.
+   *
+   * @param field
+   */
+  SetFieldValue(field TField, value interface{})
+
+  DeepCopy() TBase
+}
diff --git a/lib/go/thrift/tbinary_protocol.go b/lib/go/thrift/tbinary_protocol.go
new file mode 100644
index 0000000..1c88da6
--- /dev/null
+++ b/lib/go/thrift/tbinary_protocol.go
@@ -0,0 +1,493 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "encoding/binary"
+  "math"
+  "strings"
+  "io"
+)
+
+type TBinaryProtocol struct {
+  //TProtocolBase;
+  trans            TTransport
+  _StrictRead      bool
+  _StrictWrite     bool
+  _ReadLength      int
+  _CheckReadLength bool
+}
+
+type TBinaryProtocolFactory struct {
+  _StrictRead  bool
+  _StrictWrite bool
+}
+
+func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol {
+  return NewTBinaryProtocol(t, false, true)
+}
+
+func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol {
+  //return &TBinaryProtocol{TProtocolBase:TProtocolBase{trans:t}, _StrictRead:strictRead, _StrictWrite:strictWrite, _ReadLength:0, _CheckReadLength:false};
+  return &TBinaryProtocol{trans: t, _StrictRead: strictRead, _StrictWrite: strictWrite, _ReadLength: 0, _CheckReadLength: false}
+}
+
+func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory {
+  return NewTBinaryProtocolFactory(false, true)
+}
+
+func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory {
+  return &TBinaryProtocolFactory{_StrictRead: strictRead, _StrictWrite: strictWrite}
+}
+
+func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol {
+  return NewTBinaryProtocol(t, p._StrictRead, p._StrictWrite)
+}
+
+/**
+ * Writing Methods
+ */
+
+func (p *TBinaryProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) TProtocolException {
+  if p._StrictWrite {
+    version := uint32(VERSION_1) | uint32(typeId)
+    e := p.WriteI32(int32(version))
+    if e != nil {
+      return e
+    }
+    e = p.WriteString(name)
+    if e != nil {
+      return e
+    }
+    e = p.WriteI32(seqId)
+    return e
+  } else {
+    e := p.WriteString(name)
+    if e != nil {
+      return e
+    }
+    e = p.WriteByte(byte(typeId))
+    if e != nil {
+      return e
+    }
+    e = p.WriteI32(seqId)
+    return e
+  }
+  return nil
+}
+
+func (p *TBinaryProtocol) WriteMessageEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) WriteStructBegin(name string) TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) WriteStructEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) WriteFieldBegin(name string, typeId TType, id int16) TProtocolException {
+  e := p.WriteByte(byte(typeId))
+  if e != nil {
+    return e
+  }
+  e = p.WriteI16(id)
+  return e
+}
+
+func (p *TBinaryProtocol) WriteFieldEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) WriteFieldStop() TProtocolException {
+  e := p.WriteByte(STOP)
+  return e
+}
+
+func (p *TBinaryProtocol) WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException {
+  e := p.WriteByte(byte(keyType))
+  if e != nil {
+    return e
+  }
+  e = p.WriteByte(byte(valueType))
+  if e != nil {
+    return e
+  }
+  e = p.WriteI32(int32(size))
+  return e
+}
+
+func (p *TBinaryProtocol) WriteMapEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) WriteListBegin(elemType TType, size int) TProtocolException {
+  e := p.WriteByte(byte(elemType))
+  if e != nil {
+    return e
+  }
+  e = p.WriteI32(int32(size))
+  return e
+}
+
+func (p *TBinaryProtocol) WriteListEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) WriteSetBegin(elemType TType, size int) TProtocolException {
+  e := p.WriteByte(byte(elemType))
+  if e != nil {
+    return e
+  }
+  e = p.WriteI32(int32(size))
+  return e
+}
+
+func (p *TBinaryProtocol) WriteSetEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) WriteBool(value bool) TProtocolException {
+  if value {
+    return p.WriteByte(1)
+  }
+  return p.WriteByte(0)
+}
+
+func (p *TBinaryProtocol) WriteByte(value byte) TProtocolException {
+  v := []byte{value}
+  _, e := p.trans.Write(v)
+  return NewTProtocolExceptionFromOsError(e)
+}
+
+func (p *TBinaryProtocol) WriteI16(value int16) TProtocolException {
+  h := byte(0xff & (value >> 8))
+  l := byte(0xff & value)
+  v := []byte{h, l}
+  _, e := p.trans.Write(v)
+  return NewTProtocolExceptionFromOsError(e)
+}
+
+func (p *TBinaryProtocol) WriteI32(value int32) TProtocolException {
+  a := byte(0xff & (value >> 24))
+  b := byte(0xff & (value >> 16))
+  c := byte(0xff & (value >> 8))
+  d := byte(0xff & value)
+  v := []byte{a, b, c, d}
+  _, e := p.trans.Write(v)
+  return NewTProtocolExceptionFromOsError(e)
+}
+
+func (p *TBinaryProtocol) WriteI64(value int64) TProtocolException {
+  a := byte(0xff & (value >> 56))
+  b := byte(0xff & (value >> 48))
+  c := byte(0xff & (value >> 40))
+  d := byte(0xff & (value >> 32))
+  e := byte(0xff & (value >> 24))
+  f := byte(0xff & (value >> 16))
+  g := byte(0xff & (value >> 8))
+  h := byte(0xff & value)
+  v := []byte{a, b, c, d, e, f, g, h}
+  _, err := p.trans.Write(v)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TBinaryProtocol) WriteDouble(value float64) TProtocolException {
+  return p.WriteI64(int64(math.Float64bits(value)))
+}
+
+func (p *TBinaryProtocol) WriteString(value string) TProtocolException {
+  return p.WriteBinaryFromReader(strings.NewReader(value), len(value))
+}
+
+func (p *TBinaryProtocol) WriteBinary(value []byte) TProtocolException {
+  e := p.WriteI32(int32(len(value)))
+  if e != nil {
+    return e
+  }
+  _, err := p.trans.Write(value)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TBinaryProtocol) WriteBinaryFromReader(reader io.Reader, size int) TProtocolException {
+  e := p.WriteI32(int32(size))
+  if e != nil {
+    return e
+  }
+  _, err := io.Copyn(p.trans, reader, int64(size))
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+
+/**
+ * Reading methods
+ */
+
+func (p *TBinaryProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err TProtocolException) {
+  size, e := p.ReadI32()
+  if e != nil {
+    return "", typeId, 0, NewTProtocolExceptionFromOsError(e)
+  }
+  if size < 0 {
+    typeId = TMessageType(size & 0x0ff)
+    version := int64(int64(size) & VERSION_MASK)
+    if version != VERSION_1 {
+      return name, typeId, seqId, NewTProtocolException(BAD_VERSION, "Bad version in ReadMessageBegin")
+    }
+    name, e = p.ReadString()
+    if e != nil {
+      return name, typeId, seqId, NewTProtocolExceptionFromOsError(e)
+    }
+    seqId, e = p.ReadI32()
+    if e != nil {
+      return name, typeId, seqId, NewTProtocolExceptionFromOsError(e)
+    }
+    return name, typeId, seqId, nil
+  }
+  if p._StrictRead {
+    return name, typeId, seqId, NewTProtocolException(BAD_VERSION, "Missing version in ReadMessageBegin")
+  }
+  name, e2 := p.readStringBody(int(size))
+  if e2 != nil {
+    return name, typeId, seqId, e2
+  }
+  b, e3 := p.ReadByte()
+  if e3 != nil {
+    return name, typeId, seqId, e3
+  }
+  typeId = TMessageType(b)
+  seqId, e4 := p.ReadI32()
+  if e4 != nil {
+    return name, typeId, seqId, e4
+  }
+  return name, typeId, seqId, nil
+}
+
+func (p *TBinaryProtocol) ReadMessageEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) ReadStructBegin() (name string, err TProtocolException) {
+  return
+}
+
+func (p *TBinaryProtocol) ReadStructEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) ReadFieldBegin() (name string, typeId TType, seqId int16, err TProtocolException) {
+  t, err := p.ReadByte()
+  typeId = TType(t)
+  if err != nil {
+    return name, typeId, seqId, err
+  }
+  if t != STOP {
+    seqId, err = p.ReadI16()
+  }
+  return name, typeId, seqId, err
+}
+
+func (p *TBinaryProtocol) ReadFieldEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err TProtocolException) {
+  k, e := p.ReadByte()
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  kType = TType(k)
+  v, e := p.ReadByte()
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  vType = TType(v)
+  size32, e := p.ReadI32()
+  size = int(size32)
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  return kType, vType, size, nil
+}
+
+func (p *TBinaryProtocol) ReadMapEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err TProtocolException) {
+  b, e := p.ReadByte()
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  elemType = TType(b)
+  size32, e := p.ReadI32()
+  size = int(size32)
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  return elemType, size, nil
+}
+
+func (p *TBinaryProtocol) ReadListEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err TProtocolException) {
+  b, e := p.ReadByte()
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  elemType = TType(b)
+  size32, e := p.ReadI32()
+  size = int(size32)
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  return elemType, size, nil
+}
+
+func (p *TBinaryProtocol) ReadSetEnd() TProtocolException {
+  return nil
+}
+
+func (p *TBinaryProtocol) ReadBool() (bool, TProtocolException) {
+  b, e := p.ReadByte()
+  v := true
+  if b != 1 {
+    v = false
+  }
+  return v, e
+}
+
+func (p *TBinaryProtocol) ReadByte() (value byte, err TProtocolException) {
+  buf := []byte{0}
+  err = p.readAll(buf)
+  return buf[0], err
+}
+
+func (p *TBinaryProtocol) ReadI16() (value int16, err TProtocolException) {
+  buf := []byte{0, 0}
+  err = p.readAll(buf)
+  value = int16(binary.BigEndian.Uint16(buf))
+  return value, err
+}
+
+func (p *TBinaryProtocol) ReadI32() (value int32, err TProtocolException) {
+  buf := []byte{0, 0, 0, 0}
+  err = p.readAll(buf)
+  value = int32(binary.BigEndian.Uint32(buf))
+  return value, err
+}
+
+func (p *TBinaryProtocol) ReadI64() (value int64, err TProtocolException) {
+  buf := []byte{0, 0, 0, 0, 0, 0, 0, 0}
+  err = p.readAll(buf)
+  value = int64(binary.BigEndian.Uint64(buf))
+  return value, err
+}
+
+func (p *TBinaryProtocol) ReadDouble() (value float64, err TProtocolException) {
+  buf := []byte{0, 0, 0, 0, 0, 0, 0, 0}
+  err = p.readAll(buf)
+  value = math.Float64frombits(binary.BigEndian.Uint64(buf))
+  return value, err
+}
+
+func (p *TBinaryProtocol) ReadString() (value string, err TProtocolException) {
+  size, e := p.ReadI32()
+  if e != nil {
+    return "", e
+  }
+  return p.readStringBody(int(size))
+}
+
+func (p *TBinaryProtocol) ReadBinary() ([]byte, TProtocolException) {
+  size, e := p.ReadI32()
+  if e != nil {
+    return nil, e
+  }
+  isize := int(size)
+  e = p.checkReadLength(isize)
+  if e != nil {
+    return nil, e
+  }
+  buf := make([]byte, isize)
+  _, err := p.trans.ReadAll(buf)
+  return buf, NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TBinaryProtocol) Flush() (err TProtocolException) {
+  return NewTProtocolExceptionFromOsError(p.trans.Flush())
+}
+
+func (p *TBinaryProtocol) Skip(fieldType TType) (err TProtocolException) {
+  return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TBinaryProtocol) Transport() TTransport {
+  return p.trans
+}
+
+func (p *TBinaryProtocol) readAll(buf []byte) TProtocolException {
+  e := p.checkReadLength(len(buf))
+  if e != nil {
+    return e
+  }
+  _, err := p.trans.ReadAll(buf)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TBinaryProtocol) setReadLength(readLength int) {
+  p._ReadLength = readLength
+  p._CheckReadLength = true
+}
+
+func (p *TBinaryProtocol) checkReadLength(length int) TProtocolException {
+  if p._CheckReadLength {
+    p._ReadLength = p._ReadLength - length
+    if p._ReadLength < 0 {
+      return NewTProtocolException(UNKNOWN_PROTOCOL_EXCEPTION, "Message length exceeded: "+string(length))
+    }
+  }
+  return nil
+}
+
+func (p *TBinaryProtocol) readStringBody(size int) (value string, err TProtocolException) {
+  if size < 0 {
+    return "", nil
+  }
+  err = p.checkReadLength(size)
+  if err != nil {
+    return "", err
+  }
+  isize := int(size)
+  buf := make([]byte, isize)
+  _, e := p.trans.ReadAll(buf)
+  return string(buf), NewTProtocolExceptionFromOsError(e)
+}
diff --git a/lib/go/thrift/tbinary_protocol_test.go b/lib/go/thrift/tbinary_protocol_test.go
new file mode 100644
index 0000000..b21b248
--- /dev/null
+++ b/lib/go/thrift/tbinary_protocol_test.go
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+  //"bytes";
+)
+
+
+func TestReadWriteBinaryProtocol(t *testing.T) {
+  ReadWriteProtocolTest(t, NewTBinaryProtocolFactoryDefault())
+}
diff --git a/lib/go/thrift/tcompact_protocol.go b/lib/go/thrift/tcompact_protocol.go
new file mode 100644
index 0000000..9b780f7
--- /dev/null
+++ b/lib/go/thrift/tcompact_protocol.go
@@ -0,0 +1,856 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "container/vector"
+  "encoding/binary"
+  "fmt"
+  "math"
+  "os"
+  "strings"
+)
+
+const (
+  COMPACT_PROTOCOL_ID       = 0x082
+  COMPACT_VERSION           = 1
+  COMPACT_VERSION_MASK      = 0x1f
+  COMPACT_TYPE_MASK         = 0x0E0
+  COMPACT_TYPE_SHIFT_AMOUNT = 5
+)
+
+type TCompactType byte
+
+const (
+  COMPACT_BOOLEAN_TRUE  = 0x01
+  COMPACT_BOOLEAN_FALSE = 0x02
+  COMPACT_BYTE          = 0x03
+  COMPACT_I16           = 0x04
+  COMPACT_I32           = 0x05
+  COMPACT_I64           = 0x06
+  COMPACT_DOUBLE        = 0x07
+  COMPACT_BINARY        = 0x08
+  COMPACT_LIST          = 0x09
+  COMPACT_SET           = 0x0A
+  COMPACT_MAP           = 0x0B
+  COMPACT_STRUCT        = 0x0C
+)
+
+var (
+  _TTypeToCompactType []TCompactType
+  _TSTOP              TField
+)
+
+func init() {
+  _TSTOP = NewTField("", STOP, 0)
+  _TTypeToCompactType = make([]TCompactType, int(UTF16)+1)
+  _TTypeToCompactType[int(STOP)] = STOP
+  _TTypeToCompactType[int(BOOL)] = COMPACT_BOOLEAN_TRUE
+  _TTypeToCompactType[int(BYTE)] = COMPACT_BYTE
+  _TTypeToCompactType[int(I16)] = COMPACT_I16
+  _TTypeToCompactType[int(I32)] = COMPACT_I32
+  _TTypeToCompactType[int(I64)] = COMPACT_I64
+  _TTypeToCompactType[int(DOUBLE)] = COMPACT_DOUBLE
+  _TTypeToCompactType[int(STRING)] = COMPACT_BINARY
+  _TTypeToCompactType[int(LIST)] = COMPACT_LIST
+  _TTypeToCompactType[int(SET)] = COMPACT_SET
+  _TTypeToCompactType[int(MAP)] = COMPACT_MAP
+  _TTypeToCompactType[int(STRUCT)] = COMPACT_STRUCT
+}
+
+type TCompactProtocolFactory struct{}
+
+func NewTCompactProtocolFactory() *TCompactProtocolFactory {
+  return &TCompactProtocolFactory{}
+}
+
+func (p *TCompactProtocolFactory) GetProtocol(trans TTransport) TProtocol {
+  return NewTCompactProtocol(trans)
+}
+
+type TCompactProtocol struct {
+  trans TTransport
+
+  /** 
+   * Used to keep track of the last field for the current and previous structs,
+   * so we can do the delta stuff.
+   */
+  lastField   *vector.IntVector
+  lastFieldId int
+
+  /** 
+   * If we encounter a boolean field begin, save the TField here so it can 
+   * have the value incorporated.
+   */
+  booleanField TField
+
+  /**
+   * If we read a field header, and it's a boolean field, save the boolean 
+   * value here so that readBool can use it.
+   */
+  boolValue          bool
+  boolValueIsNotNull bool
+}
+
+/**
+ * Create a TCompactProtocol.
+ *
+ * @param transport the TTransport object to read from or write to.
+ */
+func NewTCompactProtocol(trans TTransport) *TCompactProtocol {
+  return &TCompactProtocol{trans: trans, lastField: &vector.IntVector{}}
+}
+
+
+//
+// Public Writing methods.
+//
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) WriteMessageBegin(name string, typeId TMessageType, seqid int32) TProtocolException {
+  _, err := p.writeByteDirect(COMPACT_PROTOCOL_ID)
+  if err != nil {
+    return NewTProtocolExceptionFromOsError(err)
+  }
+  _, err = p.writeByteDirect((COMPACT_VERSION & COMPACT_VERSION_MASK) | ((byte(typeId) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK))
+  if err != nil {
+    return NewTProtocolExceptionFromOsError(err)
+  }
+  _, err = p.writeVarint32(seqid)
+  if err != nil {
+    return NewTProtocolExceptionFromOsError(err)
+  }
+  e := p.WriteString(name)
+  return e
+
+}
+
+func (p *TCompactProtocol) WriteMessageEnd() TProtocolException { return nil }
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) WriteStructBegin(name string) TProtocolException {
+  p.lastField.Push(p.lastFieldId)
+  p.lastFieldId = 0
+  return nil
+}
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) WriteStructEnd() TProtocolException {
+  p.lastFieldId = p.lastField.Pop()
+  return nil
+}
+
+func (p *TCompactProtocol) WriteFieldBegin(name string, typeId TType, id int16) TProtocolException {
+  if typeId == BOOL {
+    // we want to possibly include the value, so we'll wait.
+    p.booleanField = NewTField(name, typeId, int(id))
+    return nil
+  }
+  _, err := p.writeFieldBeginInternal(name, typeId, id, 0xFF)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) writeFieldBeginInternal(name string, typeId TType, id int16, typeOverride byte) (int, os.Error) {
+  // short lastField = lastField_.pop();
+
+  // if there's a type override, use that.
+  var typeToWrite byte
+  if typeOverride == 0xFF {
+    typeToWrite = byte(p.getCompactType(typeId))
+  } else {
+    typeToWrite = typeOverride
+  }
+  // check if we can use delta encoding for the field id
+  fieldId := int(id)
+  written := 0
+  if fieldId > p.lastFieldId && fieldId-p.lastFieldId <= 15 {
+    // write them together
+    written, err := p.writeByteDirect(byte((fieldId-p.lastFieldId)<<4) | typeToWrite)
+    if err != nil {
+      return written, err
+    }
+  } else {
+    // write them separate
+    n, err := p.writeByteDirect(typeToWrite)
+    if err != nil {
+      return n, err
+    }
+    err = p.WriteI16(id)
+    written = n + 2
+    if err != nil {
+      return written, err
+    }
+  }
+
+  p.lastFieldId = fieldId
+  // p.lastField.Push(field.id);
+  return written, nil
+}
+
+
+func (p *TCompactProtocol) WriteFieldEnd() TProtocolException { return nil }
+
+func (p *TCompactProtocol) WriteFieldStop() TProtocolException {
+  _, err := p.writeByteDirect(STOP)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TCompactProtocol) WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException {
+  if size == 0 {
+    _, err := p.writeByteDirect(0)
+    return NewTProtocolExceptionFromOsError(err)
+  }
+  _, err := p.writeVarint32(int32(size))
+  if err != nil {
+    return NewTProtocolExceptionFromOsError(err)
+  }
+  _, err = p.writeByteDirect(byte(p.getCompactType(keyType))<<4 | byte(p.getCompactType(valueType)))
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TCompactProtocol) WriteMapEnd() TProtocolException { return nil }
+
+/**
+ * Write a list header.
+ */
+func (p *TCompactProtocol) WriteListBegin(elemType TType, size int) TProtocolException {
+  _, err := p.writeCollectionBegin(elemType, size)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TCompactProtocol) WriteListEnd() TProtocolException { return nil }
+
+/**
+ * Write a set header.
+ */
+func (p *TCompactProtocol) WriteSetBegin(elemType TType, size int) TProtocolException {
+  _, err := p.writeCollectionBegin(elemType, size)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TCompactProtocol) WriteSetEnd() TProtocolException { return nil }
+
+func (p *TCompactProtocol) WriteBool(value bool) TProtocolException {
+  v := byte(COMPACT_BOOLEAN_FALSE)
+  if value {
+    v = byte(COMPACT_BOOLEAN_TRUE)
+  }
+  if p.booleanField != nil {
+    // we haven't written the field header yet
+    _, err := p.writeFieldBeginInternal(p.booleanField.Name(), p.booleanField.TypeId(), int16(p.booleanField.Id()), v)
+    p.booleanField = nil
+    return NewTProtocolExceptionFromOsError(err)
+  }
+  // we're not part of a field, so just write the value.
+  _, err := p.writeByteDirect(v)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+/** 
+ * Write a byte. Nothing to see here!
+ */
+func (p *TCompactProtocol) WriteByte(value byte) TProtocolException {
+  _, err := p.writeByteDirect(value)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+/**
+ * Write an I16 as a zigzag varint.
+ */
+func (p *TCompactProtocol) WriteI16(value int16) TProtocolException {
+  _, err := p.writeVarint32(p.int32ToZigzag(int32(value)))
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+/**
+ * Write an i32 as a zigzag varint.
+ */
+func (p *TCompactProtocol) WriteI32(value int32) TProtocolException {
+  _, err := p.writeVarint32(p.int32ToZigzag(value))
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+/**
+ * Write an i64 as a zigzag varint.
+ */
+func (p *TCompactProtocol) WriteI64(value int64) TProtocolException {
+  _, err := p.writeVarint64(p.int64ToZigzag(value))
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+/**
+ * Write a double to the wire as 8 bytes.
+ */
+func (p *TCompactProtocol) WriteDouble(value float64) TProtocolException {
+  buf := make([]byte, 8)
+  binary.LittleEndian.PutUint64(buf, math.Float64bits(value))
+  _, err := p.trans.Write(buf)
+  return NewTProtocolExceptionFromOsError(err)
+}
+
+/**
+ * Write a string to the wire with a varint size preceeding.
+ */
+func (p *TCompactProtocol) WriteString(value string) TProtocolException {
+  buf := make([]byte, len(value))
+  strings.NewReader(value).Read(buf)
+  return p.WriteBinary(buf)
+}
+
+/**
+ * Write a byte array, using a varint for the size. 
+ */
+func (p *TCompactProtocol) WriteBinary(bin []byte) TProtocolException {
+  _, e := p.writeVarint32(int32(len(bin)))
+  if e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  if len(bin) > 0 {
+    _, e = p.trans.Write(bin)
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  return nil
+}
+
+
+// 
+// Reading methods.
+// 
+
+/**
+ * Read a message header. 
+ */
+func (p *TCompactProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err TProtocolException) {
+  protocolId, err := p.ReadByte()
+  if protocolId != COMPACT_PROTOCOL_ID {
+    s := fmt.Sprintf("Expected protocol id %02x but got %02x", COMPACT_PROTOCOL_ID, protocolId)
+    return "", typeId, seqId, NewTProtocolException(BAD_VERSION, s)
+  }
+  versionAndType, err := p.ReadByte()
+  version := versionAndType & COMPACT_VERSION_MASK
+  typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & 0x03)
+  if err != nil {
+    return
+  }
+  if version != COMPACT_VERSION {
+    s := fmt.Sprintf("Expected version %02x but got %02x", COMPACT_VERSION, version)
+    err = NewTProtocolException(BAD_VERSION, s)
+    return
+  }
+  seqId, e := p.readVarint32()
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  name, err = p.ReadString()
+  return
+}
+
+func (p *TCompactProtocol) ReadMessageEnd() TProtocolException { return nil }
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) ReadStructBegin() (name string, err TProtocolException) {
+  p.lastField.Push(p.lastFieldId)
+  p.lastFieldId = 0
+  return
+}
+
+/**
+ * Doesn't actually consume any wire data, just removes the last field for 
+ * this struct from the field stack.
+ */
+func (p *TCompactProtocol) ReadStructEnd() TProtocolException {
+  // consume the last field we read off the wire.
+  p.lastFieldId = p.lastField.Pop()
+  return nil
+}
+
+/**
+ * Read a field header off the wire. 
+ */
+func (p *TCompactProtocol) ReadFieldBegin() (name string, typeId TType, id int16, err TProtocolException) {
+  t, err := p.ReadByte()
+  if err != nil {
+    return
+  }
+
+  // if it's a stop, then we can return immediately, as the struct is over.
+  if (t & 0x0f) == STOP {
+    return _TSTOP.Name(), _TSTOP.TypeId(), int16(_TSTOP.Id()), nil
+  }
+
+  // mask off the 4 MSB of the type header. it could contain a field id delta.
+  modifier := int16((t & 0xf0) >> 4)
+  if modifier == 0 {
+    // not a delta. look ahead for the zigzag varint field id.
+    id, err = p.ReadI16()
+    if err != nil {
+      return
+    }
+  } else {
+    // has a delta. add the delta to the last read field id.
+    id = int16(p.lastFieldId) + modifier
+  }
+  typeId, e := p.getTType(TCompactType(t & 0x0f))
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+
+  // if this happens to be a boolean field, the value is encoded in the type
+  if p.isBoolType(t) {
+    // save the boolean value in a special instance variable.
+    p.boolValue = (byte(t)&0x0f == COMPACT_BOOLEAN_TRUE)
+    p.boolValueIsNotNull = true
+  }
+
+  // push the new field onto the field stack so we can keep the deltas going.
+  p.lastFieldId = int(id)
+  return
+}
+
+func (p *TCompactProtocol) ReadFieldEnd() TProtocolException { return nil }
+
+/** 
+ * 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.
+ */
+func (p *TCompactProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, err TProtocolException) {
+  size32, e := p.readVarint32()
+  size = int(size32)
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  keyAndValueType := byte(STOP)
+  if size != 0 {
+    keyAndValueType, err = p.ReadByte()
+    if err != nil {
+      return
+    }
+  }
+  keyType, _ = p.getTType(TCompactType(keyAndValueType >> 4))
+  valueType, _ = p.getTType(TCompactType(keyAndValueType & 0xf))
+  return
+}
+
+func (p *TCompactProtocol) ReadMapEnd() TProtocolException { return nil }
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) ReadListBegin() (elemType TType, size int, err TProtocolException) {
+  size_and_type, err := p.ReadByte()
+  if err != nil {
+    return
+  }
+  size = int((size_and_type >> 4) & 0x0f)
+  if size == 15 {
+    size2, e := p.readVarint32()
+    if e != nil {
+      err = NewTProtocolExceptionFromOsError(e)
+      return
+    }
+    size = int(size2)
+  }
+  elemType, e := p.getTType(TCompactType(size_and_type))
+  if e != nil {
+    err = NewTProtocolExceptionFromOsError(e)
+    return
+  }
+  return
+}
+
+func (p *TCompactProtocol) ReadListEnd() TProtocolException { return nil }
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) ReadSetBegin() (elemType TType, size int, err TProtocolException) {
+  return p.ReadListBegin()
+}
+
+func (p *TCompactProtocol) ReadSetEnd() TProtocolException { return nil }
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) ReadBool() (value bool, err TProtocolException) {
+  if p.boolValueIsNotNull {
+    p.boolValueIsNotNull = false
+    return p.boolValue, nil
+  }
+  v, err := p.ReadByte()
+  return v == COMPACT_BOOLEAN_TRUE, err
+}
+
+/**
+ * Read a single byte off the wire. Nothing interesting here.
+ */
+func (p *TCompactProtocol) ReadByte() (value byte, err TProtocolException) {
+  buf := []byte{0}
+  _, e := p.trans.ReadAll(buf)
+  if e != nil {
+    return 0, NewTProtocolExceptionFromOsError(e)
+  }
+  return buf[0], nil
+}
+
+/**
+ * Read an i16 from the wire as a zigzag varint.
+ */
+func (p *TCompactProtocol) ReadI16() (value int16, err TProtocolException) {
+  v, err := p.ReadI32()
+  return int16(v), err
+}
+
+/**
+ * Read an i32 from the wire as a zigzag varint.
+ */
+func (p *TCompactProtocol) ReadI32() (value int32, err TProtocolException) {
+  v, e := p.readVarint32()
+  if e != nil {
+    return 0, NewTProtocolExceptionFromOsError(e)
+  }
+  value = p.zigzagToInt32(v)
+  return value, nil
+}
+
+/**
+ * Read an i64 from the wire as a zigzag varint.
+ */
+func (p *TCompactProtocol) ReadI64() (value int64, err TProtocolException) {
+  v, e := p.readVarint64()
+  if e != nil {
+    return 0, NewTProtocolExceptionFromOsError(e)
+  }
+  value = p.zigzagToInt64(v)
+  return value, nil
+}
+
+/**
+ * No magic here - just read a double off the wire.
+ */
+func (p *TCompactProtocol) ReadDouble() (value float64, err TProtocolException) {
+  longBits := make([]byte, 8)
+  _, e := p.trans.ReadAll(longBits)
+  if e != nil {
+    return 0.0, NewTProtocolExceptionFromOsError(e)
+  }
+  return math.Float64frombits(p.bytesToUint64(longBits)), nil
+}
+
+/**
+ * Reads a []byte (via readBinary), and then UTF-8 decodes it.
+ */
+func (p *TCompactProtocol) ReadString() (value string, err TProtocolException) {
+  v, e := p.ReadBinary()
+  return string(v), NewTProtocolExceptionFromOsError(e)
+}
+
+/**
+ * Read a []byte from the wire. 
+ */
+func (p *TCompactProtocol) ReadBinary() (value []byte, err TProtocolException) {
+  length, e := p.readVarint32()
+  if e != nil {
+    return []byte{}, NewTProtocolExceptionFromOsError(e)
+  }
+  if length == 0 {
+    return []byte{}, nil
+  }
+
+  buf := make([]byte, length)
+  p.trans.ReadAll(buf)
+  return buf, nil
+}
+
+func (p *TCompactProtocol) Flush() (err TProtocolException) {
+  return NewTProtocolExceptionFromOsError(p.trans.Flush())
+}
+
+func (p *TCompactProtocol) Skip(fieldType TType) (err TProtocolException) {
+  return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TCompactProtocol) Transport() TTransport {
+  return p.trans
+}
+
+//
+// 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.
+ */
+func (p *TCompactProtocol) writeCollectionBegin(elemType TType, size int) (int, os.Error) {
+  if size <= 14 {
+    return p.writeByteDirect(byte(int32(size<<4) | int32(p.getCompactType(elemType))))
+  }
+  n, err := p.writeByteDirect(0xf0 | byte(p.getCompactType(elemType)))
+  if err != nil {
+    return n, err
+  }
+  m, err := p.writeVarint32(int32(size))
+  return n + m, err
+}
+
+/**
+ * Write an i32 as a varint. Results in 1-5 bytes on the wire.
+ * TODO(pomack): make a permanent buffer like writeVarint64?
+ */
+func (p *TCompactProtocol) writeVarint32(n int32) (int, os.Error) {
+  i32buf := make([]byte, 5)
+  idx := 0
+  for {
+    if (n & ^0x7F) == 0 {
+      i32buf[idx] = byte(n)
+      idx++
+      // p.writeByteDirect(byte(n));
+      break
+      // return;
+    } else {
+      i32buf[idx] = byte((n & 0x7F) | 0x80)
+      idx++
+      // p.writeByteDirect(byte(((n & 0x7F) | 0x80)));
+      u := uint32(n)
+      n = int32(u >> 7)
+    }
+  }
+  return p.trans.Write(i32buf[0:idx])
+}
+
+/**
+ * Write an i64 as a varint. Results in 1-10 bytes on the wire.
+ */
+func (p *TCompactProtocol) writeVarint64(n int64) (int, os.Error) {
+  varint64out := make([]byte, 10)
+  idx := 0
+  for {
+    if (n & ^0x7F) == 0 {
+      varint64out[idx] = byte(n)
+      idx++
+      break
+    } else {
+      varint64out[idx] = byte((n & 0x7F) | 0x80)
+      idx++
+      u := uint64(n)
+      n = int64(u >> 7)
+    }
+  }
+  return p.trans.Write(varint64out[0:idx])
+}
+
+/**
+ * Convert l into a zigzag long. This allows negative numbers to be 
+ * represented compactly as a varint.
+ */
+func (p *TCompactProtocol) int64ToZigzag(l int64) int64 {
+  return (l << 1) ^ (l >> 63)
+}
+
+/**
+ * Convert l into a zigzag long. This allows negative numbers to be 
+ * represented compactly as a varint.
+ */
+func (p *TCompactProtocol) int32ToZigzag(n int32) int32 {
+  return (n << 1) ^ (n >> 31)
+}
+
+func (p *TCompactProtocol) fixedUint64ToBytes(n uint64, buf []byte) {
+  binary.LittleEndian.PutUint64(buf, n)
+}
+
+func (p *TCompactProtocol) fixedInt64ToBytes(n int64, buf []byte) {
+  binary.LittleEndian.PutUint64(buf, uint64(n))
+}
+
+/** 
+ * Writes a byte without any possiblity of all that field header nonsense. 
+ * Used internally by other writing methods that know they need to write a byte.
+ */
+func (p *TCompactProtocol) writeByteDirect(b byte) (int, os.Error) {
+  return p.trans.Write([]byte{b})
+}
+
+/** 
+ * Writes a byte without any possiblity of all that field header nonsense.
+ */
+func (p *TCompactProtocol) writeIntAsByteDirect(n int) (int, os.Error) {
+  return p.writeByteDirect(byte(n))
+}
+
+
+//
+// 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.
+ */
+func (p *TCompactProtocol) readVarint32() (int32, os.Error) {
+  // if the wire contains the right stuff, this will just truncate the i64 we
+  // read and get us the right sign.
+  v, err := p.readVarint64()
+  return int32(v), err
+}
+
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) readVarint64() (int64, os.Error) {
+  shift := uint(0)
+  result := int64(0)
+  for {
+    b, err := p.ReadByte()
+    if err != nil {
+      return 0, err
+    }
+    result |= int64(b&0x7f) << shift
+    if (b & 0x80) != 0x80 {
+      break
+    }
+    shift += 7
+  }
+  return result, nil
+}
+
+
+//
+// encoding helpers
+//
+
+/**
+ * Convert from zigzag int to int.
+ */
+func (p *TCompactProtocol) zigzagToInt32(n int32) int32 {
+  u := uint32(n)
+  return int32(u>>1) ^ -(n & 1)
+}
+
+/** 
+ * Convert from zigzag long to long.
+ */
+func (p *TCompactProtocol) zigzagToInt64(n int64) int64 {
+  u := uint64(n)
+  return int64(u>>1) ^ -(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.
+ */
+func (p *TCompactProtocol) bytesToInt64(b []byte) int64 {
+  return int64(binary.LittleEndian.Uint64(b))
+}
+
+/**
+ * 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.
+ */
+func (p *TCompactProtocol) bytesToUint64(b []byte) uint64 {
+  return binary.LittleEndian.Uint64(b)
+}
+
+//
+// type testing and converting
+//
+
+func (p *TCompactProtocol) isBoolType(b byte) bool {
+  return (b&0x0f) == COMPACT_BOOLEAN_TRUE || (b&0x0f) == COMPACT_BOOLEAN_FALSE
+}
+
+/**
+ * Given a TCompactType constant, convert it to its corresponding 
+ * TType value.
+ */
+func (p *TCompactProtocol) getTType(t TCompactType) (TType, os.Error) {
+  switch byte(t) & 0x0f {
+  case STOP:
+    return STOP, nil
+  case COMPACT_BOOLEAN_FALSE:
+  case COMPACT_BOOLEAN_TRUE:
+    return BOOL, nil
+  case COMPACT_BYTE:
+    return BYTE, nil
+  case COMPACT_I16:
+    return I16, nil
+  case COMPACT_I32:
+    return I32, nil
+  case COMPACT_I64:
+    return I64, nil
+  case COMPACT_DOUBLE:
+    return DOUBLE, nil
+  case COMPACT_BINARY:
+    return STRING, nil
+  case COMPACT_LIST:
+    return LIST, nil
+  case COMPACT_SET:
+    return SET, nil
+  case COMPACT_MAP:
+    return MAP, nil
+  case COMPACT_STRUCT:
+    return STRUCT, nil
+  }
+  return STOP, NewTException("don't know what type: " + string(t&0x0f))
+}
+
+/**
+ * Given a TType value, find the appropriate TCompactProtocol.Types constant.
+ */
+func (p *TCompactProtocol) getCompactType(t TType) TCompactType {
+  return _TTypeToCompactType[int(t)]
+}
diff --git a/lib/go/thrift/tcompact_protocol_test.go b/lib/go/thrift/tcompact_protocol_test.go
new file mode 100644
index 0000000..da0e39c
--- /dev/null
+++ b/lib/go/thrift/tcompact_protocol_test.go
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+  //"bytes";
+)
+
+func TestReadWriteCompactProtocol(t *testing.T) {
+  ReadWriteProtocolTest(t, NewTCompactProtocolFactory())
+  /*
+     transports := []TTransport{
+       NewTMemoryBuffer(), 
+       NewTIOStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 16384))),
+       NewTFramedTransport(NewTMemoryBuffer()),
+     }
+     for _, trans := range transports {
+       p := NewTCompactProtocol(trans);
+       ReadWriteBool(t, p, trans);
+       p = NewTCompactProtocol(trans);
+       ReadWriteByte(t, p, trans);
+       p = NewTCompactProtocol(trans);
+       ReadWriteI16(t, p, trans);
+       p = NewTCompactProtocol(trans);
+       ReadWriteI32(t, p, trans);
+       p = NewTCompactProtocol(trans);
+       ReadWriteI64(t, p, trans);
+       p = NewTCompactProtocol(trans);
+       ReadWriteDouble(t, p, trans);
+       p = NewTCompactProtocol(trans);
+       ReadWriteString(t, p, trans);
+       p = NewTCompactProtocol(trans);
+       ReadWriteBinary(t, p, trans);
+       trans.Close();
+     }
+  */
+}
diff --git a/lib/go/thrift/tcompare.go b/lib/go/thrift/tcompare.go
new file mode 100644
index 0000000..01fef44
--- /dev/null
+++ b/lib/go/thrift/tcompare.go
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package thrift
+
+func CompareInt(i, j int) int {
+  if i > j {
+    return 1
+  }
+  if i < j {
+    return -1
+  }
+  return 0
+}
+
+func CompareInt16(i, j int16) int {
+  if i > j {
+    return 1
+  }
+  if i < j {
+    return -1
+  }
+  return 0
+}
+
+func CompareInt32(i, j int32) int {
+  if i > j {
+    return 1
+  }
+  if i < j {
+    return -1
+  }
+  return 0
+}
+
+func CompareInt64(i, j int32) int {
+  if i > j {
+    return 1
+  }
+  if i < j {
+    return -1
+  }
+  return 0
+}
+
+func CompareStringArray(i, j []string) int {
+  if cmp := CompareInt(len(i), len(j)); cmp != 0 {
+    return cmp
+  }
+  size := len(i)
+  for k := 0; k < size; k++ {
+    if cmp := CompareString(i[k], j[k]); cmp != 0 {
+      return cmp
+    }
+  }
+  return 0
+}
+
+func CompareString(i, j string) int {
+  if i > j {
+    return 1
+  }
+  if i < j {
+    return -1
+  }
+  return 0
+}
+
+func CompareFloat(i, j float32) int {
+  if i > j {
+    return 1
+  }
+  if i < j {
+    return -1
+  }
+  return 0
+}
+
+func CompareDouble(i, j float64) int {
+  if i > j {
+    return 1
+  }
+  if i < j {
+    return -1
+  }
+  return 0
+}
+
+func CompareByte(i, j byte) int {
+  if i > j {
+    return 1
+  }
+  if i < j {
+    return -1
+  }
+  return 0
+}
+
+func CompareBool(i, j bool) int {
+  if i {
+    if j {
+      return 0
+    }
+    return 1
+  }
+  if j {
+    return -1
+  }
+  return 0
+}
diff --git a/lib/go/thrift/tcontainer.go b/lib/go/thrift/tcontainer.go
new file mode 100644
index 0000000..9ea3cba
--- /dev/null
+++ b/lib/go/thrift/tcontainer.go
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package thrift
+
+type TContainer interface {
+  Len() int
+  Contains(data interface{}) bool
+  Equals(other interface{}) bool
+  CompareTo(other interface{}) (int, bool)
+}
diff --git a/lib/go/thrift/texception.go b/lib/go/thrift/texception.go
new file mode 100644
index 0000000..be6cbd5
--- /dev/null
+++ b/lib/go/thrift/texception.go
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "os"
+)
+
+/**
+ * Generic exception class for Thrift.
+ *
+ */
+
+type TException interface {
+  String() string
+}
+
+type tException struct {
+  message string
+}
+
+func (p *tException) String() string {
+  return p.message
+}
+
+func NewTException(m string) TException {
+  return &tException{message: m}
+}
+
+func NewTExceptionFromOsError(e os.Error) TException {
+  if e == nil {
+    return nil
+  }
+  t, ok := e.(TException)
+  if ok {
+    return t
+  }
+  return NewTException(e.String())
+}
diff --git a/lib/go/thrift/texception_test.go b/lib/go/thrift/texception_test.go
new file mode 100644
index 0000000..50b3cdd
--- /dev/null
+++ b/lib/go/thrift/texception_test.go
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "os"
+  "testing"
+)
+
+
+func TestTException(t *testing.T) {
+  exc := NewTException("")
+  if exc.String() != "" {
+    t.Fatalf("Expected empty string for exception but found '%s'", exc.String())
+  }
+  exc = NewTExceptionFromOsError(os.EOF)
+  if exc.String() != os.EOF.String() {
+    t.Fatalf("Expected '%s', but found '%s'", os.EOF.String(), exc.String())
+  }
+}
diff --git a/lib/go/thrift/tfield.go b/lib/go/thrift/tfield.go
new file mode 100644
index 0000000..31d9b89
--- /dev/null
+++ b/lib/go/thrift/tfield.go
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "sort"
+)
+
+/**
+ * Helper class that encapsulates field metadata.
+ *
+ */
+type TField interface {
+  Name() string
+  TypeId() TType
+  Id() int
+  String() string
+  CompareTo(other interface{}) (int, bool)
+  Equals(other interface{}) bool
+}
+
+type tField struct {
+  name   string
+  typeId TType
+  id     int
+}
+
+func NewTFieldDefault() TField {
+  return ANONYMOUS_FIELD
+}
+
+func NewTField(n string, t TType, i int) TField {
+  return &tField{name: n, typeId: t, id: i}
+}
+
+func (p *tField) Name() string {
+  if p == nil {
+    return ""
+  }
+  return p.name
+}
+
+func (p *tField) TypeId() TType {
+  if p == nil {
+    return TType(VOID)
+  }
+  return p.typeId
+}
+
+func (p *tField) Id() int {
+  if p == nil {
+    return -1
+  }
+  return p.id
+}
+
+func (p *tField) String() string {
+  if p == nil {
+    return "<nil>"
+  }
+  return "<TField name:'" + p.name + "' type:" + string(p.typeId) + " field-id:" + string(p.id) + ">"
+}
+
+func (p *tField) CompareTo(other interface{}) (int, bool) {
+  if other == nil {
+    return 1, true
+  }
+  if data, ok := other.(TField); ok {
+    if p.Id() != data.Id() {
+      return CompareInt(p.Id(), data.Id()), true
+    }
+    if p.TypeId() != data.TypeId() {
+      return CompareByte(byte(p.TypeId()), byte(data.TypeId())), true
+    }
+    return CompareString(p.Name(), data.Name()), true
+  }
+  return 0, false
+}
+
+func (p *tField) Equals(other interface{}) bool {
+  if p == nil {
+    return other == nil
+  }
+  if other == nil {
+    return false
+  }
+  if data, ok := other.(TField); ok {
+    return p.TypeId() == data.TypeId() && p.Id() == data.Id()
+  }
+  return false
+}
+
+var ANONYMOUS_FIELD TField
+
+type tFieldArray []TField
+
+func (p tFieldArray) Len() int {
+  return len(p)
+}
+
+func (p tFieldArray) Less(i, j int) bool {
+  return p[i].Id() < p[j].Id()
+}
+
+func (p tFieldArray) Swap(i, j int) {
+  p[i], p[j] = p[j], p[i]
+}
+
+type TFieldContainer interface {
+  TContainer
+  FieldNameFromFieldId(id int) string
+  FieldIdFromFieldName(name string) int
+  FieldFromFieldId(id int) TField
+  FieldFromFieldName(name string) TField
+  At(i int) TField
+  Iter() <-chan TField
+}
+
+type tFieldContainer struct {
+  fields         []TField
+  nameToFieldMap map[string]TField
+  idToFieldMap   map[int]TField
+}
+
+func NewTFieldContainer(fields []TField) TFieldContainer {
+  sortedFields := make([]TField, len(fields))
+  nameToFieldMap := make(map[string]TField)
+  idToFieldMap := make(map[int]TField)
+  for i, field := range fields {
+    sortedFields[i] = field
+    idToFieldMap[field.Id()] = field
+    if field.Name() != "" {
+      nameToFieldMap[field.Name()] = field
+    }
+  }
+  sort.Sort(tFieldArray(sortedFields))
+  return &tFieldContainer{
+    fields:         fields,
+    nameToFieldMap: nameToFieldMap,
+    idToFieldMap:   idToFieldMap,
+  }
+}
+
+func (p *tFieldContainer) FieldNameFromFieldId(id int) string {
+  if field, ok := p.idToFieldMap[id]; ok {
+    return field.Name()
+  }
+  return ""
+}
+
+func (p *tFieldContainer) FieldIdFromFieldName(name string) int {
+  if field, ok := p.nameToFieldMap[name]; ok {
+    return field.Id()
+  }
+  return -1
+}
+
+func (p *tFieldContainer) FieldFromFieldId(id int) TField {
+  if field, ok := p.idToFieldMap[id]; ok {
+    return field
+  }
+  return ANONYMOUS_FIELD
+}
+
+func (p *tFieldContainer) FieldFromFieldName(name string) TField {
+  if field, ok := p.nameToFieldMap[name]; ok {
+    return field
+  }
+  return ANONYMOUS_FIELD
+}
+
+func (p *tFieldContainer) Len() int {
+  return len(p.fields)
+}
+
+func (p *tFieldContainer) At(i int) TField {
+  return p.FieldFromFieldId(i)
+}
+
+func (p *tFieldContainer) Contains(data interface{}) bool {
+  if i, ok := data.(int); ok {
+    for _, field := range p.fields {
+      if field.Id() == i {
+        return true
+      }
+    }
+  } else if i, ok := data.(int16); ok {
+    for _, field := range p.fields {
+      if field.Id() == int(i) {
+        return true
+      }
+    }
+  } else if s, ok := data.(string); ok {
+    for _, field := range p.fields {
+      if field.Name() == s {
+        return true
+      }
+    }
+  } else if f, ok := data.(TField); ok {
+    for _, field := range p.fields {
+      if field.Equals(f) {
+        return true
+      }
+    }
+  }
+  return false
+}
+
+func (p *tFieldContainer) Equals(other interface{}) bool {
+  if other == nil {
+    return false
+  }
+  if data, ok := other.(TFieldContainer); ok {
+    if p.Len() != data.Len() {
+      return false
+    }
+    for _, field := range p.fields {
+      if !data.Contains(field) {
+        return false
+      }
+    }
+    return true
+  }
+  return false
+}
+
+func (p *tFieldContainer) CompareTo(other interface{}) (int, bool) {
+  if other == nil {
+    return 1, true
+  }
+  if data, ok := other.(TFieldContainer); ok {
+    cont, ok2 := data.(*tFieldContainer)
+    if ok2 && p == cont {
+      return 0, true
+    }
+    if cmp := CompareInt(p.Len(), data.Len()); cmp != 0 {
+      return cmp, true
+    }
+    for _, field := range p.fields {
+      if cmp, ok3 := field.CompareTo(data.At(field.Id())); !ok3 || cmp != 0 {
+        return cmp, ok3
+      }
+    }
+    return 0, true
+  }
+  return 0, false
+}
+
+func (p *tFieldContainer) Iter() <-chan TField {
+  c := make(chan TField)
+  go p.iterate(c)
+  return c
+}
+
+func (p *tFieldContainer) iterate(c chan<- TField) {
+  for _, v := range p.fields {
+    c <- v
+  }
+  close(c)
+}
+
+func init() {
+  ANONYMOUS_FIELD = NewTField("", STOP, 0)
+}
diff --git a/lib/go/thrift/tframed_transport.go b/lib/go/thrift/tframed_transport.go
new file mode 100644
index 0000000..52049cb
--- /dev/null
+++ b/lib/go/thrift/tframed_transport.go
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "encoding/binary"
+  "bytes"
+  "os"
+)
+
+
+type TFramedTransport struct {
+  transport   TTransport
+  writeBuffer *bytes.Buffer
+  readBuffer  *bytes.Buffer
+}
+
+type tFramedTransportFactory struct {
+  factory TTransportFactory
+}
+
+func NewTFramedTransportFactory(factory TTransportFactory) TTransportFactory {
+  return &tFramedTransportFactory{factory: factory}
+}
+
+func (p *tFramedTransportFactory) GetTransport(base TTransport) TTransport {
+  return NewTFramedTransport(p.factory.GetTransport(base))
+}
+
+func NewTFramedTransport(transport TTransport) *TFramedTransport {
+  writeBuf := make([]byte, 0, 1024)
+  readBuf := make([]byte, 0, 1024)
+  return &TFramedTransport{transport: transport, writeBuffer: bytes.NewBuffer(writeBuf), readBuffer: bytes.NewBuffer(readBuf)}
+}
+
+func (p *TFramedTransport) Open() os.Error {
+  return p.transport.Open()
+}
+
+func (p *TFramedTransport) IsOpen() bool {
+  return p.transport.IsOpen()
+}
+
+func (p *TFramedTransport) Peek() bool {
+  return p.transport.Peek()
+}
+
+func (p *TFramedTransport) Close() os.Error {
+  return p.transport.Close()
+}
+
+func (p *TFramedTransport) Read(buf []byte) (int, os.Error) {
+  if p.readBuffer.Len() > 0 {
+    got, err := p.readBuffer.Read(buf)
+    if got > 0 {
+      return got, NewTTransportExceptionFromOsError(err)
+    }
+  }
+
+  // Read another frame of data
+  p.readFrame()
+
+  got, err := p.readBuffer.Read(buf)
+  return got, NewTTransportExceptionFromOsError(err)
+}
+
+func (p *TFramedTransport) ReadAll(buf []byte) (int, os.Error) {
+  return ReadAllTransport(p, buf)
+}
+
+func (p *TFramedTransport) Write(buf []byte) (int, os.Error) {
+  n, err := p.writeBuffer.Write(buf)
+  return n, NewTTransportExceptionFromOsError(err)
+}
+
+func (p *TFramedTransport) Flush() os.Error {
+  size := p.writeBuffer.Len()
+  buf := []byte{0, 0, 0, 0}
+  binary.BigEndian.PutUint32(buf, uint32(size))
+  _, err := p.transport.Write(buf)
+  if err != nil {
+    return NewTTransportExceptionFromOsError(err)
+  }
+  if size > 0 {
+    n, err := p.writeBuffer.WriteTo(p.transport)
+    if err != nil {
+      print("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err.String(), "\n")
+      return NewTTransportExceptionFromOsError(err)
+    }
+  }
+  err = p.transport.Flush()
+  return NewTTransportExceptionFromOsError(err)
+}
+
+func (p *TFramedTransport) readFrame() (int, os.Error) {
+  buf := []byte{0, 0, 0, 0}
+  _, err := p.transport.ReadAll(buf)
+  if err != nil {
+    return 0, err
+  }
+  size := int(binary.BigEndian.Uint32(buf))
+  if size < 0 {
+    // TODO(pomack) log error
+    return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "Read a negative frame size ("+string(size)+")")
+  }
+  if size == 0 {
+    return 0, nil
+  }
+  buf2 := make([]byte, size)
+  n, err := p.transport.ReadAll(buf2)
+  if err != nil {
+    return n, err
+  }
+  p.readBuffer = bytes.NewBuffer(buf2)
+  return size, nil
+}
diff --git a/lib/go/thrift/tframed_transport_test.go b/lib/go/thrift/tframed_transport_test.go
new file mode 100644
index 0000000..566318c
--- /dev/null
+++ b/lib/go/thrift/tframed_transport_test.go
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+)
+
+func TestFramedTransport(t *testing.T) {
+  trans := NewTFramedTransport(NewTMemoryBuffer())
+  TransportTest(t, trans, trans)
+}
diff --git a/lib/go/thrift/thttp_client.go b/lib/go/thrift/thttp_client.go
new file mode 100644
index 0000000..e09ecdf
--- /dev/null
+++ b/lib/go/thrift/thttp_client.go
@@ -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.
+ */
+
+package thrift
+
+import (
+  "bytes"
+  "http"
+  "os"
+)
+
+
+type THttpClient struct {
+  response           *http.Response
+  url                *http.URL
+  requestBuffer      *bytes.Buffer
+  nsecConnectTimeout int64
+  nsecReadTimeout    int64
+}
+
+type THttpClientTransportFactory struct {
+  url    string
+  isPost bool
+}
+
+func (p *THttpClientTransportFactory) GetTransport(trans TTransport) TTransport {
+  if trans != nil {
+    t, ok := trans.(*THttpClient)
+    if ok && t.url != nil {
+      if t.requestBuffer != nil {
+        t2, _ := NewTHttpPostClient(t.url.String())
+        return t2
+      }
+      t2, _ := NewTHttpClient(t.url.String())
+      return t2
+    }
+  }
+  if p.isPost {
+    s, _ := NewTHttpPostClient(p.url)
+    return s
+  }
+  s, _ := NewTHttpClient(p.url)
+  return s
+}
+
+func NewTHttpClientTransportFactory(url string) *THttpClientTransportFactory {
+  return &THttpClientTransportFactory{url: url, isPost: false}
+}
+
+func NewTHttpPostClientTransportFactory(url string) *THttpClientTransportFactory {
+  return &THttpClientTransportFactory{url: url, isPost: true}
+}
+
+
+func NewTHttpClient(url string) (TTransport, os.Error) {
+  response, finalUrl, err := http.Get(url)
+  if err != nil {
+    return nil, err
+  }
+  parsedURL, err := http.ParseURL(finalUrl)
+  if err != nil {
+    return nil, err
+  }
+  return &THttpClient{response: response, url: parsedURL}, nil
+}
+
+func NewTHttpPostClient(url string) (TTransport, os.Error) {
+  parsedURL, err := http.ParseURL(url)
+  if err != nil {
+    return nil, err
+  }
+  buf := make([]byte, 0, 1024)
+  return &THttpClient{url: parsedURL, requestBuffer: bytes.NewBuffer(buf)}, nil
+}
+
+func (p *THttpClient) Open() os.Error {
+  // do nothing
+  return nil
+}
+
+func (p *THttpClient) IsOpen() bool {
+  return p.response != nil || p.requestBuffer != nil
+}
+
+func (p *THttpClient) Peek() bool {
+  return p.IsOpen()
+}
+
+func (p *THttpClient) Close() os.Error {
+  if p.response != nil && p.response.Body != nil {
+    err := p.response.Body.Close()
+    p.response = nil
+    return err
+  }
+  if p.requestBuffer != nil {
+    p.requestBuffer.Reset()
+    p.requestBuffer = nil
+  }
+  return nil
+}
+
+func (p *THttpClient) Read(buf []byte) (int, os.Error) {
+  if p.response == nil {
+    return 0, NewTTransportException(NOT_OPEN, "Response buffer is empty, no request.")
+  }
+  n, err := p.response.Body.Read(buf)
+  return n, NewTTransportExceptionFromOsError(err)
+}
+
+func (p *THttpClient) ReadAll(buf []byte) (int, os.Error) {
+  return ReadAllTransport(p, buf)
+}
+
+func (p *THttpClient) Write(buf []byte) (int, os.Error) {
+  n, err := p.requestBuffer.Write(buf)
+  return n, err
+}
+
+func (p *THttpClient) Flush() os.Error {
+  response, err := http.Post(p.url.String(), "application/x-thrift", p.requestBuffer)
+  if err != nil {
+    return NewTTransportExceptionFromOsError(err)
+  }
+  if response.StatusCode != http.StatusOK {
+    // TODO(pomack) log bad response
+    return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "HTTP Response code: "+string(response.StatusCode))
+  }
+  p.response = response
+  return nil
+}
diff --git a/lib/go/thrift/thttp_client_test.go b/lib/go/thrift/thttp_client_test.go
new file mode 100644
index 0000000..1af8cd3
--- /dev/null
+++ b/lib/go/thrift/thttp_client_test.go
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+  "http"
+  "net"
+)
+
+func TestHttpClient(t *testing.T) {
+  addr, err := FindAvailableTCPServerPort(40000)
+  if err != nil {
+    t.Fatalf("Unable to find available tcp port addr: %s", err)
+  }
+  l, err := net.Listen(addr.Network(), addr.String())
+  if err != nil {
+    t.Fatalf("Unable to setup tcp listener on %s: %s", addr.String(), err)
+  }
+  go http.Serve(l, &HTTPEchoServer{})
+  trans, err := NewTHttpPostClient("http://" + addr.String())
+  if err != nil {
+    l.Close()
+    t.Fatalf("Unable to connect to %s: %s", addr.String(), err)
+  }
+  TransportTest(t, trans, trans)
+}
diff --git a/lib/go/thrift/tiostream_transport.go b/lib/go/thrift/tiostream_transport.go
new file mode 100644
index 0000000..5c4beea
--- /dev/null
+++ b/lib/go/thrift/tiostream_transport.go
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "bufio"
+  "io"
+  "os"
+)
+
+/**
+ * This is the most commonly used base transport. It takes an InputStream
+ * and an OutputStream and uses those to perform all transport operations.
+ * This allows for compatibility with all the nice constructs Java already
+ * has to provide a variety of types of streams.
+ *
+ */
+type TIOStreamTransport struct {
+  Reader       io.Reader
+  Writer       io.Writer
+  IsReadWriter bool
+}
+
+type TIOStreamTransportFactory struct {
+  Reader       io.Reader
+  Writer       io.Writer
+  IsReadWriter bool
+}
+
+func (p *TIOStreamTransportFactory) GetTransport(trans TTransport) TTransport {
+  if trans != nil {
+    t, ok := trans.(*TIOStreamTransport)
+    if ok {
+      if t.IsReadWriter {
+        return NewTIOStreamTransportRW(t.Reader.(io.ReadWriter))
+      }
+      if t.Reader != nil && t.Writer != nil {
+        return NewTIOStreamTransportRAndW(t.Reader, t.Writer)
+      }
+      if t.Reader != nil && t.Writer == nil {
+        return NewTIOStreamTransportR(t.Reader)
+      }
+      if t.Reader == nil && t.Writer != nil {
+        return NewTIOStreamTransportW(t.Writer)
+      }
+      return NewTIOStreamTransportDefault()
+    }
+  }
+  if p.IsReadWriter {
+    return NewTIOStreamTransportRW(p.Reader.(io.ReadWriter))
+  }
+  if p.Reader != nil && p.Writer != nil {
+    return NewTIOStreamTransportRAndW(p.Reader, p.Writer)
+  }
+  if p.Reader != nil && p.Writer == nil {
+    return NewTIOStreamTransportR(p.Reader)
+  }
+  if p.Reader == nil && p.Writer != nil {
+    return NewTIOStreamTransportW(p.Writer)
+  }
+  return NewTIOStreamTransportDefault()
+}
+
+func NewTIOStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *TIOStreamTransportFactory {
+  return &TIOStreamTransportFactory{Reader: reader, Writer: writer, IsReadWriter: isReadWriter}
+}
+
+
+/**
+ * Subclasses can invoke the default constructor and then assign the input
+ * streams in the open method.
+ */
+func NewTIOStreamTransportDefault() *TIOStreamTransport {
+  return &TIOStreamTransport{}
+}
+
+/**
+ * Input stream constructor.
+ *
+ * @param is Input stream to read from
+ */
+func NewTIOStreamTransportR(r io.Reader) *TIOStreamTransport {
+  return &TIOStreamTransport{Reader: bufio.NewReader(r)}
+}
+
+/**
+ * Output stream constructor.
+ *
+ * @param os Output stream to read from
+ */
+func NewTIOStreamTransportW(w io.Writer) *TIOStreamTransport {
+  return &TIOStreamTransport{Writer: bufio.NewWriter(w)}
+}
+
+/**
+ * Two-way stream constructor.
+ *
+ * @param is Input stream to read from
+ * @param os Output stream to read from
+ */
+func NewTIOStreamTransportRAndW(r io.Reader, w io.Writer) *TIOStreamTransport {
+  return &TIOStreamTransport{Reader: bufio.NewReader(r), Writer: bufio.NewWriter(w)}
+}
+
+/**
+ * Two-way stream constructor.
+ *
+ * @param is Input stream to read from
+ * @param os Output stream to read from
+ */
+func NewTIOStreamTransportRW(rw io.ReadWriter) *TIOStreamTransport {
+  // bufio has a bug where once a Reader hits EOF, a new Write never brings the reader out of EOF
+  // even if reader and writer use the same underlier
+  //bufrw := bufio.NewReadWriter(bufio.NewReader(rw), bufio.NewWriter(rw));
+  return &TIOStreamTransport{Reader: rw, Writer: rw, IsReadWriter: true}
+}
+
+/**
+ * The streams must already be open at construction time, so this should
+ * always return true.
+ *
+ * @return true
+ */
+func (p *TIOStreamTransport) IsOpen() bool {
+  return true
+}
+
+/**
+ * The streams must already be open. This method does nothing.
+ */
+func (p *TIOStreamTransport) Open() os.Error {
+  return nil
+}
+
+func (p *TIOStreamTransport) Peek() bool {
+  return p.IsOpen()
+}
+
+/**
+ * Closes both the input and output streams.
+ */
+func (p *TIOStreamTransport) Close() os.Error {
+  closedReader := false
+  if p.Reader != nil {
+    c, ok := p.Reader.(io.Closer)
+    if ok {
+      e := c.Close()
+      closedReader = true
+      if e != nil {
+        LOGGER.Print("Error closing input stream.", e)
+      }
+    }
+    p.Reader = nil
+  }
+  if p.Writer != nil && (!closedReader || !p.IsReadWriter) {
+    c, ok := p.Writer.(io.Closer)
+    if ok {
+      e := c.Close()
+      if e != nil {
+        LOGGER.Print("Error closing output stream.", e)
+      }
+    }
+    p.Writer = nil
+  }
+  return nil
+}
+
+/**
+ * Reads from the underlying input stream if not null.
+ */
+func (p *TIOStreamTransport) Read(buf []byte) (int, os.Error) {
+  if p.Reader == nil {
+    return 0, NewTTransportException(NOT_OPEN, "Cannot read from null inputStream")
+  }
+  n, err := p.Reader.Read(buf)
+  return n, NewTTransportExceptionFromOsError(err)
+}
+
+func (p *TIOStreamTransport) ReadAll(buf []byte) (int, os.Error) {
+  return ReadAllTransport(p, buf)
+}
+
+
+/**
+ * Writes to the underlying output stream if not null.
+ */
+func (p *TIOStreamTransport) Write(buf []byte) (int, os.Error) {
+  if p.Writer == nil {
+    LOGGER.Print("Could not write to iostream as Writer is null\n")
+    return 0, NewTTransportException(NOT_OPEN, "Cannot write to null outputStream")
+  }
+  n, err := p.Writer.Write(buf)
+  if n == 0 || err != nil {
+    LOGGER.Print("Error writing to iostream, only wrote ", n, " bytes: ", err.String(), "\n")
+  }
+  return n, NewTTransportExceptionFromOsError(err)
+}
+
+/**
+ * Flushes the underlying output stream if not null.
+ */
+func (p *TIOStreamTransport) Flush() os.Error {
+  if p.Writer == nil {
+    return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream")
+  }
+  f, ok := p.Writer.(Flusher)
+  if ok {
+    err := f.Flush()
+    if err != nil {
+      return NewTTransportExceptionFromOsError(err)
+    }
+  }
+  return nil
+}
diff --git a/lib/go/thrift/tiostream_transport_test.go b/lib/go/thrift/tiostream_transport_test.go
new file mode 100644
index 0000000..a7425c7
--- /dev/null
+++ b/lib/go/thrift/tiostream_transport_test.go
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+  "bytes"
+)
+
+func TestIOStreamTransport(t *testing.T) {
+  trans := NewTIOStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024)))
+  TransportTest(t, trans, trans)
+}
diff --git a/lib/go/thrift/tjson_protocol.go b/lib/go/thrift/tjson_protocol.go
new file mode 100644
index 0000000..45ab700
--- /dev/null
+++ b/lib/go/thrift/tjson_protocol.go
@@ -0,0 +1,537 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "encoding/base64"
+  "fmt"
+)
+
+const (
+  THRIFT_JSON_PROTOCOL_VERSION = 1
+)
+
+// for references to _ParseContext see tsimplejson_protocol.go
+
+/**
+ * JSON protocol implementation for thrift.
+ *
+ * This protocol produces/consumes a simple output format
+ * suitable for parsing by scripting languages.  It should not be
+ * confused with the full-featured TJSONProtocol.
+ *
+ */
+type TJSONProtocol struct {
+  *TSimpleJSONProtocol
+}
+
+/**
+ * Constructor
+ */
+func NewTJSONProtocol(t TTransport) *TJSONProtocol {
+  v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)}
+  v.parseContextStack.Push(int(_CONTEXT_IN_TOPLEVEL))
+  v.dumpContext.Push(int(_CONTEXT_IN_TOPLEVEL))
+  return v
+}
+
+/**
+ * Factory
+ */
+type TJSONProtocolFactory struct{}
+
+func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
+  return NewTJSONProtocol(trans)
+}
+
+func NewTJSONProtocolFactory() *TJSONProtocolFactory {
+  return &TJSONProtocolFactory{}
+}
+
+
+func (p *TJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) TProtocolException {
+  if e := p.OutputListBegin(); e != nil {
+    return e
+  }
+  if e := p.WriteI32(THRIFT_JSON_PROTOCOL_VERSION); e != nil {
+    return e
+  }
+  if e := p.WriteString(name); e != nil {
+    return e
+  }
+  if e := p.WriteByte(byte(typeId)); e != nil {
+    return e
+  }
+  if e := p.WriteI32(seqId); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TJSONProtocol) WriteMessageEnd() TProtocolException {
+  return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteStructBegin(name string) TProtocolException {
+  if e := p.OutputObjectBegin(); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TJSONProtocol) WriteStructEnd() TProtocolException {
+  return p.OutputObjectEnd()
+}
+
+func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) TProtocolException {
+  if e := p.WriteI16(id); e != nil {
+    return e
+  }
+  if e := p.OutputObjectBegin(); e != nil {
+    return e
+  }
+  if e := p.WriteString(p.TypeIdToString(typeId)); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TJSONProtocol) WriteFieldEnd() TProtocolException {
+  return p.OutputObjectEnd()
+}
+
+func (p *TJSONProtocol) WriteFieldStop() TProtocolException { return nil }
+
+func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException {
+  if e := p.OutputListBegin(); e != nil {
+    return e
+  }
+  if e := p.WriteString(p.TypeIdToString(keyType)); e != nil {
+    return e
+  }
+  if e := p.WriteString(p.TypeIdToString(valueType)); e != nil {
+    return e
+  }
+  return p.WriteI64(int64(size))
+}
+
+func (p *TJSONProtocol) WriteMapEnd() TProtocolException {
+  return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) TProtocolException {
+  return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TJSONProtocol) WriteListEnd() TProtocolException {
+  return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) TProtocolException {
+  return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TJSONProtocol) WriteSetEnd() TProtocolException {
+  return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteBool(b bool) TProtocolException {
+  return p.OutputBool(b)
+}
+
+func (p *TJSONProtocol) WriteByte(b byte) TProtocolException {
+  return p.WriteI32(int32(b))
+}
+
+func (p *TJSONProtocol) WriteI16(v int16) TProtocolException {
+  return p.WriteI32(int32(v))
+}
+
+func (p *TJSONProtocol) WriteI32(v int32) TProtocolException {
+  return p.OutputI64(int64(v))
+}
+
+func (p *TJSONProtocol) WriteI64(v int64) TProtocolException {
+  return p.OutputI64(int64(v))
+}
+
+func (p *TJSONProtocol) WriteDouble(v float64) TProtocolException {
+  return p.OutputF64(v)
+}
+
+func (p *TJSONProtocol) WriteString(v string) TProtocolException {
+  return p.OutputString(v)
+}
+
+func (p *TJSONProtocol) WriteBinary(v []byte) TProtocolException {
+  // JSON library only takes in a string, 
+  // not an arbitrary byte array, to ensure bytes are transmitted
+  // efficiently we must convert this into a valid JSON string
+  // therefore we use base64 encoding to avoid excessive escaping/quoting
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  p.writer.Write(JSON_QUOTE_BYTES)
+  writer := base64.NewEncoder(base64.StdEncoding, p.writer)
+  if _, e := writer.Write(v); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  writer.Close()
+  p.writer.Write(JSON_QUOTE_BYTES)
+  return p.OutputPostValue()
+}
+
+/**
+ * Reading methods.
+ */
+
+func (p *TJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err TProtocolException) {
+  if isNull, err := p.ParseListBegin(); isNull || err != nil {
+    return name, typeId, seqId, err
+  }
+  version, err := p.ReadI32()
+  if err != nil {
+    return name, typeId, seqId, err
+  }
+  if version != THRIFT_JSON_PROTOCOL_VERSION {
+    return name, typeId, seqId, NewTProtocolException(INVALID_DATA, fmt.Sprint("Unknown Protocol version ", version, ", expected version ", THRIFT_JSON_PROTOCOL_VERSION, "\n"))
+  }
+  if name, err = p.ReadString(); err != nil {
+    return name, typeId, seqId, err
+  }
+  bTypeId, err := p.ReadByte()
+  typeId = TMessageType(bTypeId)
+  if err != nil {
+    return name, typeId, seqId, err
+  }
+  if seqId, err = p.ReadI32(); err != nil {
+    return name, typeId, seqId, err
+  }
+  return name, typeId, seqId, nil
+}
+
+func (p *TJSONProtocol) ReadMessageEnd() TProtocolException {
+  err := p.ParseListEnd()
+  return err
+}
+
+func (p *TJSONProtocol) ReadStructBegin() (name string, err TProtocolException) {
+  _, err = p.ParseObjectStart()
+  return "", err
+}
+
+func (p *TJSONProtocol) ReadStructEnd() TProtocolException {
+  return p.ParseObjectEnd()
+}
+
+func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, TProtocolException) {
+  if p.reader.Buffered() < 1 {
+    return "", STOP, -1, nil
+  }
+  b, _ := p.reader.Peek(1)
+  if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] {
+    return "", STOP, -1, nil
+  }
+  fieldId, err := p.ReadI16()
+  if err != nil {
+    return "", STOP, fieldId, err
+  }
+  if _, err = p.ParseObjectStart(); err != nil {
+    return "", STOP, fieldId, err
+  }
+  sType, err := p.ReadString()
+  fType := p.StringToTypeId(sType)
+  return "", fType, fieldId, err
+}
+
+func (p *TJSONProtocol) ReadFieldEnd() TProtocolException {
+  return p.ParseObjectEnd()
+}
+
+func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e TProtocolException) {
+  if isNull, e := p.ParseListBegin(); isNull || e != nil {
+    return VOID, VOID, 0, e
+  }
+
+  // read keyType
+  sKeyType, e := p.ReadString()
+  keyType = p.StringToTypeId(sKeyType)
+  if e != nil {
+    return keyType, valueType, size, e
+  }
+
+  // read valueType
+  sValueType, e := p.ReadString()
+  valueType = p.StringToTypeId(sValueType)
+  if e != nil {
+    return keyType, valueType, size, e
+  }
+
+  // read size
+  iSize, err := p.ReadI64()
+  size = int(iSize)
+  return keyType, valueType, size, err
+}
+
+func (p *TJSONProtocol) ReadMapEnd() TProtocolException {
+  return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e TProtocolException) {
+  return p.ParseElemListBegin()
+}
+
+func (p *TJSONProtocol) ReadListEnd() TProtocolException {
+  return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e TProtocolException) {
+  return p.ParseElemListBegin()
+}
+
+func (p *TJSONProtocol) ReadSetEnd() TProtocolException {
+  return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadBool() (bool, TProtocolException) {
+  var value bool
+  if err := p.ParsePreValue(); err != nil {
+    return value, err
+  }
+  b, _ := p.reader.Peek(len(JSON_FALSE))
+  if len(b) > 0 {
+    switch b[0] {
+    case JSON_TRUE[0]:
+      if string(b[0:len(JSON_TRUE)]) == string(JSON_TRUE) {
+        p.reader.Read(b[0:len(JSON_TRUE)])
+        value = true
+      } else {
+        return value, NewTProtocolException(INVALID_DATA, "Expected \"true\" but found: "+string(b))
+      }
+      break
+    case JSON_FALSE[0]:
+      if string(b[0:len(JSON_FALSE)]) == string(JSON_FALSE) {
+        p.reader.Read(b[0:len(JSON_FALSE)])
+        value = false
+      } else {
+        return value, NewTProtocolException(INVALID_DATA, "Expected \"false\" but found: "+string(b))
+      }
+      break
+    case JSON_NULL[0]:
+      if string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+        p.reader.Read(b[0:len(JSON_NULL)])
+        value = false
+      } else {
+        return value, NewTProtocolException(INVALID_DATA, "Expected \"null\" but found: "+string(b))
+      }
+    default:
+      return value, NewTProtocolException(INVALID_DATA, "Expected \"true\", \"false\", or \"null\" but found: "+string(b))
+    }
+  }
+  return value, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) ReadByte() (byte, TProtocolException) {
+  v, err := p.ReadI64()
+  return byte(v), err
+}
+
+func (p *TJSONProtocol) ReadI16() (int16, TProtocolException) {
+  v, err := p.ReadI64()
+  return int16(v), err
+}
+
+func (p *TJSONProtocol) ReadI32() (int32, TProtocolException) {
+  v, err := p.ReadI64()
+  return int32(v), err
+}
+
+func (p *TJSONProtocol) ReadI64() (int64, TProtocolException) {
+  v, _, err := p.ParseI64()
+  return v, err
+}
+
+func (p *TJSONProtocol) ReadDouble() (float64, TProtocolException) {
+  v, _, err := p.ParseF64()
+  return v, err
+}
+
+func (p *TJSONProtocol) ReadString() (string, TProtocolException) {
+  var v string
+  if err := p.ParsePreValue(); err != nil {
+    return v, err
+  }
+  b, _ := p.reader.Peek(len(JSON_NULL))
+  if len(b) > 0 && b[0] == JSON_QUOTE {
+    p.reader.ReadByte()
+    value, err := p.ParseStringBody()
+    v = value
+    if err != nil {
+      return v, err
+    }
+  } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+    _, err := p.reader.Read(b[0:len(JSON_NULL)])
+    if err != nil {
+      return v, NewTProtocolExceptionFromOsError(err)
+    }
+  } else {
+    return v, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected a JSON string, found ", string(b)))
+  }
+  return v, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) ReadBinary() ([]byte, TProtocolException) {
+  var v []byte
+  if err := p.ParsePreValue(); err != nil {
+    return nil, err
+  }
+  b, _ := p.reader.Peek(len(JSON_NULL))
+  if len(b) > 0 && b[0] == JSON_QUOTE {
+    p.reader.ReadByte()
+    value, err := p.ParseBase64EncodedBody()
+    v = value
+    if err != nil {
+      return v, err
+    }
+  } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+    _, err := p.reader.Read(b[0:len(JSON_NULL)])
+    if err != nil {
+      return v, NewTProtocolExceptionFromOsError(err)
+    }
+  } else {
+    return v, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected a JSON string, found ", string(b)))
+  }
+  return v, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) Flush() (err TProtocolException) {
+  return NewTProtocolExceptionFromOsError(p.writer.Flush())
+}
+
+func (p *TJSONProtocol) Skip(fieldType TType) (err TProtocolException) {
+  return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TJSONProtocol) Transport() TTransport {
+  return p.trans
+}
+
+func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e TProtocolException) {
+  if isNull, e := p.ParseListBegin(); isNull || e != nil {
+    return VOID, 0, e
+  }
+  sElemType, err := p.ReadString()
+  elemType = p.StringToTypeId(sElemType)
+  if err != nil {
+    return elemType, size, err
+  }
+  nSize, err2 := p.ReadI64()
+  size = int(nSize)
+  return elemType, size, err2
+}
+
+func (p *TJSONProtocol) writeElemListBegin(elemType TType, size int) TProtocolException {
+  if e := p.OutputListBegin(); e != nil {
+    return e
+  }
+  if e := p.OutputString(p.TypeIdToString(elemType)); e != nil {
+    return e
+  }
+  if e := p.OutputI64(int64(size)); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TJSONProtocol) TypeIdToString(fieldType TType) string {
+  switch byte(fieldType) {
+  case STOP:
+    return "stp"
+  case VOID:
+    return "v"
+  case BOOL:
+    return "tf"
+  case BYTE:
+    return "i8"
+  case DOUBLE:
+    return "dbl"
+  case I16:
+    return "i16"
+  case I32:
+    return "i32"
+  case I64:
+    return "i64"
+  case STRING:
+    return "str"
+  case STRUCT:
+    return "rec"
+  case MAP:
+    return "map"
+  case SET:
+    return "set"
+  case LIST:
+    return "lst"
+  case ENUM:
+    return "i32"
+  case UTF16:
+    return "str"
+  case GENERIC:
+    return "gen"
+  }
+  return ""
+}
+
+func (p *TJSONProtocol) StringToTypeId(fieldType string) TType {
+  switch fieldType {
+  case "stp":
+    return TType(STOP)
+  case "v":
+    return TType(VOID)
+  case "tf":
+    return TType(BOOL)
+  case "i8":
+    return TType(BYTE)
+  case "dbl":
+    return TType(DOUBLE)
+  case "16":
+    return TType(I16)
+  case "i32":
+    return TType(I32)
+  case "i64":
+    return TType(I64)
+  case "str":
+    return TType(STRING)
+  case "rec":
+    return TType(STRUCT)
+  case "map":
+    return TType(MAP)
+  case "set":
+    return TType(SET)
+  case "lst":
+    return TType(LIST)
+  case "enm":
+    return TType(ENUM)
+  case "u16":
+    return TType(UTF16)
+  case "gen":
+    return TType(GENERIC)
+  }
+  return TType(STOP)
+}
diff --git a/lib/go/thrift/tjson_protocol_test.go b/lib/go/thrift/tjson_protocol_test.go
new file mode 100644
index 0000000..60f0f2e
--- /dev/null
+++ b/lib/go/thrift/tjson_protocol_test.go
@@ -0,0 +1,674 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "encoding/base64"
+  "fmt"
+  "json"
+  "math"
+  "strconv"
+  "testing"
+)
+
+func TestWriteJSONProtocolBool(t *testing.T) {
+  thetype := "boolean"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  for _, value := range BOOL_VALUES {
+    if e := p.WriteBool(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := false
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadJSONProtocolBool(t *testing.T) {
+  thetype := "boolean"
+  for _, value := range BOOL_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTJSONProtocol(trans)
+    if value {
+      trans.Write(JSON_TRUE)
+    } else {
+      trans.Write(JSON_FALSE)
+    }
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadBool()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteJSONProtocolByte(t *testing.T) {
+  thetype := "byte"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  for _, value := range BYTE_VALUES {
+    if e := p.WriteByte(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := byte(0)
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadJSONProtocolByte(t *testing.T) {
+  thetype := "byte"
+  for _, value := range BYTE_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTJSONProtocol(trans)
+    trans.WriteString(strconv.Itoa(int(value)))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadByte()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteJSONProtocolI16(t *testing.T) {
+  thetype := "int16"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  for _, value := range INT16_VALUES {
+    if e := p.WriteI16(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := int16(0)
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadJSONProtocolI16(t *testing.T) {
+  thetype := "int16"
+  for _, value := range INT16_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTJSONProtocol(trans)
+    trans.WriteString(strconv.Itoa(int(value)))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadI16()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteJSONProtocolI32(t *testing.T) {
+  thetype := "int32"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  for _, value := range INT32_VALUES {
+    if e := p.WriteI32(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := int32(0)
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadJSONProtocolI32(t *testing.T) {
+  thetype := "int32"
+  for _, value := range INT32_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTJSONProtocol(trans)
+    trans.WriteString(strconv.Itoa(int(value)))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadI32()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteJSONProtocolI64(t *testing.T) {
+  thetype := "int64"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  for _, value := range INT64_VALUES {
+    if e := p.WriteI64(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := int64(0)
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadJSONProtocolI64(t *testing.T) {
+  thetype := "int64"
+  for _, value := range INT64_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTJSONProtocol(trans)
+    trans.WriteString(strconv.Itoa64(value))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadI64()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteJSONProtocolDouble(t *testing.T) {
+  thetype := "double"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  for _, value := range DOUBLE_VALUES {
+    if e := p.WriteDouble(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if math.IsInf(value, 1) {
+      if s != JsonQuote(JSON_INFINITY) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_INFINITY))
+      }
+    } else if math.IsInf(value, -1) {
+      if s != JsonQuote(JSON_NEGATIVE_INFINITY) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_NEGATIVE_INFINITY))
+      }
+    } else if math.IsNaN(value) {
+      if s != JsonQuote(JSON_NAN) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_NAN))
+      }
+    } else {
+      if s != fmt.Sprint(value) {
+        t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+      }
+      v := float64(0)
+      if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+      }
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadJSONProtocolDouble(t *testing.T) {
+  thetype := "double"
+  for _, value := range DOUBLE_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTJSONProtocol(trans)
+    n := NewNumericFromDouble(value)
+    trans.WriteString(n.String())
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadDouble()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if math.IsInf(value, 1) {
+      if !math.IsInf(v, 1) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+      }
+    } else if math.IsInf(value, -1) {
+      if !math.IsInf(v, -1) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+      }
+    } else if math.IsNaN(value) {
+      if !math.IsNaN(v) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+      }
+    } else {
+      if v != value {
+        t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+      }
+      if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+      }
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteJSONProtocolString(t *testing.T) {
+  thetype := "string"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  for _, value := range STRING_VALUES {
+    if e := p.WriteString(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s[0] != '"' || s[len(s)-1] != '"' {
+      t.Fatalf("Bad value for %s '%v', wrote '%v', expected: %v", thetype, value, s, fmt.Sprint("\"", value, "\""))
+    }
+    v := new(string)
+    if err := json.Unmarshal([]byte(s), v); err != nil || *v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadJSONProtocolString(t *testing.T) {
+  thetype := "string"
+  for _, value := range STRING_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTJSONProtocol(trans)
+    trans.WriteString(JsonQuote(value))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadString()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    v1 := new(string)
+    if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteJSONProtocolBinary(t *testing.T) {
+  thetype := "binary"
+  value := protocol_bdata
+  b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata)))
+  base64.StdEncoding.Encode(b64value, value)
+  b64String := string(b64value)
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  if e := p.WriteBinary(value); e != nil {
+    t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+  }
+  if e := p.Flush(); e != nil {
+    t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+  }
+  s := trans.String()
+  expectedString := fmt.Sprint("\"", b64String, "\"")
+  if s != expectedString {
+    t.Fatalf("Bad value for %s %v\n  wrote:  \"%v\"\nexpected: \"%v\"", thetype, value, s, expectedString)
+  }
+  v1, err := p.ReadBinary()
+  if err != nil {
+    t.Fatalf("Unable to read binary: %s", err.String())
+  }
+  if len(v1) != len(value) {
+    t.Fatalf("Invalid value for binary\nexpected: \"%v\"\n   read: \"%v\"", value, v1)
+  }
+  for k, v := range value {
+    if v1[k] != v {
+      t.Fatalf("Invalid value for binary at %v\nexpected: \"%v\"\n   read: \"%v\"", k, v, v1[k])
+    }
+  }
+  trans.Close()
+}
+
+func TestReadJSONProtocolBinary(t *testing.T) {
+  thetype := "binary"
+  value := protocol_bdata
+  b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata)))
+  base64.StdEncoding.Encode(b64value, value)
+  b64String := string(b64value)
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  trans.WriteString(JsonQuote(b64String))
+  trans.Flush()
+  s := trans.String()
+  v, e := p.ReadBinary()
+  if e != nil {
+    t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+  }
+  if len(v) != len(value) {
+    t.Fatalf("Bad value for %s value length %v, wrote: %v, received length: %v", thetype, len(value), s, len(v))
+  }
+  for i := 0; i < len(v); i++ {
+    if v[i] != value[i] {
+      t.Fatalf("Bad value for %s at index %d value %v, wrote: %v, received: %v", thetype, i, value[i], s, v[i])
+    }
+  }
+  v1 := new(string)
+  if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != b64String {
+    t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1)
+  }
+  trans.Reset()
+  trans.Close()
+}
+
+func TestWriteJSONProtocolList(t *testing.T) {
+  thetype := "list"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  p.WriteListBegin(TType(DOUBLE), len(DOUBLE_VALUES))
+  for _, value := range DOUBLE_VALUES {
+    if e := p.WriteDouble(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+  }
+  p.WriteListEnd()
+  if e := p.Flush(); e != nil {
+    t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+  }
+  str := trans.String()
+  str1 := new([]interface{})
+  err := json.Unmarshal([]byte(str), str1)
+  if err != nil {
+    t.Fatalf("Unable to decode %s, wrote: %s", thetype, str)
+  }
+  l := *str1
+  if len(l) < 2 {
+    t.Fatalf("List must be at least of length two to include metadata")
+  }
+  if int(l[0].(float64)) != DOUBLE {
+    t.Fatal("Invalid type for list, expected: ", DOUBLE, ", but was: ", l[0])
+  }
+  if int(l[1].(float64)) != len(DOUBLE_VALUES) {
+    t.Fatal("Invalid length for list, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1])
+  }
+  for k, value := range DOUBLE_VALUES {
+    s := l[k+2]
+    if math.IsInf(value, 1) {
+      if s.(string) != JSON_INFINITY {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_INFINITY), str)
+      }
+    } else if math.IsInf(value, 0) {
+      if s.(string) != JSON_NEGATIVE_INFINITY {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY), str)
+      }
+    } else if math.IsNaN(value) {
+      if s.(string) != JSON_NAN {
+        t.Fatalf("Bad value for %s at index %v  %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NAN), str)
+      }
+    } else {
+      if s.(float64) != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s)
+      }
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestWriteJSONProtocolSet(t *testing.T) {
+  thetype := "set"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  p.WriteSetBegin(TType(DOUBLE), len(DOUBLE_VALUES))
+  for _, value := range DOUBLE_VALUES {
+    if e := p.WriteDouble(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+  }
+  p.WriteSetEnd()
+  if e := p.Flush(); e != nil {
+    t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+  }
+  str := trans.String()
+  str1 := new([]interface{})
+  err := json.Unmarshal([]byte(str), str1)
+  if err != nil {
+    t.Fatalf("Unable to decode %s, wrote: %s", thetype, str)
+  }
+  l := *str1
+  if len(l) < 2 {
+    t.Fatalf("Set must be at least of length two to include metadata")
+  }
+  if int(l[0].(float64)) != DOUBLE {
+    t.Fatal("Invalid type for set, expected: ", DOUBLE, ", but was: ", l[0])
+  }
+  if int(l[1].(float64)) != len(DOUBLE_VALUES) {
+    t.Fatal("Invalid length for set, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1])
+  }
+  for k, value := range DOUBLE_VALUES {
+    s := l[k+2]
+    if math.IsInf(value, 1) {
+      if s.(string) != JSON_INFINITY {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_INFINITY), str)
+      }
+    } else if math.IsInf(value, 0) {
+      if s.(string) != JSON_NEGATIVE_INFINITY {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY), str)
+      }
+    } else if math.IsNaN(value) {
+      if s.(string) != JSON_NAN {
+        t.Fatalf("Bad value for %s at index %v  %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NAN), str)
+      }
+    } else {
+      if s.(float64) != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s)
+      }
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestWriteJSONProtocolMap(t *testing.T) {
+  thetype := "map"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  p.WriteMapBegin(TType(I32), TType(DOUBLE), len(DOUBLE_VALUES))
+  for k, value := range DOUBLE_VALUES {
+    if e := p.WriteI32(int32(k)); e != nil {
+      t.Fatalf("Unable to write %s key int32 value %v due to error: %s", thetype, k, e.String())
+    }
+    if e := p.WriteDouble(value); e != nil {
+      t.Fatalf("Unable to write %s value float64 value %v due to error: %s", thetype, value, e.String())
+    }
+  }
+  p.WriteMapEnd()
+  if e := p.Flush(); e != nil {
+    t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+  }
+  str := trans.String()
+  if str[0] != '[' || str[len(str)-1] != ']' {
+    t.Fatalf("Bad value for %s, wrote: %q, in go: %q", thetype, str, DOUBLE_VALUES)
+  }
+  expectedKeyType, expectedValueType, expectedSize, err := p.ReadMapBegin()
+  if err != nil {
+    t.Fatalf("Error while reading map begin: %s", err.String())
+  }
+  if expectedKeyType != I32 {
+    t.Fatal("Expected map key type ", I32, ", but was ", expectedKeyType)
+  }
+  if expectedValueType != DOUBLE {
+    t.Fatal("Expected map value type ", DOUBLE, ", but was ", expectedValueType)
+  }
+  if expectedSize != len(DOUBLE_VALUES) {
+    t.Fatal("Expected map size of ", len(DOUBLE_VALUES), ", but was ", expectedSize)
+  }
+  for k, value := range DOUBLE_VALUES {
+    ik, err := p.ReadI32()
+    if err != nil {
+      t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, ik, string(k), err.String())
+    }
+    if int(ik) != k {
+      t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v", thetype, k, ik, k)
+    }
+    dv, err := p.ReadDouble()
+    if err != nil {
+      t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, dv, value, err.String())
+    }
+    s := strconv.Ftoa64(dv, 'g', 10)
+    if math.IsInf(value, 1) {
+      if !math.IsInf(dv, 1) {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_INFINITY))
+      }
+    } else if math.IsInf(value, 0) {
+      if !math.IsInf(dv, 0) {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY))
+      }
+    } else if math.IsNaN(value) {
+      if !math.IsNaN(dv) {
+        t.Fatalf("Bad value for %s at index %v  %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_NAN))
+      }
+    } else {
+      expected := strconv.Ftoa64(value, 'g', 10)
+      if s != expected {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected %v", thetype, k, value, s, expected)
+      }
+      v := float64(0)
+      if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+      }
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+
+func TestReadWriteJSONStruct(t *testing.T) {
+  thetype := "struct"
+  trans := NewTMemoryBuffer()
+  p := NewTJSONProtocol(trans)
+  orig := NewWork()
+  orig.Num1 = 25
+  orig.Num2 = 102
+  orig.Op = ADD
+  orig.Comment = "Add: 25 + 102"
+  if e := orig.Write(p); e != nil {
+    t.Fatalf("Unable to write %s value %#v due to error: %s", thetype, orig, e.String())
+  }
+  p.Flush()
+  t.Log("Memory buffer contents: ", trans.String())
+  expectedString := "{\"1\":{\"i32\":25},\"2\":{\"i32\":102},\"3\":{\"i32\":1},\"4\":{\"str\":\"Add: 25 + 102\"}}"
+  if expectedString != trans.String() {
+    t.Fatalf("Expected JSON Struct with value %#v but have %#v", expectedString, trans.String())
+  }
+  read := NewWork()
+  e := read.Read(p)
+  t.Logf("Read %s value: %#v", thetype, read)
+  if e != nil {
+    t.Fatalf("Unable to read %s due to error: %s", thetype, e.String())
+  }
+  if !orig.Equals(read) {
+    t.Fatalf("Original Write != Read: %#v != %#v ", orig, read)
+  }
+}
+
+func TestReadWriteJSONProtocol(t *testing.T) {
+  ReadWriteProtocolTest(t, NewTJSONProtocolFactory())
+}
diff --git a/lib/go/thrift/tlist.go b/lib/go/thrift/tlist.go
new file mode 100644
index 0000000..778fc3b
--- /dev/null
+++ b/lib/go/thrift/tlist.go
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "container/vector"
+)
+
+/**
+ * Helper class that encapsulates list metadata.
+ *
+ */
+type TList interface {
+  TContainer
+  ElemType() TType
+  At(i int) interface{}
+  Set(i int, data interface{})
+  Push(data interface{})
+  Pop() interface{}
+  Swap(i, j int)
+  Insert(i int, data interface{})
+  Delete(i int)
+  Less(i, j int) bool
+  Iter() <-chan interface{}
+}
+
+type tList struct {
+  elemType TType
+  l        *vector.Vector
+}
+
+func NewTList(t TType, s int) TList {
+  var v vector.Vector
+  return &tList{elemType: t, l: v.Resize(s, s)}
+}
+
+func NewTListDefault() TList {
+  var v vector.Vector
+  return &tList{elemType: TType(STOP), l: &v}
+}
+
+func (p *tList) ElemType() TType {
+  return p.elemType
+}
+
+func (p *tList) Len() int {
+  return p.l.Len()
+}
+
+func (p *tList) At(i int) interface{} {
+  return p.l.At(i)
+}
+
+func (p *tList) Set(i int, data interface{}) {
+  if p.elemType.IsEmptyType() {
+    p.elemType = TypeFromValue(data)
+  }
+  if data, ok := p.elemType.CoerceData(data); ok {
+    p.l.Set(i, data)
+  }
+}
+
+func (p *tList) Push(data interface{}) {
+  if p.elemType.IsEmptyType() {
+    p.elemType = TypeFromValue(data)
+  }
+  data, ok := p.elemType.CoerceData(data)
+  if ok {
+    p.l.Push(data)
+  }
+}
+
+func (p *tList) Pop() interface{} {
+  return p.l.Pop()
+}
+
+func (p *tList) Swap(i, j int) {
+  p.l.Swap(i, j)
+}
+
+func (p *tList) Insert(i int, data interface{}) {
+  p.l.Insert(i, data)
+}
+
+func (p *tList) Delete(i int) {
+  p.l.Delete(i)
+}
+
+func (p *tList) Contains(data interface{}) bool {
+  return p.indexOf(data) >= 0
+}
+
+func (p *tList) Less(i, j int) bool {
+  return p.l.Less(i, j)
+}
+
+func (p *tList) Iter() <-chan interface{} {
+  c := make(chan interface{})
+  go p.iterate(c)
+  return c
+}
+
+func (p *tList) iterate(c chan<- interface{}) {
+  for _, elem := range *p.l {
+    c <- elem
+  }
+  close(c)
+}
+
+func (p *tList) indexOf(data interface{}) int {
+  if data == nil {
+    size := p.l.Len()
+    for i := 0; i < size; i++ {
+      if p.l.At(i) == nil {
+        return i
+      }
+    }
+    return -1
+  }
+  data, ok := p.elemType.CoerceData(data)
+  if data == nil || !ok {
+    return -1
+  }
+  size := p.l.Len()
+  if p.elemType.IsBaseType() || p.elemType.IsEnum() {
+    for i := 0; i < size; i++ {
+      if data == p.l.At(i) {
+        return i
+      }
+    }
+    return -1
+  }
+  if cmp, ok := data.(EqualsOtherInterface); ok {
+    for i := 0; i < size; i++ {
+      if cmp.Equals(p.l.At(i)) {
+        return i
+      }
+    }
+    return -1
+  }
+  switch p.elemType {
+  case MAP:
+    if cmp, ok := data.(EqualsMap); ok {
+      for i := 0; i < size; i++ {
+        v := p.l.At(i)
+        if v == nil {
+          continue
+        }
+        if cmp.Equals(v.(TMap)) {
+          return i
+        }
+      }
+      return -1
+    }
+  case SET:
+    if cmp, ok := data.(EqualsSet); ok {
+      for i := 0; i < size; i++ {
+        v := p.l.At(i)
+        if v == nil {
+          continue
+        }
+        if cmp.Equals(v.(TSet)) {
+          return i
+        }
+      }
+      return -1
+    }
+  case LIST:
+    if cmp, ok := data.(EqualsList); ok {
+      for i := 0; i < size; i++ {
+        v := p.l.At(i)
+        if v == nil {
+          continue
+        }
+        if cmp.Equals(v.(TList)) {
+          return i
+        }
+      }
+      return -1
+    }
+  case STRUCT:
+    if cmp, ok := data.(EqualsStruct); ok {
+      for i := 0; i < size; i++ {
+        v := p.l.At(i)
+        if v == nil {
+          continue
+        }
+        if cmp.Equals(v.(TStruct)) {
+          return i
+        }
+      }
+      return -1
+    }
+  }
+  return -1
+}
+
+func (p *tList) Equals(other interface{}) bool {
+  c, cok := p.CompareTo(other)
+  return cok && c == 0
+}
+
+func (p *tList) CompareTo(other interface{}) (int, bool) {
+  return TType(LIST).Compare(p, other)
+}
diff --git a/lib/go/thrift/tmap.go b/lib/go/thrift/tmap.go
new file mode 100644
index 0000000..d042f05
--- /dev/null
+++ b/lib/go/thrift/tmap.go
@@ -0,0 +1,763 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "container/list"
+  "reflect"
+)
+
+/**
+ * Helper class that encapsulates map metadata.
+ *
+ */
+type TMap interface {
+  KeyType() TType
+  ValueType() TType
+  Len() int
+  Set(key, value interface{})
+  Get(key interface{}) (interface{}, bool)
+  Contains(key interface{}) bool
+  Iter() <-chan TMapElem
+  KeyIter() <-chan interface{}
+  ValueIter() <-chan interface{}
+  Keys() []interface{}
+  Values() []interface{}
+  Less(other interface{}) bool
+  Equals(other interface{}) bool
+  CompareTo(other interface{}) (int, bool)
+}
+
+type TMapElem interface {
+  Key() interface{}
+  Value() interface{}
+}
+
+type tMap struct {
+  keyType   TType
+  valueType TType
+  size      int
+  l         *list.List
+  b         map[bool]interface{}
+  i08       map[byte]interface{}
+  i16       map[int16]interface{}
+  i32       map[int32]interface{}
+  i64       map[int64]interface{}
+  f64       map[float64]interface{}
+  s         map[string]interface{}
+}
+
+type tMapElem struct {
+  key   interface{}
+  value interface{}
+}
+
+func (p *tMapElem) Key() interface{} {
+  return p.key
+}
+
+func (p *tMapElem) Value() interface{} {
+  return p.value
+}
+
+func NewTMapElem(k, v interface{}) TMapElem {
+  return &tMapElem{key: k, value: v}
+}
+
+func NewTMap(k, v TType, s int) TMap {
+  return &tMap{keyType: k, valueType: v, size: s, l: list.New()}
+}
+
+func NewTMapDefault() TMap {
+  return NewTMap(STOP, STOP, 0)
+}
+
+func (p *tMap) KeyType() TType {
+  return p.keyType
+}
+
+func (p *tMap) ValueType() TType {
+  return p.valueType
+}
+
+func (p *tMap) Len() int {
+  if p.l.Len() != 0 {
+    return p.l.Len()
+  }
+  switch p.KeyType() {
+  case STOP, VOID:
+    return 0
+  case BOOL:
+    return len(p.b)
+  case BYTE:
+    return len(p.i08)
+  case I16:
+    return len(p.i16)
+  case I32:
+    return len(p.i32)
+  case I64:
+    return len(p.i64)
+  case DOUBLE:
+    return len(p.f64)
+  case STRING, UTF8, UTF16:
+    return len(p.s)
+  default:
+    return p.size
+  }
+  return p.size
+}
+
+func (p *tMap) Get(key interface{}) (interface{}, bool) {
+  if p.KeyType().IsEmptyType() {
+    return nil, false
+  }
+  if key == nil {
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        return e.Value(), true
+      }
+    }
+    return nil, false
+  }
+  useKey, ok := p.KeyType().CoerceData(key)
+  if !ok {
+    return nil, false
+  }
+  switch p.KeyType() {
+  case STOP, VOID:
+    // if here, then we don't have a key type yet and key is not nil
+    // so this is pretty much an empty map
+    return nil, false
+  case BOOL:
+    m := p.b
+    if m == nil {
+      return nil, false
+    }
+    if v, ok := m[useKey.(bool)]; ok {
+      return v, true
+    }
+    return nil, true
+  case BYTE:
+    m := p.i08
+    if v, ok := m[useKey.(byte)]; ok {
+      return v, true
+    }
+    return nil, false
+  case DOUBLE:
+    m := p.f64
+    if m == nil {
+      return nil, false
+    }
+    if v, ok := m[useKey.(float64)]; ok {
+      return v, true
+    }
+    return nil, false
+  case I16:
+    m := p.i16
+    if m == nil {
+      return nil, false
+    }
+    if v, ok := m[useKey.(int16)]; ok {
+      return v, true
+    }
+    return nil, false
+  case I32:
+    m := p.i32
+    if m == nil {
+      return nil, false
+    }
+    if v, ok := m[useKey.(int32)]; ok {
+      return v, true
+    }
+    return nil, false
+  case I64:
+    m := p.i64
+    if m == nil {
+      return nil, false
+    }
+    if v, ok := m[useKey.(int64)]; ok {
+      return v, true
+    }
+    return nil, false
+  case STRING, UTF8, UTF16:
+    // TODO(pomack) properly handle ENUM
+    m := p.s
+    if m == nil {
+      return nil, false
+    }
+    if v, ok := m[useKey.(string)]; ok {
+      return v, true
+    }
+    return nil, false
+  case STRUCT:
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        continue
+      }
+      structkey, ok := k.(TStruct)
+      if ok {
+        if structkey.Equals(useKey.(TStruct)) {
+          return e.Value(), true
+        }
+        continue
+      }
+      if reflect.DeepEqual(useKey, k) {
+        return e.Value(), true
+      }
+    }
+    return nil, false
+  case MAP:
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        continue
+      }
+      mapkey, ok := k.(TMap)
+      if ok {
+        if mapkey.Equals(useKey.(TMap)) {
+          return e.Value(), true
+        }
+        continue
+      }
+      if reflect.DeepEqual(useKey, k) {
+        return e.Value(), true
+      }
+    }
+    return nil, false
+  case SET:
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        continue
+      }
+      setkey, ok := k.(TSet)
+      if ok {
+        if setkey.Equals(useKey.(TSet)) {
+          return e.Value(), true
+        }
+        continue
+      }
+      if reflect.DeepEqual(useKey, k) {
+        return e.Value(), true
+      }
+    }
+    return nil, false
+  case LIST:
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        continue
+      }
+      listkey, ok := k.(TList)
+      if ok {
+        if listkey.Equals(useKey.(TList)) {
+          return e.Value(), true
+        }
+        continue
+      }
+      if reflect.DeepEqual(useKey, k) {
+        return e.Value(), true
+      }
+    }
+    return nil, false
+  default:
+    panic("Invalid Thrift element type")
+  }
+  return nil, false
+}
+
+
+func (p *tMap) Set(key, value interface{}) {
+  if p.KeyType() == STOP || p.KeyType() == VOID {
+    p.keyType = TypeFromValue(key)
+  }
+  coercedKey, ok := p.KeyType().CoerceData(key)
+  if !ok {
+    return
+  }
+  if p.ValueType() == STOP || p.ValueType() == VOID {
+    p.valueType = TypeFromValue(value)
+  }
+  coercedValue, ok := p.ValueType().CoerceData(value)
+  if !ok {
+    return
+  }
+  newElem := NewTMapElem(coercedKey, coercedValue)
+  if !p.KeyType().IsBaseType() {
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      k := elem.Value.(TMapElem).Key()
+      if cmp, ok := p.KeyType().Compare(coercedKey, k); ok && cmp >= 0 {
+        if cmp == 0 {
+          p.l.InsertAfter(newElem, elem)
+          p.l.Remove(elem)
+          return
+        }
+        p.l.InsertBefore(newElem, elem)
+        return
+      }
+    }
+    p.l.PushBack(newElem)
+    return
+  }
+  if key == nil {
+    return
+  }
+  switch p.KeyType() {
+  case STOP, VOID:
+    // if here, then we don't have a key type yet and key is not nil
+    // so this is pretty much an empty map
+    return
+  case BOOL:
+    if p.b == nil {
+      p.b = make(map[bool]interface{})
+    }
+    b := coercedKey.(bool)
+    p.b[b] = value
+  case BYTE:
+    if p.i08 == nil {
+      p.i08 = make(map[byte]interface{})
+    }
+    b := coercedKey.(byte)
+    p.i08[b] = value
+  case DOUBLE:
+    if p.f64 == nil {
+      p.f64 = make(map[float64]interface{})
+    }
+    b := coercedKey.(float64)
+    p.f64[b] = value
+  case I16:
+    if p.i16 == nil {
+      p.i16 = make(map[int16]interface{})
+    }
+    b := coercedKey.(int16)
+    p.i16[b] = value
+  case I32:
+    if p.i32 == nil {
+      p.i32 = make(map[int32]interface{})
+    }
+    b := coercedKey.(int32)
+    p.i32[b] = value
+  case I64:
+    if p.i64 == nil {
+      p.i64 = make(map[int64]interface{})
+    }
+    b := coercedKey.(int64)
+    p.i64[b] = value
+  case STRING, UTF8, UTF16:
+    if p.s == nil {
+      p.s = make(map[string]interface{})
+    }
+    b := coercedKey.(string)
+    p.s[b] = value
+  case STRUCT, MAP, SET, LIST:
+    panic("Should never be here")
+  default:
+    panic("Should never be here")
+  }
+}
+
+func (p *tMap) Contains(key interface{}) bool {
+  coercedKey, ok := p.KeyType().CoerceData(key)
+  if !ok {
+    return false
+  }
+  if coercedKey == nil {
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      k := elem.Value.(TMapElem).Key()
+      if k == nil {
+        return true
+      }
+    }
+    return false
+  }
+  if !ok {
+    return false
+  }
+  switch p.KeyType() {
+  case STOP:
+    // if here, then we don't have a key type yet and key is not nil
+    // so this is pretty much an empty map
+    return false
+  case VOID:
+    // if here, then we don't have a key type yet and key is not nil
+    // so this is pretty much an empty map
+    return false
+  case BOOL:
+    m := p.b
+    if m == nil {
+      return false
+    }
+    _, ok := m[coercedKey.(bool)]
+    return ok
+  case BYTE:
+    m := p.i08
+    _, ok := m[coercedKey.(byte)]
+    return ok
+  case DOUBLE:
+    m := p.f64
+    if m == nil {
+      return false
+    }
+    _, ok := m[coercedKey.(float64)]
+    return ok
+  case I16:
+    m := p.i16
+    if m == nil {
+      return false
+    }
+    _, ok := m[coercedKey.(int16)]
+    return ok
+  case I32:
+    m := p.i32
+    if m == nil {
+      return false
+    }
+    _, ok := m[coercedKey.(int32)]
+    return ok
+  case I64:
+    m := p.i64
+    if m == nil {
+      return false
+    }
+    _, ok := m[coercedKey.(int64)]
+    return ok
+  case STRING, UTF8, UTF16:
+    // TODO(pomack) properly handle ENUM
+    m := p.s
+    if m == nil {
+      return false
+    }
+    _, ok := m[coercedKey.(string)]
+    return ok
+  case STRUCT:
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        continue
+      }
+      structkey, ok := k.(TStruct)
+      if ok {
+        if structkey.Equals(coercedKey.(TStruct)) {
+          return true
+        }
+        continue
+      }
+      if reflect.DeepEqual(coercedKey, k) {
+        return true
+      }
+    }
+    return false
+  case MAP:
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        continue
+      }
+      mapkey, ok := k.(TMap)
+      if ok {
+        if mapkey.Equals(coercedKey.(TMap)) {
+          return true
+        }
+        continue
+      }
+    }
+    return false
+  case SET:
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        continue
+      }
+      setkey, ok := k.(TSet)
+      if ok {
+        if setkey.Equals(coercedKey.(TSet)) {
+          return true
+        }
+        continue
+      }
+    }
+    return false
+  case LIST:
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      e := elem.Value.(TMapElem)
+      k := e.Key()
+      if k == nil {
+        continue
+      }
+      listkey, ok := k.(TList)
+      if ok {
+        if listkey.Equals(coercedKey.(TList)) {
+          return true
+        }
+        continue
+      }
+    }
+    return false
+  default:
+    panic("Invalid Thrift element type")
+  }
+  return false
+}
+
+// Iterate over all elements; driver for range
+func (p *tMap) iterate(c chan<- TMapElem) {
+  switch p.KeyType() {
+  case STOP, VOID:
+    close(c)
+  case BOOL:
+    for k, v := range p.b {
+      c <- NewTMapElem(k, v)
+    }
+    close(c)
+  case BYTE:
+    for k, v := range p.i08 {
+      c <- NewTMapElem(k, v)
+    }
+    close(c)
+  case I16:
+    for k, v := range p.i16 {
+      c <- NewTMapElem(k, v)
+    }
+    close(c)
+  case I32:
+    for k, v := range p.i32 {
+      c <- NewTMapElem(k, v)
+    }
+    close(c)
+  case I64:
+    for k, v := range p.i64 {
+      c <- NewTMapElem(k, v)
+    }
+    close(c)
+  case DOUBLE:
+    for k, v := range p.f64 {
+      c <- NewTMapElem(k, v)
+    }
+    close(c)
+  case STRING, UTF8, UTF16:
+    for k, v := range p.s {
+      c <- NewTMapElem(k, v)
+    }
+    close(c)
+  case STRUCT:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem)
+    }
+    close(c)
+  case LIST:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem)
+    }
+    close(c)
+  case SET:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem)
+    }
+    close(c)
+  default:
+    panic("Invalid Thrift type")
+  }
+}
+
+// Channel iterator for range.
+func (p *tMap) Iter() <-chan TMapElem {
+  c := make(chan TMapElem)
+  go p.iterate(c)
+  return c
+}
+
+// Iterate over all keys; driver for range
+func (p *tMap) iterateKeys(c chan<- interface{}) {
+  switch p.KeyType() {
+  case STOP, VOID:
+    close(c)
+  case BOOL:
+    for k, _ := range p.b {
+      c <- k
+    }
+    close(c)
+  case BYTE:
+    for k, _ := range p.i08 {
+      c <- k
+    }
+    close(c)
+  case I16:
+    for k, _ := range p.i16 {
+      c <- k
+    }
+    close(c)
+  case I32:
+    for k, _ := range p.i32 {
+      c <- k
+    }
+    close(c)
+  case I64:
+    for k, _ := range p.i64 {
+      c <- k
+    }
+    close(c)
+  case DOUBLE:
+    for k, _ := range p.f64 {
+      c <- k
+    }
+    close(c)
+  case STRING, UTF8, UTF16:
+    for k, _ := range p.s {
+      c <- k
+    }
+    close(c)
+  case STRUCT:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem).Key()
+    }
+    close(c)
+  case LIST:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem).Key()
+    }
+    close(c)
+  case SET:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem).Key()
+    }
+    close(c)
+  default:
+    panic("Invalid Thrift type")
+  }
+}
+
+func (p *tMap) KeyIter() <-chan interface{} {
+  c := make(chan interface{})
+  go p.iterateKeys(c)
+  return c
+}
+
+// Iterate over all values; driver for range
+func (p *tMap) iterateValues(c chan<- interface{}) {
+  switch p.KeyType() {
+  case STOP, VOID:
+    close(c)
+  case BOOL:
+    for _, v := range p.b {
+      c <- v
+    }
+    close(c)
+  case BYTE:
+    for _, v := range p.i08 {
+      c <- v
+    }
+    close(c)
+  case I16:
+    for _, v := range p.i16 {
+      c <- v
+    }
+    close(c)
+  case I32:
+    for _, v := range p.i32 {
+      c <- v
+    }
+    close(c)
+  case I64:
+    for _, v := range p.i64 {
+      c <- v
+    }
+    close(c)
+  case DOUBLE:
+    for _, v := range p.f64 {
+      c <- v
+    }
+    close(c)
+  case STRING, UTF8, UTF16:
+    for _, v := range p.s {
+      c <- v
+    }
+    close(c)
+  case STRUCT:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem).Value()
+    }
+    close(c)
+  case LIST:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem).Value()
+    }
+    close(c)
+  case SET:
+    for v := p.l.Front(); v != nil; v = v.Next() {
+      c <- v.Value.(TMapElem).Value()
+    }
+    close(c)
+  default:
+    panic("Invalid Thrift type")
+  }
+}
+
+func (p *tMap) ValueIter() <-chan interface{} {
+  c := make(chan interface{})
+  go p.iterateValues(c)
+  return c
+}
+
+
+func (p *tMap) Less(other interface{}) bool {
+  cmp, ok := p.CompareTo(other)
+  return ok && cmp > 0
+}
+
+func (p *tMap) Equals(other interface{}) bool {
+  c, cok := p.CompareTo(other)
+  return cok && c == 0
+}
+
+func (p *tMap) CompareTo(other interface{}) (int, bool) {
+  return TType(MAP).Compare(p, other)
+}
+
+func (p *tMap) Keys() []interface{} {
+  size := p.Len()
+  values := make([]interface{}, size, size)
+  i := 0
+  for k := range p.KeyIter() {
+    values[i] = k
+    i++
+  }
+  return values
+}
+
+func (p *tMap) Values() []interface{} {
+  size := p.Len()
+  values := make([]interface{}, size, size)
+  i := 0
+  for v := range p.ValueIter() {
+    values[i] = v
+    i++
+  }
+  return values
+}
diff --git a/lib/go/thrift/tmemory_buffer.go b/lib/go/thrift/tmemory_buffer.go
new file mode 100644
index 0000000..69b794e
--- /dev/null
+++ b/lib/go/thrift/tmemory_buffer.go
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "bytes"
+  "io"
+  "os"
+)
+
+/**
+ * Memory buffer-based implementation of the TTransport interface.
+ *
+ */
+type TMemoryBuffer struct {
+  buf  *bytes.Buffer
+  size int
+}
+
+type TMemoryBufferTransportFactory struct {
+  size int
+}
+
+func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) TTransport {
+  if trans != nil {
+    t, ok := trans.(*TMemoryBuffer)
+    if ok && t.size > 0 {
+      return NewTMemoryBufferLen(t.size)
+    }
+  }
+  return NewTMemoryBufferLen(p.size)
+}
+
+func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory {
+  return &TMemoryBufferTransportFactory{size: size}
+}
+
+func NewTMemoryBuffer() *TMemoryBuffer {
+  return &TMemoryBuffer{buf: &bytes.Buffer{}, size: 0}
+}
+
+func NewTMemoryBufferLen(size int) *TMemoryBuffer {
+  buf := make([]byte, 0, size)
+  return &TMemoryBuffer{buf: bytes.NewBuffer(buf), size: size}
+}
+
+func (p *TMemoryBuffer) IsOpen() bool {
+  return true
+}
+
+func (p *TMemoryBuffer) Open() os.Error {
+  return nil
+}
+
+func (p *TMemoryBuffer) Peek() bool {
+  return p.IsOpen()
+}
+
+func (p *TMemoryBuffer) Close() os.Error {
+  p.buf.Reset()
+  return nil
+}
+
+func (p *TMemoryBuffer) Read(buf []byte) (int, os.Error) {
+  return p.buf.Read(buf)
+}
+
+func (p *TMemoryBuffer) ReadAll(buf []byte) (int, os.Error) {
+  return ReadAllTransport(p, buf)
+}
+
+func (p *TMemoryBuffer) ReadByte() (byte, os.Error) {
+  return p.buf.ReadByte()
+}
+
+func (p *TMemoryBuffer) ReadFrom(r io.Reader) (int64, os.Error) {
+  return p.buf.ReadFrom(r)
+}
+
+func (p *TMemoryBuffer) Write(buf []byte) (int, os.Error) {
+  return p.buf.Write(buf)
+}
+
+func (p *TMemoryBuffer) WriteString(buf string) (int, os.Error) {
+  return p.buf.WriteString(buf)
+}
+
+func (p *TMemoryBuffer) WriteTo(w io.Writer) (int64, os.Error) {
+  return p.buf.WriteTo(w)
+}
+
+func (p *TMemoryBuffer) Flush() os.Error {
+  return nil
+}
+
+func (p *TMemoryBuffer) Reset() {
+  p.buf.Reset()
+}
+
+func (p *TMemoryBuffer) Bytes() []byte {
+  return p.buf.Bytes()
+}
+
+func (p *TMemoryBuffer) Len() int {
+  return p.buf.Len()
+}
+
+func (p *TMemoryBuffer) String() string {
+  return p.buf.String()
+}
diff --git a/lib/go/thrift/tmemory_buffer_test.go b/lib/go/thrift/tmemory_buffer_test.go
new file mode 100644
index 0000000..5d17864
--- /dev/null
+++ b/lib/go/thrift/tmemory_buffer_test.go
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+)
+
+func TestMemoryBuffer(t *testing.T) {
+  trans := NewTMemoryBufferLen(1024)
+  TransportTest(t, trans, trans)
+}
diff --git a/lib/go/thrift/tmessage.go b/lib/go/thrift/tmessage.go
new file mode 100644
index 0000000..c768cb4
--- /dev/null
+++ b/lib/go/thrift/tmessage.go
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * Helper class that encapsulates struct metadata.
+ *
+ */
+type TMessage interface {
+  Name() string
+  TypeId() TMessageType
+  SeqId() int
+  Equals(other TMessage) bool
+}
+type tMessage struct {
+  name   string
+  typeId TMessageType
+  seqid  int
+}
+
+func NewTMessageDefault() TMessage {
+  return NewTMessage("", STOP, 0)
+}
+
+func NewTMessage(n string, t TMessageType, s int) TMessage {
+  return &tMessage{name: n, typeId: t, seqid: s}
+}
+
+func (p *tMessage) Name() string {
+  return p.name
+}
+
+func (p *tMessage) TypeId() TMessageType {
+  return p.typeId
+}
+
+func (p *tMessage) SeqId() int {
+  return p.seqid
+}
+
+func (p *tMessage) String() string {
+  return "<TMessage name:'" + p.name + "' type: " + string(p.typeId) + " seqid:" + string(p.seqid) + ">"
+}
+
+func (p *tMessage) Equals(other TMessage) bool {
+  return p.name == other.Name() && p.typeId == other.TypeId() && p.seqid == other.SeqId()
+}
+
+var EMPTY_MESSAGE TMessage
+
+func init() {
+  EMPTY_MESSAGE = NewTMessageDefault()
+}
diff --git a/lib/go/thrift/tmessagetype.go b/lib/go/thrift/tmessagetype.go
new file mode 100644
index 0000000..b31c66c
--- /dev/null
+++ b/lib/go/thrift/tmessagetype.go
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * Message type constants in the Thrift protocol.
+ *
+ */
+type TMessageType int32
+
+const (
+  INVALID_TMESSAGE_TYPE TMessageType = 0
+  CALL                  TMessageType = 1
+  REPLY                 TMessageType = 2
+  EXCEPTION             TMessageType = 3
+  ONEWAY                TMessageType = 4
+)
diff --git a/lib/go/thrift/tnonblocking_server.go b/lib/go/thrift/tnonblocking_server.go
new file mode 100644
index 0000000..e234c5a
--- /dev/null
+++ b/lib/go/thrift/tnonblocking_server.go
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "os"
+)
+
+/**
+ * A nonblocking TServer implementation. This allows for fairness amongst all
+ * connected clients in terms of invocations.
+ *
+ * This server is inherently single-threaded. If you want a limited thread pool
+ * coupled with invocation-fairness, see THsHaServer.
+ *
+ * To use this server, you MUST use a TFramedTransport at the outermost
+ * transport, otherwise this server will be unable to determine when a whole
+ * method call has been read off the wire. Clients must also use TFramedTransport.
+ */
+type TNonblockingServer struct {
+  /** Flag for stopping the server */
+  stopped bool
+
+  processorFactory       TProcessorFactory
+  serverTransport        TServerTransport
+  inputTransportFactory  TTransportFactory
+  outputTransportFactory TTransportFactory
+  inputProtocolFactory   TProtocolFactory
+  outputProtocolFactory  TProtocolFactory
+}
+
+
+func NewTNonblockingServer2(processor TProcessor, serverTransport TServerTransport) *TNonblockingServer {
+  return NewTNonblockingServerFactory2(NewTProcessorFactory(processor), serverTransport)
+}
+
+func NewTNonblockingServer4(processor TProcessor, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TNonblockingServer {
+  return NewTNonblockingServerFactory4(NewTProcessorFactory(processor),
+    serverTransport,
+    transportFactory,
+    protocolFactory,
+  )
+}
+
+func NewTNonblockingServer6(processor TProcessor, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TNonblockingServer {
+  return NewTNonblockingServerFactory6(NewTProcessorFactory(processor),
+    serverTransport,
+    inputTransportFactory,
+    outputTransportFactory,
+    inputProtocolFactory,
+    outputProtocolFactory,
+  )
+}
+
+func NewTNonblockingServerFactory2(processorFactory TProcessorFactory, serverTransport TServerTransport) *TNonblockingServer {
+  return NewTNonblockingServerFactory6(processorFactory,
+    serverTransport,
+    NewTTransportFactory(),
+    NewTTransportFactory(),
+    NewTBinaryProtocolFactoryDefault(),
+    NewTBinaryProtocolFactoryDefault(),
+  )
+}
+
+func NewTNonblockingServerFactory4(processorFactory TProcessorFactory, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TNonblockingServer {
+  return NewTNonblockingServerFactory6(processorFactory,
+    serverTransport,
+    transportFactory,
+    transportFactory,
+    protocolFactory,
+    protocolFactory,
+  )
+}
+
+func NewTNonblockingServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TNonblockingServer {
+  return &TNonblockingServer{processorFactory: processorFactory,
+    serverTransport:        serverTransport,
+    inputTransportFactory:  inputTransportFactory,
+    outputTransportFactory: outputTransportFactory,
+    inputProtocolFactory:   inputProtocolFactory,
+    outputProtocolFactory:  outputProtocolFactory,
+  }
+}
+
+func (p *TNonblockingServer) ProcessorFactory() TProcessorFactory {
+  return p.processorFactory
+}
+
+func (p *TNonblockingServer) ServerTransport() TServerTransport {
+  return p.serverTransport
+}
+
+func (p *TNonblockingServer) InputTransportFactory() TTransportFactory {
+  return p.inputTransportFactory
+}
+
+func (p *TNonblockingServer) OutputTransportFactory() TTransportFactory {
+  return p.outputTransportFactory
+}
+
+func (p *TNonblockingServer) InputProtocolFactory() TProtocolFactory {
+  return p.inputProtocolFactory
+}
+
+func (p *TNonblockingServer) OutputProtocolFactory() TProtocolFactory {
+  return p.outputProtocolFactory
+}
+
+func (p *TNonblockingServer) Serve() os.Error {
+  p.stopped = false
+  err := p.serverTransport.Listen()
+  if err != nil {
+    return err
+  }
+  for !p.stopped {
+    client, err := p.serverTransport.Accept()
+    if err != nil {
+      return err
+    }
+    if client != nil {
+      go p.processRequest(client)
+    }
+  }
+  return nil
+}
+
+func (p *TNonblockingServer) Stop() os.Error {
+  p.stopped = true
+  p.serverTransport.Interrupt()
+  return nil
+}
+
+func (p *TNonblockingServer) IsStopped() bool {
+  return p.stopped
+}
+
+func (p *TNonblockingServer) processRequest(client TTransport) {
+  processor := p.processorFactory.GetProcessor(client)
+  inputTransport := p.inputTransportFactory.GetTransport(client)
+  outputTransport := p.outputTransportFactory.GetTransport(client)
+  inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport)
+  outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport)
+  if inputTransport != nil {
+    defer inputTransport.Close()
+  }
+  if outputTransport != nil {
+    defer outputTransport.Close()
+  }
+  for {
+    ok, e := processor.Process(inputProtocol, outputProtocol)
+    if e != nil {
+      if !p.stopped {
+        // TODO(pomack) log error
+        break
+      }
+    }
+    if !ok {
+      break
+    }
+  }
+}
diff --git a/lib/go/thrift/tnonblocking_server_socket.go b/lib/go/thrift/tnonblocking_server_socket.go
new file mode 100644
index 0000000..3c9dbaa
--- /dev/null
+++ b/lib/go/thrift/tnonblocking_server_socket.go
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "net"
+  "os"
+)
+
+/**
+ * Socket implementation of the TTransport interface. To be commented soon!
+ */
+type TNonblockingServerSocket struct {
+  listener net.Listener
+  addr     net.Addr
+  /**
+   * Socket timeout
+   */
+  nsecTimeout int64
+}
+
+type TNonblockingServerSocketTransportFactory struct {
+  addr net.Addr
+}
+
+func (p *TNonblockingServerSocketTransportFactory) GetTransport(trans TTransport) TTransport {
+  if trans != nil {
+    t, ok := trans.(*TNonblockingServerSocket)
+    if ok && t.addr != nil {
+      s, _ := NewTNonblockingServerSocketAddr(t.addr)
+      s.SetTimeout(t.nsecTimeout)
+      return s
+    }
+  }
+  s, _ := NewTNonblockingServerSocketAddr(p.addr)
+  return s
+}
+
+func NewTNonblockingServerSocketTransportFactory(addr net.Addr) *TNonblockingServerSocketTransportFactory {
+  return &TNonblockingServerSocketTransportFactory{addr: addr}
+}
+
+
+func NewTNonblockingServerSocketListener(listener net.Listener) (*TNonblockingServerSocket, TTransportException) {
+  s := &TNonblockingServerSocket{listener: listener, addr: listener.Addr()}
+  return s, nil
+}
+
+func NewTNonblockingServerSocketAddr(addr net.Addr) (*TNonblockingServerSocket, TTransportException) {
+  s := &TNonblockingServerSocket{addr: addr}
+  return s, nil
+}
+
+func (p *TNonblockingServerSocket) Listen() os.Error {
+  return p.Open()
+}
+
+/**
+ * Sets the socket timeout
+ *
+ * @param timeout Nanoseconds timeout
+ */
+func (p *TNonblockingServerSocket) SetTimeout(nsecTimeout int64) os.Error {
+  p.nsecTimeout = nsecTimeout
+  return nil
+}
+
+/**
+ * Checks whether the socket is connected.
+ */
+func (p *TNonblockingServerSocket) IsOpen() bool {
+  return p.listener != nil
+}
+
+/**
+ * Connects the socket, creating a new socket object if necessary.
+ */
+func (p *TNonblockingServerSocket) Open() os.Error {
+  if !p.IsOpen() {
+    l, err := net.Listen(p.addr.Network(), p.addr.String())
+    if err != nil {
+      return err
+    }
+    p.listener = l
+    return nil
+  }
+  return NewTTransportException(ALREADY_OPEN, "Server socket already open")
+}
+
+/**
+ * Perform a nonblocking read into buffer.
+ */
+func (p *TNonblockingServerSocket) Read(buf []byte) (int, os.Error) {
+  return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TNonblockingServerSocket.Read([]byte) is not implemented")
+}
+
+func (p *TNonblockingServerSocket) ReadAll(buf []byte) (int, os.Error) {
+  return ReadAllTransport(p, buf)
+}
+
+/**
+ * Perform a nonblocking write of the data in buffer;
+ */
+func (p *TNonblockingServerSocket) Write(buf []byte) (int, os.Error) {
+  return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TNonblockingServerSocket.Write([]byte) is not implemented")
+}
+
+/**
+ * Flushes the underlying output stream if not null.
+ */
+func (p *TNonblockingServerSocket) Flush() os.Error {
+  return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TNonblockingServerSocket.Flush() is not implemented")
+}
+
+func (p *TNonblockingServerSocket) Addr() net.Addr {
+  return p.addr
+}
+
+func (p *TNonblockingServerSocket) Accept() (TTransport, os.Error) {
+  if !p.IsOpen() {
+    return nil, NewTTransportException(NOT_OPEN, "No underlying server socket")
+  }
+  conn, err := p.listener.Accept()
+  if err != nil {
+    return nil, NewTTransportExceptionFromOsError(err)
+  }
+  conn.SetTimeout(p.nsecTimeout)
+  return NewTSocketConn(conn)
+}
+
+func (p *TNonblockingServerSocket) Peek() bool {
+  return p.IsOpen()
+}
+
+/**
+ * Closes the socket.
+ */
+func (p *TNonblockingServerSocket) Close() (err os.Error) {
+  if p.IsOpen() {
+    err := p.listener.Close()
+    if err != nil {
+      return NewTTransportExceptionFromOsError(err)
+    }
+    p.listener = nil
+  }
+  return nil
+}
+
+func (p *TNonblockingServerSocket) Interrupt() os.Error {
+  // probably not right
+  return p.Close()
+}
diff --git a/lib/go/thrift/tnonblocking_socket.go b/lib/go/thrift/tnonblocking_socket.go
new file mode 100644
index 0000000..a1c0310
--- /dev/null
+++ b/lib/go/thrift/tnonblocking_socket.go
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "net"
+  "os"
+)
+
+/**
+ * Socket implementation of the TTransport interface. To be commented soon!
+ */
+type TNonblockingSocket struct {
+  conn net.Conn
+  addr net.Addr
+  /**
+   * Socket timeout
+   */
+  nsecTimeout int64
+}
+
+type TNonblockingSocketTransportFactory struct {
+  addr net.Addr
+}
+
+func (p *TNonblockingSocketTransportFactory) GetTransport(trans TTransport) TTransport {
+  if trans != nil {
+    t, ok := trans.(*TNonblockingSocket)
+    if ok {
+      s, _ := NewTNonblockingSocketAddr(t.addr)
+      s.SetTimeout(t.nsecTimeout)
+      return s
+    }
+  }
+  s, _ := NewTNonblockingSocketAddr(p.addr)
+  return s
+}
+
+func NewTNonblockingSocketTransportFactory(addr net.Addr) *TNonblockingSocketTransportFactory {
+  return &TNonblockingSocketTransportFactory{addr: addr}
+}
+
+func NewTNonblockingSocketConn(conn net.Conn) (*TNonblockingSocket, TTransportException) {
+  s := &TNonblockingSocket{conn: conn, addr: conn.RemoteAddr()}
+  return s, nil
+}
+
+func NewTNonblockingSocketAddr(addr net.Addr) (*TNonblockingSocket, TTransportException) {
+  s := &TNonblockingSocket{addr: addr}
+  return s, nil
+}
+
+/**
+ * Sets the socket timeout
+ *
+ * @param nsecTimeout Nanoseconds timeout
+ */
+func (p *TNonblockingSocket) SetTimeout(nsecTimeout int64) os.Error {
+  p.nsecTimeout = nsecTimeout
+  if p.IsOpen() {
+    if err := p.conn.SetTimeout(nsecTimeout); err != nil {
+      LOGGER.Print("Could not set socket timeout.", err)
+      return err
+    }
+  }
+  return nil
+}
+
+/**
+ * Checks whether the socket is connected.
+ */
+func (p *TNonblockingSocket) IsOpen() bool {
+  return p.conn != nil
+}
+
+/**
+ * Connects the socket, creating a new socket object if necessary.
+ */
+func (p *TNonblockingSocket) Open() os.Error {
+  if p.IsOpen() {
+    return NewTTransportException(ALREADY_OPEN, "Socket already connected.")
+  }
+  if p.addr == nil {
+    return NewTTransportException(NOT_OPEN, "Cannot open nil address.")
+  }
+  if len(p.addr.Network()) == 0 {
+    return NewTTransportException(NOT_OPEN, "Cannot open bad network name.")
+  }
+  if len(p.addr.String()) == 0 {
+    return NewTTransportException(NOT_OPEN, "Cannot open bad address.")
+  }
+
+  var err os.Error
+  if p.conn, err = net.Dial(p.addr.Network(), "", p.addr.String()); err != nil {
+    LOGGER.Print("Could not open socket", err.String())
+    return NewTTransportException(NOT_OPEN, err.String())
+  }
+  if p.conn != nil {
+    p.conn.SetTimeout(p.nsecTimeout)
+  }
+  return nil
+}
+
+/**
+ * Perform a nonblocking read into buffer.
+ */
+func (p *TNonblockingSocket) Read(buf []byte) (int, os.Error) {
+  if !p.IsOpen() {
+    return 0, NewTTransportException(NOT_OPEN, "Connection not open")
+  }
+  n, err := p.conn.Read(buf)
+  return n, NewTTransportExceptionFromOsError(err)
+}
+
+
+func (p *TNonblockingSocket) ReadAll(buf []byte) (int, os.Error) {
+  return ReadAllTransport(p, buf)
+}
+
+/**
+ * Perform a nonblocking write of the data in buffer;
+ */
+func (p *TNonblockingSocket) Write(buf []byte) (int, os.Error) {
+  if !p.IsOpen() {
+    return 0, NewTTransportException(NOT_OPEN, "Connection not open")
+  }
+  return p.conn.Write(buf)
+}
+
+/**
+ * Flushes the underlying output stream if not null.
+ */
+func (p *TNonblockingSocket) Flush() os.Error {
+  if !p.IsOpen() {
+    return NewTTransportException(NOT_OPEN, "Connection not open")
+  }
+  f, ok := p.conn.(Flusher)
+  if ok {
+    err := f.Flush()
+    if err != nil {
+      return NewTTransportExceptionFromOsError(err)
+    }
+  }
+  return nil
+}
+
+func (p *TNonblockingSocket) Addr() net.Addr {
+  return p.addr
+}
+
+func (p *TNonblockingSocket) Peek() bool {
+  return p.IsOpen()
+}
+
+/**
+ * Closes the socket.
+ */
+func (p *TNonblockingSocket) Close() os.Error {
+  if p.conn != nil {
+    if err := p.conn.Close(); err != nil {
+      LOGGER.Print("Could not close socket.", err.String())
+      return err
+    }
+    p.conn = nil
+  }
+  return nil
+}
+
+func (p *TNonblockingSocket) Interrupt() os.Error {
+  if !p.IsOpen() {
+    return nil
+  }
+  // TODO(pomack) fix Interrupt as it is probably not right
+  return p.Close()
+}
diff --git a/lib/go/thrift/tnonblocking_transport.go b/lib/go/thrift/tnonblocking_transport.go
new file mode 100644
index 0000000..da9c26d
--- /dev/null
+++ b/lib/go/thrift/tnonblocking_transport.go
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+type TNonblockingTransport interface {
+  TTransport
+}
diff --git a/lib/go/thrift/tnonblocking_transport_test.go b/lib/go/thrift/tnonblocking_transport_test.go
new file mode 100644
index 0000000..7d019db
--- /dev/null
+++ b/lib/go/thrift/tnonblocking_transport_test.go
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+  "net"
+)
+
+func TestNonblockingTransportServerToClient(t *testing.T) {
+
+  addr, err := FindAvailableTCPServerPort(40000)
+  if err != nil {
+    t.Fatalf("Unable to find available tcp port addr: %s", err)
+  }
+  trans1, err := NewTNonblockingServerSocketAddr(addr)
+  if err != nil {
+    t.Fatalf("Unable to setup server socket listener: %s", err)
+  }
+  trans1.Open()
+  trans2, err := NewTNonblockingSocketAddr(addr)
+  if err != nil {
+    t.Fatalf("Unable to setup client socket: %s", err)
+  }
+  trans1.SetTimeout(10)
+  trans2.SetTimeout(10)
+  err = trans2.Open()
+  if err != nil {
+    t.Fatalf("Unable to connect client to server: %s", err)
+  }
+  s, err := trans1.Accept()
+  if err != nil {
+    t.Fatalf("Unable to accept client connection from server: %s", err)
+  }
+  //s.SetTimeout(10)
+  TransportTest(t, NewTFramedTransport(s), NewTFramedTransport(trans2))
+  trans1.Close()
+}
+
+func TestNonblockingTransportClientToServer(t *testing.T) {
+  addr, err := FindAvailableTCPServerPort(40000)
+  if err != nil {
+    t.Fatalf("Unable to find available tcp port addr: %s", err)
+  }
+  l, err := net.Listen(addr.Network(), addr.String())
+  if err != nil {
+    t.Fatalf("Unable to setup listener: %s", err)
+  }
+  trans1, err := NewTNonblockingServerSocketListener(l)
+  if err != nil {
+    t.Fatalf("Unable to setup server socket listener: %s", err)
+  }
+  trans2, err := NewTNonblockingSocketAddr(l.Addr())
+  if err != nil {
+    t.Fatalf("Unable to setup client socket: %s", err)
+  }
+  trans1.SetTimeout(10)
+  trans2.SetTimeout(10)
+  err = trans2.Open()
+  if err != nil {
+    t.Fatalf("Unable to connect client to server: %s", err)
+  }
+  s, err := trans1.Accept()
+  if err != nil {
+    t.Fatalf("Unable to accept client connection from server: %s", err)
+  }
+  //s.SetTimeout(10)
+  TransportTest(t, NewTFramedTransport(trans2), NewTFramedTransport(s))
+  trans1.Close()
+}
diff --git a/lib/go/thrift/tnumeric.go b/lib/go/thrift/tnumeric.go
new file mode 100644
index 0000000..b1f6508
--- /dev/null
+++ b/lib/go/thrift/tnumeric.go
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package thrift
+
+import (
+  "math"
+  "strconv"
+)
+
+type Numeric interface {
+  Int64() int64
+  Int32() int32
+  Int16() int16
+  Byte() byte
+  Int() int
+  Float64() float64
+  Float32() float32
+  String() string
+  isNull() bool
+}
+
+type numeric struct {
+  iValue int64
+  dValue float64
+  sValue string
+  isNil  bool
+}
+
+var (
+  INFINITY          Numeric
+  NEGATIVE_INFINITY Numeric
+  NAN               Numeric
+  ZERO              Numeric
+  NUMERIC_NULL      Numeric
+)
+
+func NewNumericFromDouble(dValue float64) Numeric {
+  if math.IsInf(dValue, 1) {
+    return INFINITY
+  }
+  if math.IsInf(dValue, -1) {
+    return NEGATIVE_INFINITY
+  }
+  if math.IsNaN(dValue) {
+    return NAN
+  }
+  iValue := int64(dValue)
+  sValue := strconv.Ftoa64(dValue, 'g', 10)
+  isNil := false
+  return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil}
+}
+
+func NewNumericFromI64(iValue int64) Numeric {
+  dValue := float64(iValue)
+  sValue := string(iValue)
+  isNil := false
+  return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil}
+}
+
+func NewNumericFromI32(iValue int32) Numeric {
+  dValue := float64(iValue)
+  sValue := string(iValue)
+  isNil := false
+  return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil}
+}
+
+func NewNumericFromString(sValue string) Numeric {
+  if sValue == INFINITY.String() {
+    return INFINITY
+  }
+  if sValue == NEGATIVE_INFINITY.String() {
+    return NEGATIVE_INFINITY
+  }
+  if sValue == NAN.String() {
+    return NAN
+  }
+  iValue, _ := strconv.Atoi64(sValue)
+  dValue, _ := strconv.Atof64(sValue)
+  isNil := len(sValue) == 0
+  return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil}
+}
+
+func NewNumericFromJSONString(sValue string, isNull bool) Numeric {
+  if isNull {
+    return NewNullNumeric()
+  }
+  if sValue == JSON_INFINITY {
+    return INFINITY
+  }
+  if sValue == JSON_NEGATIVE_INFINITY {
+    return NEGATIVE_INFINITY
+  }
+  if sValue == JSON_NAN {
+    return NAN
+  }
+  iValue, _ := strconv.Atoi64(sValue)
+  dValue, _ := strconv.Atof64(sValue)
+  return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNull}
+}
+
+func NewNullNumeric() Numeric {
+  return &numeric{iValue: 0, dValue: 0.0, sValue: "", isNil: true}
+}
+
+func (p *numeric) Int64() int64 {
+  return p.iValue
+}
+
+func (p *numeric) Int32() int32 {
+  return int32(p.iValue)
+}
+
+func (p *numeric) Int16() int16 {
+  return int16(p.iValue)
+}
+
+func (p *numeric) Byte() byte {
+  return byte(p.iValue)
+}
+
+func (p *numeric) Int() int {
+  return int(p.iValue)
+}
+
+func (p *numeric) Float64() float64 {
+  return p.dValue
+}
+
+func (p *numeric) Float32() float32 {
+  return float32(p.dValue)
+}
+
+func (p *numeric) String() string {
+  return p.sValue
+}
+
+func (p *numeric) isNull() bool {
+  return p.isNil
+}
+
+func init() {
+  INFINITY = &numeric{iValue: 0, dValue: math.Inf(1), sValue: "Infinity", isNil: false}
+  NEGATIVE_INFINITY = &numeric{iValue: 0, dValue: math.Inf(-1), sValue: "-Infinity", isNil: false}
+  NAN = &numeric{iValue: 0, dValue: math.NaN(), sValue: "NaN", isNil: false}
+  ZERO = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: false}
+  NUMERIC_NULL = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: true}
+}
diff --git a/lib/go/thrift/tprocessor.go b/lib/go/thrift/tprocessor.go
new file mode 100644
index 0000000..d2bb5e4
--- /dev/null
+++ b/lib/go/thrift/tprocessor.go
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * A processor is a generic object which operates upon an input stream and
+ * writes to some output stream.
+ *
+ */
+type TProcessor interface {
+  Process(in, out TProtocol) (bool, TException)
+}
+
+type TProcessorFunction interface {
+  Process(seqId int32, in, out TProtocol) (bool, TException)
+}
diff --git a/lib/go/thrift/tprocessor_factory.go b/lib/go/thrift/tprocessor_factory.go
new file mode 100644
index 0000000..72681ab
--- /dev/null
+++ b/lib/go/thrift/tprocessor_factory.go
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+
+/**
+ * The default processor factory just returns a singleton
+ * instance.
+ */
+type TProcessorFactory interface {
+  GetProcessor(trans TTransport) TProcessor
+}
+
+type tProcessorFactory struct {
+  processor TProcessor
+}
+
+func NewTProcessorFactory(p TProcessor) TProcessorFactory {
+  return &tProcessorFactory{processor: p}
+}
+
+func (p *tProcessorFactory) GetProcessor(trans TTransport) TProcessor {
+  return p.processor
+}
+
+
+/**
+ * The default processor factory just returns a singleton
+ * instance.
+ */
+type TProcessorFunctionFactory interface {
+  GetProcessorFunction(trans TTransport) TProcessorFunction
+}
+
+type tProcessorFunctionFactory struct {
+  processor TProcessorFunction
+}
+
+func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactory {
+  return &tProcessorFunctionFactory{processor: p}
+}
+
+func (p *tProcessorFunctionFactory) GetProcessorFunction(trans TTransport) TProcessorFunction {
+  return p.processor
+}
diff --git a/lib/go/thrift/tprotocol.go b/lib/go/thrift/tprotocol.go
new file mode 100644
index 0000000..dcb27a8
--- /dev/null
+++ b/lib/go/thrift/tprotocol.go
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+
+const (
+  VERSION_MASK = 0xffff0000
+  VERSION_1    = 0x80010000
+)
+
+type EmptyInterface interface{}
+
+type TProtocol interface {
+  WriteMessageBegin(name string, typeId TMessageType, seqid int32) TProtocolException
+  WriteMessageEnd() TProtocolException
+  WriteStructBegin(name string) TProtocolException
+  WriteStructEnd() TProtocolException
+  WriteFieldBegin(name string, typeId TType, id int16) TProtocolException
+  WriteFieldEnd() TProtocolException
+  WriteFieldStop() TProtocolException
+  WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException
+  WriteMapEnd() TProtocolException
+  WriteListBegin(elemType TType, size int) TProtocolException
+  WriteListEnd() TProtocolException
+  WriteSetBegin(elemType TType, size int) TProtocolException
+  WriteSetEnd() TProtocolException
+  WriteBool(value bool) TProtocolException
+  WriteByte(value byte) TProtocolException
+  WriteI16(value int16) TProtocolException
+  WriteI32(value int32) TProtocolException
+  WriteI64(value int64) TProtocolException
+  WriteDouble(value float64) TProtocolException
+  WriteString(value string) TProtocolException
+  WriteBinary(value []byte) TProtocolException
+
+  ReadMessageBegin() (name string, typeId TMessageType, seqid int32, err TProtocolException)
+  ReadMessageEnd() TProtocolException
+  ReadStructBegin() (name string, err TProtocolException)
+  ReadStructEnd() TProtocolException
+  ReadFieldBegin() (name string, typeId TType, id int16, err TProtocolException)
+  ReadFieldEnd() TProtocolException
+  ReadMapBegin() (keyType TType, valueType TType, size int, err TProtocolException)
+  ReadMapEnd() TProtocolException
+  ReadListBegin() (elemType TType, size int, err TProtocolException)
+  ReadListEnd() TProtocolException
+  ReadSetBegin() (elemType TType, size int, err TProtocolException)
+  ReadSetEnd() TProtocolException
+  ReadBool() (value bool, err TProtocolException)
+  ReadByte() (value byte, err TProtocolException)
+  ReadI16() (value int16, err TProtocolException)
+  ReadI32() (value int32, err TProtocolException)
+  ReadI64() (value int64, err TProtocolException)
+  ReadDouble() (value float64, err TProtocolException)
+  ReadString() (value string, err TProtocolException)
+  ReadBinary() (value []byte, err TProtocolException)
+
+  Skip(fieldType TType) (err TProtocolException)
+  Flush() (err TProtocolException)
+
+  Transport() TTransport
+}
+
+/**
+ * The maximum recursive depth the skip() function will traverse before
+ * throwing a TException.
+ */
+var (
+  MaxSkipDepth = 1<<31 - 1
+)
+
+/**
+ * Specifies the maximum recursive depth that the skip function will
+ * traverse before throwing a TException.  This is a global setting, so
+ * any call to skip in this JVM will enforce this value.
+ *
+ * @param depth  the maximum recursive depth.  A value of 2 would allow
+ *    the skip function to skip a structure or collection with basic children,
+ *    but it would not permit skipping a struct that had a field containing
+ *    a child struct.  A value of 1 would only allow skipping of simple
+ *    types and empty structs/collections.
+ */
+func SetMaxSkipDepth(depth int) {
+  MaxSkipDepth = depth
+}
+
+/**
+ * Skips over the next data element from the provided input TProtocol object.
+ *
+ * @param prot  the protocol object to read from
+ * @param type  the next value will be intepreted as this TType value.
+ */
+func SkipDefaultDepth(prot TProtocol, typeId TType) (err TProtocolException) {
+  return Skip(prot, typeId, MaxSkipDepth)
+}
+
+/**
+ * Skips over the next data element from the provided input TProtocol object.
+ *
+ * @param prot  the protocol object to read from
+ * @param type  the next value will be intepreted as this TType value.
+ * @param maxDepth  this function will only skip complex objects to this
+ *   recursive depth, to prevent Java stack overflow.
+ */
+func Skip(self TProtocol, fieldType TType, maxDepth int) (err TProtocolException) {
+  switch fieldType {
+  case STOP:
+    return
+  case BOOL:
+    _, err = self.ReadBool()
+    return
+  case BYTE:
+    _, err = self.ReadByte()
+    return
+  case I16:
+    _, err = self.ReadI16()
+    return
+  case I32:
+    _, err = self.ReadI32()
+    return
+  case I64:
+    _, err = self.ReadI64()
+    return
+  case DOUBLE:
+    _, err = self.ReadDouble()
+    return
+  case STRING:
+    _, err = self.ReadString()
+    return
+  case STRUCT:
+    {
+      _, err = self.ReadStructBegin()
+      if err != nil {
+        return
+      }
+      for {
+        _, typeId, _, _ := self.ReadFieldBegin()
+        if typeId == STOP {
+          break
+        }
+        Skip(self, typeId, maxDepth-1)
+        self.ReadFieldEnd()
+      }
+      return self.ReadStructEnd()
+    }
+  case MAP:
+    {
+      keyType, valueType, l, err := self.ReadMapBegin()
+      if err != nil {
+        return err
+      }
+      size := int(l)
+      for i := 0; i < size; i++ {
+        Skip(self, keyType, maxDepth-1)
+        self.Skip(valueType)
+      }
+      return self.ReadMapEnd()
+    }
+  case SET:
+    {
+      elemType, l, err := self.ReadSetBegin()
+      if err != nil {
+        return err
+      }
+      size := int(l)
+      for i := 0; i < size; i++ {
+        Skip(self, elemType, maxDepth-1)
+      }
+      return self.ReadSetEnd()
+    }
+  case LIST:
+    {
+      elemType, l, err := self.ReadListBegin()
+      if err != nil {
+        return err
+      }
+      size := int(l)
+      for i := 0; i < size; i++ {
+        Skip(self, elemType, maxDepth-1)
+      }
+      return self.ReadListEnd()
+    }
+  }
+  return nil
+}
diff --git a/lib/go/thrift/tprotocol_exception.go b/lib/go/thrift/tprotocol_exception.go
new file mode 100644
index 0000000..2dac97e
--- /dev/null
+++ b/lib/go/thrift/tprotocol_exception.go
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "encoding/base64"
+  "os"
+)
+
+/**
+ * Protocol exceptions.
+ *
+ */
+type TProtocolException interface {
+  TException
+  TypeId() int
+}
+
+const (
+  UNKNOWN_PROTOCOL_EXCEPTION = 0
+  INVALID_DATA               = 1
+  NEGATIVE_SIZE              = 2
+  SIZE_LIMIT                 = 3
+  BAD_VERSION                = 4
+  NOT_IMPLEMENTED            = 5
+)
+
+type tProtocolException struct {
+  typeId  int
+  message string
+}
+
+func (p *tProtocolException) TypeId() int {
+  return p.typeId
+}
+
+func (p *tProtocolException) String() string {
+  return p.message
+}
+
+func NewTProtocolExceptionDefault() TProtocolException {
+  return NewTProtocolExceptionDefaultType(UNKNOWN_PROTOCOL_EXCEPTION)
+}
+
+func NewTProtocolExceptionDefaultType(t int) TProtocolException {
+  return NewTProtocolException(t, "")
+}
+
+func NewTProtocolExceptionDefaultString(m string) TProtocolException {
+  return NewTProtocolException(UNKNOWN_PROTOCOL_EXCEPTION, m)
+}
+
+func NewTProtocolException(t int, m string) TProtocolException {
+  return &tProtocolException{typeId: t, message: m}
+}
+
+func NewTProtocolExceptionReadField(fieldId int, fieldName string, structName string, e TProtocolException) TProtocolException {
+  t := e.TypeId()
+  if t == UNKNOWN_PROTOCOL_EXCEPTION {
+    t = INVALID_DATA
+  }
+  return NewTProtocolException(t, "Unable to read field "+string(fieldId)+" ("+fieldName+") in "+structName+" due to: "+e.String())
+}
+
+func NewTProtocolExceptionWriteField(fieldId int, fieldName string, structName string, e TProtocolException) TProtocolException {
+  t := e.TypeId()
+  if t == UNKNOWN_PROTOCOL_EXCEPTION {
+    t = INVALID_DATA
+  }
+  return NewTProtocolException(t, "Unable to write field "+string(fieldId)+" ("+fieldName+") in "+structName+" due to: "+e.String())
+}
+
+func NewTProtocolExceptionReadStruct(structName string, e TProtocolException) TProtocolException {
+  t := e.TypeId()
+  if t == UNKNOWN_PROTOCOL_EXCEPTION {
+    t = INVALID_DATA
+  }
+  return NewTProtocolException(t, "Unable to read struct "+structName+" due to: "+e.String())
+}
+
+func NewTProtocolExceptionWriteStruct(structName string, e TProtocolException) TProtocolException {
+  t := e.TypeId()
+  if t == UNKNOWN_PROTOCOL_EXCEPTION {
+    t = INVALID_DATA
+  }
+  return NewTProtocolException(t, "Unable to write struct "+structName+" due to: "+e.String())
+}
+
+func NewTProtocolExceptionFromOsError(e os.Error) TProtocolException {
+  if e == nil {
+    return nil
+  }
+  if t, ok := e.(TProtocolException); ok {
+    return t
+  }
+  if te, ok := e.(TTransportException); ok {
+    return NewTProtocolExceptionFromTransportException(te)
+  }
+  if _, ok := e.(base64.CorruptInputError); ok {
+    return NewTProtocolException(INVALID_DATA, e.String())
+  }
+  return NewTProtocolExceptionDefaultString(e.String())
+}
+
+func NewTProtocolExceptionFromTransportException(e TTransportException) TProtocolException {
+  if e == nil {
+    return nil
+  }
+  if t, ok := e.(TProtocolException); ok {
+    return t
+  }
+  return NewTProtocolExceptionDefaultString(e.String())
+}
diff --git a/lib/go/thrift/tprotocol_factory.go b/lib/go/thrift/tprotocol_factory.go
new file mode 100644
index 0000000..2eed2c2
--- /dev/null
+++ b/lib/go/thrift/tprotocol_factory.go
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * Factory interface for constructing protocol instances.
+ *
+ */
+type TProtocolFactory interface {
+  GetProtocol(trans TTransport) TProtocol
+}
diff --git a/lib/go/thrift/tprotocol_test.go b/lib/go/thrift/tprotocol_test.go
new file mode 100644
index 0000000..22d6ad6
--- /dev/null
+++ b/lib/go/thrift/tprotocol_test.go
@@ -0,0 +1,1817 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+  "http"
+  "math"
+  "net"
+  "io"
+  "os"
+  "bytes"
+  "fmt"
+)
+
+const PROTOCOL_BINARY_DATA_SIZE = 155
+
+var (
+  data           string // test data for writing
+  protocol_bdata []byte // test data for writing; same as data
+  BOOL_VALUES    []bool
+  BYTE_VALUES    []byte
+  INT16_VALUES   []int16
+  INT32_VALUES   []int32
+  INT64_VALUES   []int64
+  DOUBLE_VALUES  []float64
+  STRING_VALUES  []string
+)
+
+
+func init() {
+  protocol_bdata = make([]byte, PROTOCOL_BINARY_DATA_SIZE)
+  for i := 0; i < PROTOCOL_BINARY_DATA_SIZE; i++ {
+    protocol_bdata[i] = byte((i + 'a') % 255)
+  }
+  data = string(protocol_bdata)
+  BOOL_VALUES = []bool{false, true, false, false, true}
+  BYTE_VALUES = []byte{117, 0, 1, 32, 127, 128, 255}
+  INT16_VALUES = []int16{459, 0, 1, -1, -128, 127, 32767, -32768}
+  INT32_VALUES = []int32{459, 0, 1, -1, -128, 127, 32767, 2147483647, -2147483535}
+  INT64_VALUES = []int64{459, 0, 1, -1, -128, 127, 32767, 2147483647, -2147483535, 34359738481, -35184372088719, -9223372036854775808, 9223372036854775807}
+  DOUBLE_VALUES = []float64{459.3, 0.0, -1.0, 1.0, 0.5, 0.3333, 3.14159, 1.537e-38, 1.673e25, 6.02214179e23, -6.02214179e23, INFINITY.Float64(), NEGATIVE_INFINITY.Float64(), NAN.Float64()}
+  STRING_VALUES = []string{"", "a", "st[uf]f", "st,u:ff with spaces", "stuff\twith\nescape\\characters'...\"lots{of}fun</xml>"}
+}
+
+type HTTPEchoServer struct{}
+
+func (p *HTTPEchoServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+  w.WriteHeader(http.StatusOK)
+  io.Copy(w, req.Body)
+}
+
+func HttpClientSetupForTest(t *testing.T) (net.Listener, net.Addr) {
+  addr, err := FindAvailableTCPServerPort(40000)
+  if err != nil {
+    t.Fatalf("Unable to find available tcp port addr: %s", err)
+  }
+  l, err := net.Listen(addr.Network(), addr.String())
+  if err != nil {
+    t.Fatalf("Unable to setup tcp listener on %s: %s", addr.String(), err)
+  }
+  go http.Serve(l, &HTTPEchoServer{})
+  return l, addr
+}
+
+
+func ReadWriteProtocolTest(t *testing.T, protocolFactory TProtocolFactory) {
+  buf := bytes.NewBuffer(make([]byte, 0, 1024))
+  l, addr := HttpClientSetupForTest(t)
+  transports := []TTransportFactory{
+    NewTMemoryBufferTransportFactory(1024),
+    NewTIOStreamTransportFactory(buf, buf, true),
+    NewTFramedTransportFactory(NewTMemoryBufferTransportFactory(1024)),
+    NewTHttpPostClientTransportFactory("http://" + addr.String()),
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteBool(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteByte(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteI16(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteI32(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteI64(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteDouble(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteString(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteBinary(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteWork(t, p, trans)
+    trans.Close()
+  }
+  for _, tf := range transports {
+    trans := tf.GetTransport(nil)
+    p := protocolFactory.GetProtocol(trans)
+    ReadWriteCalculate(t, p, trans)
+    trans.Close()
+  }
+
+  // this test doesn't work in all cases due to EOF issues between
+  // buffer read and buffer write when using the same bufio for both
+  //for _, tf := range transports {
+  //  trans := tf.GetTransport(nil)
+  //  p := GetProtocol(trans);
+  //  ReadWriteI64(t, p, trans);
+  //  ReadWriteDouble(t, p, trans);
+  //  ReadWriteBinary(t, p, trans);
+  //  ReadWriteByte(t, p, trans);
+  //  trans.Close()
+  //}
+
+  l.Close()
+}
+
+func ReadWriteBool(t *testing.T, p TProtocol, trans TTransport) {
+  thetype := TType(BOOL)
+  thelen := len(BOOL_VALUES)
+  err := p.WriteListBegin(thetype, thelen)
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error writing list begin: %q", "ReadWriteBool", p, trans, err, thetype)
+  }
+  for k, v := range BOOL_VALUES {
+    err = p.WriteBool(v)
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error writing bool in list at index %d: %q", "ReadWriteBool", p, trans, err, k, v)
+    }
+  }
+  p.WriteListEnd()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteBool", p, trans, err, BOOL_VALUES)
+  }
+  p.Flush()
+  thetype2, thelen2, err := p.ReadListBegin()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteBool", p, trans, err, BOOL_VALUES)
+  }
+  _, ok := p.(*TSimpleJSONProtocol)
+  if !ok {
+    if thetype != thetype2 {
+      t.Errorf("%s: %T %T type %s != type %s", "ReadWriteBool", p, trans, thetype, thetype2)
+    }
+    if thelen != thelen2 {
+      t.Errorf("%s: %T %T len %s != len %s", "ReadWriteBool", p, trans, thelen, thelen2)
+    }
+  }
+  for k, v := range BOOL_VALUES {
+    value, err := p.ReadBool()
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error reading bool at index %d: %q", "ReadWriteBool", p, trans, err, k, v)
+    }
+    if v != value {
+      t.Errorf("%s: index %d %q %q %q != %q", "ReadWriteBool", k, p, trans, v, value)
+    }
+  }
+  err = p.ReadListEnd()
+  if err != nil {
+    t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteBool", p, trans, err)
+  }
+}
+
+func ReadWriteByte(t *testing.T, p TProtocol, trans TTransport) {
+  thetype := TType(BYTE)
+  thelen := len(BYTE_VALUES)
+  err := p.WriteListBegin(thetype, thelen)
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error writing list begin: %q", "ReadWriteByte", p, trans, err, thetype)
+  }
+  for k, v := range BYTE_VALUES {
+    err = p.WriteByte(v)
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error writing byte in list at index %d: %q", "ReadWriteByte", p, trans, err, k, v)
+    }
+  }
+  err = p.WriteListEnd()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES)
+  }
+  err = p.Flush()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error flushing list of bytes: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES)
+  }
+  thetype2, thelen2, err := p.ReadListBegin()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES)
+  }
+  _, ok := p.(*TSimpleJSONProtocol)
+  if !ok {
+    if thetype != thetype2 {
+      t.Errorf("%s: %T %T type %s != type %s", "ReadWriteByte", p, trans, thetype, thetype2)
+    }
+    if thelen != thelen2 {
+      t.Errorf("%s: %T %T len %s != len %s", "ReadWriteByte", p, trans, thelen, thelen2)
+    }
+  }
+  for k, v := range BYTE_VALUES {
+    value, err := p.ReadByte()
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error reading byte at index %d: %q", "ReadWriteByte", p, trans, err, k, v)
+    }
+    if v != value {
+      t.Errorf("%s: %T %T %d != %d", "ReadWriteByte", p, trans, v, value)
+    }
+  }
+  err = p.ReadListEnd()
+  if err != nil {
+    t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteByte", p, trans, err)
+  }
+}
+
+func ReadWriteI16(t *testing.T, p TProtocol, trans TTransport) {
+  thetype := TType(I16)
+  thelen := len(INT16_VALUES)
+  p.WriteListBegin(thetype, thelen)
+  for _, v := range INT16_VALUES {
+    p.WriteI16(v)
+  }
+  p.WriteListEnd()
+  p.Flush()
+  thetype2, thelen2, err := p.ReadListBegin()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI16", p, trans, err, INT16_VALUES)
+  }
+  _, ok := p.(*TSimpleJSONProtocol)
+  if !ok {
+    if thetype != thetype2 {
+      t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI16", p, trans, thetype, thetype2)
+    }
+    if thelen != thelen2 {
+      t.Errorf("%s: %T %T len %s != len %s", "ReadWriteI16", p, trans, thelen, thelen2)
+    }
+  }
+  for k, v := range INT16_VALUES {
+    value, err := p.ReadI16()
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error reading int16 at index %d: %q", "ReadWriteI16", p, trans, err, k, v)
+    }
+    if v != value {
+      t.Errorf("%s: %T %T %d != %d", "ReadWriteI16", p, trans, v, value)
+    }
+  }
+  err = p.ReadListEnd()
+  if err != nil {
+    t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI16", p, trans, err)
+  }
+}
+
+func ReadWriteI32(t *testing.T, p TProtocol, trans TTransport) {
+  thetype := TType(I32)
+  thelen := len(INT32_VALUES)
+  p.WriteListBegin(thetype, thelen)
+  for _, v := range INT32_VALUES {
+    p.WriteI32(v)
+  }
+  p.WriteListEnd()
+  p.Flush()
+  thetype2, thelen2, err := p.ReadListBegin()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI32", p, trans, err, INT32_VALUES)
+  }
+  _, ok := p.(*TSimpleJSONProtocol)
+  if !ok {
+    if thetype != thetype2 {
+      t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI32", p, trans, thetype, thetype2)
+    }
+    if thelen != thelen2 {
+      t.Errorf("%s: %T %T len %s != len %s", "ReadWriteI32", p, trans, thelen, thelen2)
+    }
+  }
+  for k, v := range INT32_VALUES {
+    value, err := p.ReadI32()
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error reading int32 at index %d: %q", "ReadWriteI32", p, trans, err, k, v)
+    }
+    if v != value {
+      t.Errorf("%s: %T %T %d != %d", "ReadWriteI32", p, trans, v, value)
+    }
+  }
+  if err != nil {
+    t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI32", p, trans, err)
+  }
+}
+
+func ReadWriteI64(t *testing.T, p TProtocol, trans TTransport) {
+  thetype := TType(I64)
+  thelen := len(INT64_VALUES)
+  p.WriteListBegin(thetype, thelen)
+  for _, v := range INT64_VALUES {
+    p.WriteI64(v)
+  }
+  p.WriteListEnd()
+  p.Flush()
+  thetype2, thelen2, err := p.ReadListBegin()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI64", p, trans, err, INT64_VALUES)
+  }
+  _, ok := p.(*TSimpleJSONProtocol)
+  if !ok {
+    if thetype != thetype2 {
+      t.Errorf("%s: %T %T type %s != type %s", "ReadWriteI64", p, trans, thetype, thetype2)
+    }
+    if thelen != thelen2 {
+      t.Errorf("%s: %T %T len %s != len %s", "ReadWriteI64", p, trans, thelen, thelen2)
+    }
+  }
+  for k, v := range INT64_VALUES {
+    value, err := p.ReadI64()
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error reading int64 at index %d: %q", "ReadWriteI64", p, trans, err, k, v)
+    }
+    if v != value {
+      t.Errorf("%s: %T %T %q != %q", "ReadWriteI64", p, trans, v, value)
+    }
+  }
+  if err != nil {
+    t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteI64", p, trans, err)
+  }
+}
+
+func ReadWriteDouble(t *testing.T, p TProtocol, trans TTransport) {
+  thetype := TType(DOUBLE)
+  thelen := len(DOUBLE_VALUES)
+  p.WriteListBegin(thetype, thelen)
+  for _, v := range DOUBLE_VALUES {
+    p.WriteDouble(v)
+  }
+  p.WriteListEnd()
+  p.Flush()
+  wrotebuffer := ""
+  if memtrans, ok := trans.(*TMemoryBuffer); ok {
+    wrotebuffer = memtrans.String()
+  }
+  thetype2, thelen2, err := p.ReadListBegin()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error reading list: %q, wrote: %v", "ReadWriteDouble", p, trans, err, DOUBLE_VALUES, wrotebuffer)
+  }
+  if thetype != thetype2 {
+    t.Errorf("%s: %T %T type %s != type %s", "ReadWriteDouble", p, trans, thetype, thetype2)
+  }
+  if thelen != thelen2 {
+    t.Errorf("%s: %T %T len %s != len %s", "ReadWriteDouble", p, trans, thelen, thelen2)
+  }
+  for k, v := range DOUBLE_VALUES {
+    value, err := p.ReadDouble()
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error reading double at index %d: %q", "ReadWriteDouble", p, trans, err, k, v)
+    }
+    if math.IsNaN(v) {
+      if !math.IsNaN(value) {
+        t.Errorf("%s: %T %T math.IsNaN(%q) != math.IsNaN(%q)", "ReadWriteDouble", p, trans, v, value)
+      }
+    } else if v != value {
+      t.Errorf("%s: %T %T %v != %q", "ReadWriteDouble", p, trans, v, value)
+    }
+  }
+  err = p.ReadListEnd()
+  if err != nil {
+    t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteDouble", p, trans, err)
+  }
+}
+
+func ReadWriteString(t *testing.T, p TProtocol, trans TTransport) {
+  thetype := TType(STRING)
+  thelen := len(STRING_VALUES)
+  p.WriteListBegin(thetype, thelen)
+  for _, v := range STRING_VALUES {
+    p.WriteString(v)
+  }
+  p.WriteListEnd()
+  p.Flush()
+  thetype2, thelen2, err := p.ReadListBegin()
+  if err != nil {
+    t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteString", p, trans, err, STRING_VALUES)
+  }
+  _, ok := p.(*TSimpleJSONProtocol)
+  if !ok {
+    if thetype != thetype2 {
+      t.Errorf("%s: %T %T type %s != type %s", "ReadWriteString", p, trans, thetype, thetype2)
+    }
+    if thelen != thelen2 {
+      t.Errorf("%s: %T %T len %s != len %s", "ReadWriteString", p, trans, thelen, thelen2)
+    }
+  }
+  for k, v := range STRING_VALUES {
+    value, err := p.ReadString()
+    if err != nil {
+      t.Errorf("%s: %T %T %q Error reading string at index %d: %q", "ReadWriteString", p, trans, err, k, v)
+    }
+    if v != value {
+      t.Errorf("%s: %T %T %d != %d", "ReadWriteString", p, trans, v, value)
+    }
+  }
+  if err != nil {
+    t.Errorf("%s: %T %T Unable to read list end: %q", "ReadWriteString", p, trans, err)
+  }
+}
+
+
+func ReadWriteBinary(t *testing.T, p TProtocol, trans TTransport) {
+  v := protocol_bdata
+  p.WriteBinary(v)
+  p.Flush()
+  value, err := p.ReadBinary()
+  if err != nil {
+    t.Errorf("%s: %T %T Unable to read binary: %s", "ReadWriteBinary", p, trans, err.String())
+  }
+  if len(v) != len(value) {
+    t.Errorf("%s: %T %T len(v) != len(value)... %d != %d", "ReadWriteBinary", p, trans, len(v), len(value))
+  } else {
+    for i := 0; i < len(v); i++ {
+      if v[i] != value[i] {
+        t.Errorf("%s: %T %T %s != %s", "ReadWriteBinary", p, trans, v, value)
+      }
+    }
+  }
+}
+
+
+func ReadWriteWork(t *testing.T, p TProtocol, trans TTransport) {
+  thetype := "struct"
+  orig := NewWork()
+  orig.Num1 = 25
+  orig.Num2 = 102
+  orig.Op = ADD
+  orig.Comment = "Add: 25 + 102"
+  return
+  if e := orig.Write(p); e != nil {
+    t.Fatalf("Unable to write %s value %#v due to error: %s", thetype, orig, e.String())
+  }
+  read := NewWork()
+  e := read.Read(p)
+  if e != nil {
+    t.Fatalf("Unable to read %s due to error: %s", thetype, e.String())
+  }
+  if !orig.Equals(read) {
+    t.Fatalf("Original Write != Read: %#v != %#v ", orig, read)
+  }
+}
+
+
+func ReadWriteCalculate(t *testing.T, p TProtocol, trans TTransport) {
+  messageName := "calculate"
+  logid := int32(12)
+  seqId := int32(35)
+  w := NewWork()
+  w.Num1 = 25
+  w.Num2 = 102
+  w.Op = ADD
+  w.Comment = "Add: 25 + 102"
+
+  args31 := NewCalculateArgs()
+  args31.Logid = logid
+  args31.W = w
+  p.WriteMessageBegin(messageName, CALL, seqId)
+  if err := args31.Write(p); err != nil {
+    t.Fatalf("%s: %T %T Unable to write message: %s", messageName, p, trans, err.String())
+  }
+  p.WriteMessageEnd()
+  p.Transport().Flush()
+
+  name, ttype, seqid, err1 := p.ReadMessageBegin()
+  if err1 != nil {
+    t.Fatalf("%s: %T %T Unable to read message begin: %s", messageName, p, trans, err1.String())
+  }
+  if name != messageName {
+    t.Errorf("%s: %T %T Expected message named \"%s\", but was: \"%s\"", messageName, p, trans, messageName, name)
+  }
+  if ttype != CALL {
+    t.Errorf("%s: %T %T Expected message type \"%s\", but was: \"%s\"", messageName, p, trans, CALL, ttype)
+  }
+  if seqid != seqId {
+    t.Errorf("%s: %T %T Expected message type \"%s\", but was: \"%s\"", messageName, p, trans, seqId, seqid)
+  }
+  calcArgs := NewCalculateArgs()
+  err2 := calcArgs.Read(p)
+  if !args31.Equals(calcArgs) {
+    //cmp1, _ := args31.W.CompareTo(calcArgs.W)
+    cmp2, ok := args31.CompareTo(calcArgs)
+    t.Errorf("%s: %T %T Calculate args not as expected, %T vs %T, cmp: %#v, ok: %#v, equals: %#v", messageName, p, trans, args31, calcArgs, cmp2, ok, args31.Equals(calcArgs))
+  }
+  if err2 != nil {
+    t.Fatalf("%s: %T %T Unable to read message end: %s", messageName, p, trans, err2.String())
+  }
+  err3 := p.ReadMessageEnd()
+  if err3 != nil {
+    t.Fatalf("%s: %T %T Unable to read message end: %s", messageName, p, trans, err3.String())
+  }
+}
+
+
+/**
+ *You can define enums, which are just 32 bit integers. Values are optional
+ *and start at 1 if not supplied, C style again.
+ */
+type Operation int
+
+const (
+  ADD      Operation = 1
+  SUBTRACT Operation = 2
+  MULTIPLY Operation = 3
+  DIVIDE   Operation = 4
+)
+
+func (p Operation) String() string {
+  switch p {
+  case ADD:
+    return "ADD"
+  case SUBTRACT:
+    return "SUBTRACT"
+  case MULTIPLY:
+    return "MULTIPLY"
+  case DIVIDE:
+    return "DIVIDE"
+  }
+  return ""
+}
+
+func FromOperationString(s string) Operation {
+  switch s {
+  case "ADD":
+    return ADD
+  case "SUBTRACT":
+    return SUBTRACT
+  case "MULTIPLY":
+    return MULTIPLY
+  case "DIVIDE":
+    return DIVIDE
+  }
+  return Operation(-10000)
+}
+
+func (p Operation) Value() int {
+  return int(p)
+}
+
+func (p Operation) IsEnum() bool {
+  return true
+}
+
+/**
+ *Thrift lets you do typedefs to get pretty names for your types. Standard
+ *C style here.
+ */
+type MyInteger int32
+
+const INT32CONSTANT = 9853
+
+var MAPCONSTANT TMap
+/**
+ * Structs are the basic complex data structures. They are comprised of fields
+ * which each have an integer identifier, a type, a symbolic name, and an
+ * optional default value.
+ * 
+ * Fields can be declared "optional", which ensures they will not be included
+ * in the serialized output if they aren't set.  Note that this requires some
+ * manual management in some languages.
+ * 
+ * Attributes:
+ *  - Num1
+ *  - Num2
+ *  - Op
+ *  - Comment
+ */
+type Work struct {
+  TStruct
+  _       interface{} "num1"    // nil # 0
+  Num1    int32       "num1"    // 1
+  Num2    int32       "num2"    // 2
+  Op      Operation   "op"      // 3
+  Comment string      "comment" // 4
+}
+
+func NewWork() *Work {
+  output := &Work{
+    TStruct: NewTStruct("Work", []TField{
+      NewTField("num1", I32, 1),
+      NewTField("num2", I32, 2),
+      NewTField("op", I32, 3),
+      NewTField("comment", STRING, 4),
+    }),
+  }
+  {
+    output.Num1 = 0
+  }
+  return output
+}
+
+func (p *Work) Read(iprot TProtocol) (err TProtocolException) {
+  _, err = iprot.ReadStructBegin()
+  if err != nil {
+    return NewTProtocolExceptionReadStruct(p.ThriftName(), err)
+  }
+  for {
+    fieldName, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
+    if fieldId < 0 {
+      fieldId = int16(p.FieldIdFromFieldName(fieldName))
+    } else if fieldName == "" {
+      fieldName = p.FieldNameFromFieldId(int(fieldId))
+    }
+    if fieldTypeId == GENERIC {
+      fieldTypeId = p.FieldFromFieldId(int(fieldId)).TypeId()
+    }
+    if err != nil {
+      return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+    }
+    if fieldTypeId == STOP {
+      break
+    }
+    if fieldId == 1 || fieldName == "num1" {
+      if fieldTypeId == I32 {
+        err = p.ReadField1(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField1(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else if fieldId == 2 || fieldName == "num2" {
+      if fieldTypeId == I32 {
+        err = p.ReadField2(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField2(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else if fieldId == 3 || fieldName == "op" {
+      if fieldTypeId == I32 {
+        err = p.ReadField3(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField3(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else if fieldId == 4 || fieldName == "comment" {
+      if fieldTypeId == STRING {
+        err = p.ReadField4(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField4(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else {
+      err = iprot.Skip(fieldTypeId)
+      if err != nil {
+        return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+      }
+    }
+    err = iprot.ReadFieldEnd()
+    if err != nil {
+      return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+    }
+  }
+  err = iprot.ReadStructEnd()
+  if err != nil {
+    return NewTProtocolExceptionReadStruct(p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *Work) ReadField1(iprot TProtocol) (err TProtocolException) {
+  v4, err5 := iprot.ReadI32()
+  if err5 != nil {
+    return NewTProtocolExceptionReadField(1, "num1", p.ThriftName(), err5)
+  }
+  p.Num1 = v4
+  return err
+}
+
+func (p *Work) ReadFieldNum1(iprot TProtocol) TProtocolException {
+  return p.ReadField1(iprot)
+}
+
+func (p *Work) ReadField2(iprot TProtocol) (err TProtocolException) {
+  v6, err7 := iprot.ReadI32()
+  if err7 != nil {
+    return NewTProtocolExceptionReadField(2, "num2", p.ThriftName(), err7)
+  }
+  p.Num2 = v6
+  return err
+}
+
+func (p *Work) ReadFieldNum2(iprot TProtocol) TProtocolException {
+  return p.ReadField2(iprot)
+}
+
+func (p *Work) ReadField3(iprot TProtocol) (err TProtocolException) {
+  v8, err9 := iprot.ReadI32()
+  if err9 != nil {
+    return NewTProtocolExceptionReadField(3, "op", p.ThriftName(), err9)
+  }
+  p.Op = Operation(v8)
+  return err
+}
+
+func (p *Work) ReadFieldOp(iprot TProtocol) TProtocolException {
+  return p.ReadField3(iprot)
+}
+
+func (p *Work) ReadField4(iprot TProtocol) (err TProtocolException) {
+  v10, err11 := iprot.ReadString()
+  if err11 != nil {
+    return NewTProtocolExceptionReadField(4, "comment", p.ThriftName(), err11)
+  }
+  p.Comment = v10
+  return err
+}
+
+func (p *Work) ReadFieldComment(iprot TProtocol) TProtocolException {
+  return p.ReadField4(iprot)
+}
+
+func (p *Work) Write(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteStructBegin("Work")
+  if err != nil {
+    return NewTProtocolExceptionWriteStruct(p.ThriftName(), err)
+  }
+  err = p.WriteField1(oprot)
+  if err != nil {
+    return err
+  }
+  err = p.WriteField2(oprot)
+  if err != nil {
+    return err
+  }
+  err = p.WriteField3(oprot)
+  if err != nil {
+    return err
+  }
+  err = p.WriteField4(oprot)
+  if err != nil {
+    return err
+  }
+  err = oprot.WriteFieldStop()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(-1, "STOP", p.ThriftName(), err)
+  }
+  err = oprot.WriteStructEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteStruct(p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *Work) WriteField1(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteFieldBegin("num1", I32, 1)
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "num1", p.ThriftName(), err)
+  }
+  err = oprot.WriteI32(int32(p.Num1))
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "num1", p.ThriftName(), err)
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "num1", p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *Work) WriteFieldNum1(oprot TProtocol) TProtocolException {
+  return p.WriteField1(oprot)
+}
+
+func (p *Work) WriteField2(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteFieldBegin("num2", I32, 2)
+  if err != nil {
+    return NewTProtocolExceptionWriteField(2, "num2", p.ThriftName(), err)
+  }
+  err = oprot.WriteI32(int32(p.Num2))
+  if err != nil {
+    return NewTProtocolExceptionWriteField(2, "num2", p.ThriftName(), err)
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(2, "num2", p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *Work) WriteFieldNum2(oprot TProtocol) TProtocolException {
+  return p.WriteField2(oprot)
+}
+
+func (p *Work) WriteField3(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteFieldBegin("op", I32, 3)
+  if err != nil {
+    return NewTProtocolExceptionWriteField(3, "op", p.ThriftName(), err)
+  }
+  err = oprot.WriteI32(int32(p.Op))
+  if err != nil {
+    return NewTProtocolExceptionWriteField(3, "op", p.ThriftName(), err)
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(3, "op", p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *Work) WriteFieldOp(oprot TProtocol) TProtocolException {
+  return p.WriteField3(oprot)
+}
+
+func (p *Work) WriteField4(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteFieldBegin("comment", STRING, 4)
+  if err != nil {
+    return NewTProtocolExceptionWriteField(4, "comment", p.ThriftName(), err)
+  }
+  err = oprot.WriteString(string(p.Comment))
+  if err != nil {
+    return NewTProtocolExceptionWriteField(4, "comment", p.ThriftName(), err)
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(4, "comment", p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *Work) WriteFieldComment(oprot TProtocol) TProtocolException {
+  return p.WriteField4(oprot)
+}
+
+func (p *Work) TStructName() string {
+  return "Work"
+}
+
+func (p *Work) ThriftName() string {
+  return "Work"
+}
+
+func (p *Work) String() string {
+  if p == nil {
+    return "<nil>"
+  }
+  return fmt.Sprintf("Work(%+v)", *p)
+}
+
+func (p *Work) CompareTo(other interface{}) (int, bool) {
+  if other == nil {
+    return 1, true
+  }
+  data, ok := other.(*Work)
+  if !ok {
+    return 0, false
+  }
+  if p.Num1 != data.Num1 {
+    if p.Num1 < data.Num1 {
+      return -1, true
+    }
+    return 1, true
+  }
+  if p.Num2 != data.Num2 {
+    if p.Num2 < data.Num2 {
+      return -1, true
+    }
+    return 1, true
+  }
+  if p.Op != data.Op {
+    if p.Op < data.Op {
+      return -1, true
+    }
+    return 1, true
+  }
+  if p.Comment != data.Comment {
+    if p.Comment < data.Comment {
+      return -1, true
+    }
+    return 1, true
+  }
+  return 0, true
+}
+
+func (p *Work) AttributeByFieldId(id int) interface{} {
+  switch id {
+  default:
+    return nil
+  case 1:
+    return p.Num1
+  case 2:
+    return p.Num2
+  case 3:
+    return p.Op
+  case 4:
+    return p.Comment
+  }
+  return nil
+}
+
+func (p *Work) TStructFields() TFieldContainer {
+  return NewTFieldContainer([]TField{
+    NewTField("num1", I32, 1),
+    NewTField("num2", I32, 2),
+    NewTField("op", I32, 3),
+    NewTField("comment", STRING, 4),
+  })
+}
+
+
+type ICalculator interface {
+  /**
+   * Parameters:
+   *  - Key
+   */
+  Calculate(logid int32, w *Work) (retval30 int32, ouch *InvalidOperation, err os.Error)
+}
+
+type CalculatorClient struct {
+  Transport       TTransport
+  ProtocolFactory TProtocolFactory
+  InputProtocol   TProtocol
+  OutputProtocol  TProtocol
+  SeqId           int32
+}
+
+func NewCalculatorClientFactory(t TTransport, f TProtocolFactory) *CalculatorClient {
+  return &CalculatorClient{Transport: t,
+    ProtocolFactory: f,
+    InputProtocol:   f.GetProtocol(t),
+    OutputProtocol:  f.GetProtocol(t),
+    SeqId:           0,
+  }
+}
+
+func NewCalculatorClientProtocol(t TTransport, iprot TProtocol, oprot TProtocol) *CalculatorClient {
+  return &CalculatorClient{Transport: t,
+    ProtocolFactory: nil,
+    InputProtocol:   iprot,
+    OutputProtocol:  oprot,
+    SeqId:           0,
+  }
+}
+
+
+/**
+ * Parameters:
+ *  - Logid
+ *  - W
+ */
+func (p *CalculatorClient) Calculate(logid int32, w *Work) (retval30 int32, ouch *InvalidOperation, err os.Error) {
+  err = p.SendCalculate(logid, w)
+  if err != nil {
+    return
+  }
+  return p.RecvCalculate()
+}
+
+func (p *CalculatorClient) SendCalculate(logid int32, w *Work) (err os.Error) {
+  oprot := p.OutputProtocol
+  if oprot != nil {
+    oprot = p.ProtocolFactory.GetProtocol(p.Transport)
+    p.OutputProtocol = oprot
+  }
+  oprot.WriteMessageBegin("calculate", CALL, p.SeqId)
+  args31 := NewCalculateArgs()
+  args31.Logid = logid
+  args31.W = w
+  err = args31.Write(oprot)
+  oprot.WriteMessageEnd()
+  oprot.Transport().Flush()
+  return
+}
+
+
+func (p *CalculatorClient) RecvCalculate() (value int32, ouch *InvalidOperation, err os.Error) {
+  iprot := p.InputProtocol
+  if iprot == nil {
+    iprot = p.ProtocolFactory.GetProtocol(p.Transport)
+    p.InputProtocol = iprot
+  }
+  _, mTypeId, _, err := iprot.ReadMessageBegin()
+  if err != nil {
+    return
+  }
+  if mTypeId == EXCEPTION {
+    error33 := NewTApplicationExceptionDefault()
+    error34, err := error33.Read(iprot)
+    if err != nil {
+      return
+    }
+    if err = iprot.ReadMessageEnd(); err != nil {
+      return
+    }
+    err = error34
+    return
+  }
+  result32 := NewCalculateResult()
+  err = result32.Read(iprot)
+  iprot.ReadMessageEnd()
+  value = result32.Success
+  if result32.Ouch != nil {
+    ouch = result32.Ouch
+  }
+  return
+}
+
+
+/**
+ * Attributes:
+ *  - Logid
+ *  - W
+ */
+type CalculateArgs struct {
+  TStruct
+  _     interface{} "logid" // nil # 0
+  Logid int32       "logid" // 1
+  W     *Work       "w"     // 2
+}
+
+func NewCalculateArgs() *CalculateArgs {
+  output := &CalculateArgs{
+    TStruct: NewTStruct("calculate_args", []TField{
+      NewTField("logid", I32, 1),
+      NewTField("w", STRUCT, 2),
+    }),
+  }
+  {
+  }
+  return output
+}
+
+func (p *CalculateArgs) Read(iprot TProtocol) (err TProtocolException) {
+  _, err = iprot.ReadStructBegin()
+  if err != nil {
+    return NewTProtocolExceptionReadStruct(p.ThriftName(), err)
+  }
+  for {
+    fieldName, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
+    if fieldId < 0 {
+      fieldId = int16(p.FieldIdFromFieldName(fieldName))
+    } else if fieldName == "" {
+      fieldName = p.FieldNameFromFieldId(int(fieldId))
+    }
+    if fieldTypeId == GENERIC {
+      fieldTypeId = p.FieldFromFieldId(int(fieldId)).TypeId()
+    }
+    if err != nil {
+      return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+    }
+    if fieldTypeId == STOP {
+      break
+    }
+    if fieldId == 1 || fieldName == "logid" {
+      if fieldTypeId == I32 {
+        err = p.ReadField1(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField1(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else if fieldId == 2 || fieldName == "w" {
+      if fieldTypeId == STRUCT {
+        err = p.ReadField2(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField2(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else {
+      err = iprot.Skip(fieldTypeId)
+      if err != nil {
+        return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+      }
+    }
+    err = iprot.ReadFieldEnd()
+    if err != nil {
+      return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+    }
+  }
+  err = iprot.ReadStructEnd()
+  if err != nil {
+    return NewTProtocolExceptionReadStruct(p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *CalculateArgs) ReadField1(iprot TProtocol) (err TProtocolException) {
+  v47, err48 := iprot.ReadI32()
+  if err48 != nil {
+    return NewTProtocolExceptionReadField(1, "logid", p.ThriftName(), err48)
+  }
+  p.Logid = v47
+  return err
+}
+
+func (p *CalculateArgs) ReadFieldLogid(iprot TProtocol) TProtocolException {
+  return p.ReadField1(iprot)
+}
+
+func (p *CalculateArgs) ReadField2(iprot TProtocol) (err TProtocolException) {
+  p.W = NewWork()
+  err51 := p.W.Read(iprot)
+  if err51 != nil {
+    return NewTProtocolExceptionReadStruct("p.WWork", err51)
+  }
+  return err
+}
+
+func (p *CalculateArgs) ReadFieldW(iprot TProtocol) TProtocolException {
+  return p.ReadField2(iprot)
+}
+
+func (p *CalculateArgs) Write(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteStructBegin("calculate_args")
+  if err != nil {
+    return NewTProtocolExceptionWriteStruct(p.ThriftName(), err)
+  }
+  err = p.WriteField1(oprot)
+  if err != nil {
+    return err
+  }
+  err = p.WriteField2(oprot)
+  if err != nil {
+    return err
+  }
+  err = oprot.WriteFieldStop()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(-1, "STOP", p.ThriftName(), err)
+  }
+  err = oprot.WriteStructEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteStruct(p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *CalculateArgs) WriteField1(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteFieldBegin("logid", I32, 1)
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "logid", p.ThriftName(), err)
+  }
+  err = oprot.WriteI32(int32(p.Logid))
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "logid", p.ThriftName(), err)
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "logid", p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *CalculateArgs) WriteFieldLogid(oprot TProtocol) TProtocolException {
+  return p.WriteField1(oprot)
+}
+
+func (p *CalculateArgs) WriteField2(oprot TProtocol) (err TProtocolException) {
+  if p.W != nil {
+    err = oprot.WriteFieldBegin("w", STRUCT, 2)
+    if err != nil {
+      return NewTProtocolExceptionWriteField(2, "w", p.ThriftName(), err)
+    }
+    err = p.W.Write(oprot)
+    if err != nil {
+      return NewTProtocolExceptionWriteStruct("Work", err)
+    }
+    err = oprot.WriteFieldEnd()
+    if err != nil {
+      return NewTProtocolExceptionWriteField(2, "w", p.ThriftName(), err)
+    }
+  }
+  return err
+}
+
+func (p *CalculateArgs) WriteFieldW(oprot TProtocol) TProtocolException {
+  return p.WriteField2(oprot)
+}
+
+func (p *CalculateArgs) TStructName() string {
+  return "CalculateArgs"
+}
+
+func (p *CalculateArgs) ThriftName() string {
+  return "calculate_args"
+}
+
+func (p *CalculateArgs) String() string {
+  if p == nil {
+    return "<nil>"
+  }
+  return fmt.Sprintf("CalculateArgs(%+v)", *p)
+}
+
+func (p *CalculateArgs) CompareTo(other interface{}) (int, bool) {
+  if other == nil {
+    return 1, true
+  }
+  data, ok := other.(*CalculateArgs)
+  if !ok {
+    return 0, false
+  }
+  if p.Logid != data.Logid {
+    if p.Logid < data.Logid {
+      return -1, true
+    }
+    return 1, true
+  }
+  if cmp, ok := p.W.CompareTo(data.W); !ok || cmp != 0 {
+    return cmp, ok
+  }
+  return 0, true
+}
+
+func (p *CalculateArgs) AttributeByFieldId(id int) interface{} {
+  switch id {
+  default:
+    return nil
+  case 1:
+    return p.Logid
+  case 2:
+    return p.W
+  }
+  return nil
+}
+
+func (p *CalculateArgs) TStructFields() TFieldContainer {
+  return NewTFieldContainer([]TField{
+    NewTField("logid", I32, 1),
+    NewTField("w", STRUCT, 2),
+  })
+}
+
+/**
+ * Attributes:
+ *  - Success
+ *  - Ouch
+ */
+type CalculateResult struct {
+  TStruct
+  Success int32             "success" // 0
+  Ouch    *InvalidOperation "ouch"    // 1
+}
+
+func NewCalculateResult() *CalculateResult {
+  output := &CalculateResult{
+    TStruct: NewTStruct("calculate_result", []TField{
+      NewTField("success", I32, 0),
+      NewTField("ouch", STRUCT, 1),
+    }),
+  }
+  {
+  }
+  return output
+}
+
+func (p *CalculateResult) Read(iprot TProtocol) (err TProtocolException) {
+  _, err = iprot.ReadStructBegin()
+  if err != nil {
+    return NewTProtocolExceptionReadStruct(p.ThriftName(), err)
+  }
+  for {
+    fieldName, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
+    if fieldId < 0 {
+      fieldId = int16(p.FieldIdFromFieldName(fieldName))
+    } else if fieldName == "" {
+      fieldName = p.FieldNameFromFieldId(int(fieldId))
+    }
+    if fieldTypeId == GENERIC {
+      fieldTypeId = p.FieldFromFieldId(int(fieldId)).TypeId()
+    }
+    if err != nil {
+      return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+    }
+    if fieldTypeId == STOP {
+      break
+    }
+    if fieldId == 0 || fieldName == "success" {
+      if fieldTypeId == I32 {
+        err = p.ReadField0(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField0(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else if fieldId == 1 || fieldName == "ouch" {
+      if fieldTypeId == STRUCT {
+        err = p.ReadField1(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField1(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else {
+      err = iprot.Skip(fieldTypeId)
+      if err != nil {
+        return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+      }
+    }
+    err = iprot.ReadFieldEnd()
+    if err != nil {
+      return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+    }
+  }
+  err = iprot.ReadStructEnd()
+  if err != nil {
+    return NewTProtocolExceptionReadStruct(p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *CalculateResult) ReadField0(iprot TProtocol) (err TProtocolException) {
+  v52, err53 := iprot.ReadI32()
+  if err53 != nil {
+    return NewTProtocolExceptionReadField(0, "success", p.ThriftName(), err53)
+  }
+  p.Success = v52
+  return err
+}
+
+func (p *CalculateResult) ReadFieldSuccess(iprot TProtocol) TProtocolException {
+  return p.ReadField0(iprot)
+}
+
+func (p *CalculateResult) ReadField1(iprot TProtocol) (err TProtocolException) {
+  p.Ouch = NewInvalidOperation()
+  err56 := p.Ouch.Read(iprot)
+  if err56 != nil {
+    return NewTProtocolExceptionReadStruct("p.OuchInvalidOperation", err56)
+  }
+  return err
+}
+
+func (p *CalculateResult) ReadFieldOuch(iprot TProtocol) TProtocolException {
+  return p.ReadField1(iprot)
+}
+
+func (p *CalculateResult) Write(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteStructBegin("calculate_result")
+  if err != nil {
+    return NewTProtocolExceptionWriteStruct(p.ThriftName(), err)
+  }
+  err = p.WriteField0(oprot)
+  if err != nil {
+    return err
+  }
+  err = p.WriteField1(oprot)
+  if err != nil {
+    return err
+  }
+  err = oprot.WriteFieldStop()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(-1, "STOP", p.ThriftName(), err)
+  }
+  err = oprot.WriteStructEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteStruct(p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *CalculateResult) WriteField0(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteFieldBegin("success", I32, 0)
+  if err != nil {
+    return NewTProtocolExceptionWriteField(0, "success", p.ThriftName(), err)
+  }
+  err = oprot.WriteI32(int32(p.Success))
+  if err != nil {
+    return NewTProtocolExceptionWriteField(0, "success", p.ThriftName(), err)
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(0, "success", p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *CalculateResult) WriteFieldSuccess(oprot TProtocol) TProtocolException {
+  return p.WriteField0(oprot)
+}
+
+func (p *CalculateResult) WriteField1(oprot TProtocol) (err TProtocolException) {
+  if p.Ouch != nil {
+    err = oprot.WriteFieldBegin("ouch", STRUCT, 1)
+    if err != nil {
+      return NewTProtocolExceptionWriteField(1, "ouch", p.ThriftName(), err)
+    }
+    err = p.Ouch.Write(oprot)
+    if err != nil {
+      return NewTProtocolExceptionWriteStruct("InvalidOperation", err)
+    }
+    err = oprot.WriteFieldEnd()
+    if err != nil {
+      return NewTProtocolExceptionWriteField(1, "ouch", p.ThriftName(), err)
+    }
+  }
+  return err
+}
+
+func (p *CalculateResult) WriteFieldOuch(oprot TProtocol) TProtocolException {
+  return p.WriteField1(oprot)
+}
+
+func (p *CalculateResult) TStructName() string {
+  return "CalculateResult"
+}
+
+func (p *CalculateResult) ThriftName() string {
+  return "calculate_result"
+}
+
+func (p *CalculateResult) String() string {
+  if p == nil {
+    return "<nil>"
+  }
+  return fmt.Sprintf("CalculateResult(%+v)", *p)
+}
+
+func (p *CalculateResult) CompareTo(other interface{}) (int, bool) {
+  if other == nil {
+    return 1, true
+  }
+  data, ok := other.(*CalculateResult)
+  if !ok {
+    return 0, false
+  }
+  if p.Success != data.Success {
+    if p.Success < data.Success {
+      return -1, true
+    }
+    return 1, true
+  }
+  if cmp, ok := p.Ouch.CompareTo(data.Ouch); !ok || cmp != 0 {
+    return cmp, ok
+  }
+  return 0, true
+}
+
+func (p *CalculateResult) AttributeByFieldId(id int) interface{} {
+  switch id {
+  default:
+    return nil
+  case 0:
+    return p.Success
+  case 1:
+    return p.Ouch
+  }
+  return nil
+}
+
+func (p *CalculateResult) TStructFields() TFieldContainer {
+  return NewTFieldContainer([]TField{
+    NewTField("success", I32, 0),
+    NewTField("ouch", STRUCT, 1),
+  })
+}
+
+
+/**
+ * Structs can also be exceptions, if they are nasty.
+ * 
+ * Attributes:
+ *  - What
+ *  - Why
+ */
+type InvalidOperation struct {
+  TStruct
+  _    interface{} "what" // nil # 0
+  What int32       "what" // 1
+  Why  string      "why"  // 2
+}
+
+func NewInvalidOperation() *InvalidOperation {
+  output := &InvalidOperation{
+    TStruct: NewTStruct("InvalidOperation", []TField{
+      NewTField("what", I32, 1),
+      NewTField("why", STRING, 2),
+    }),
+  }
+  {
+  }
+  return output
+}
+
+func (p *InvalidOperation) Read(iprot TProtocol) (err TProtocolException) {
+  _, err = iprot.ReadStructBegin()
+  if err != nil {
+    return NewTProtocolExceptionReadStruct(p.ThriftName(), err)
+  }
+  for {
+    fieldName, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
+    if fieldId < 0 {
+      fieldId = int16(p.FieldIdFromFieldName(fieldName))
+    } else if fieldName == "" {
+      fieldName = p.FieldNameFromFieldId(int(fieldId))
+    }
+    if fieldTypeId == GENERIC {
+      fieldTypeId = p.FieldFromFieldId(int(fieldId)).TypeId()
+    }
+    if err != nil {
+      return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+    }
+    if fieldTypeId == STOP {
+      break
+    }
+    if fieldId == 1 || fieldName == "what" {
+      if fieldTypeId == I32 {
+        err = p.ReadField1(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField1(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else if fieldId == 2 || fieldName == "why" {
+      if fieldTypeId == STRING {
+        err = p.ReadField2(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else if fieldTypeId == VOID {
+        err = iprot.Skip(fieldTypeId)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      } else {
+        err = p.ReadField2(iprot)
+        if err != nil {
+          return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+        }
+      }
+    } else {
+      err = iprot.Skip(fieldTypeId)
+      if err != nil {
+        return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+      }
+    }
+    err = iprot.ReadFieldEnd()
+    if err != nil {
+      return NewTProtocolExceptionReadField(int(fieldId), fieldName, p.ThriftName(), err)
+    }
+  }
+  err = iprot.ReadStructEnd()
+  if err != nil {
+    return NewTProtocolExceptionReadStruct(p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *InvalidOperation) ReadField1(iprot TProtocol) (err TProtocolException) {
+  v12, err13 := iprot.ReadI32()
+  if err13 != nil {
+    return NewTProtocolExceptionReadField(1, "what", p.ThriftName(), err13)
+  }
+  p.What = v12
+  return err
+}
+
+func (p *InvalidOperation) ReadFieldWhat(iprot TProtocol) TProtocolException {
+  return p.ReadField1(iprot)
+}
+
+func (p *InvalidOperation) ReadField2(iprot TProtocol) (err TProtocolException) {
+  v14, err15 := iprot.ReadString()
+  if err15 != nil {
+    return NewTProtocolExceptionReadField(2, "why", p.ThriftName(), err15)
+  }
+  p.Why = v14
+  return err
+}
+
+func (p *InvalidOperation) ReadFieldWhy(iprot TProtocol) TProtocolException {
+  return p.ReadField2(iprot)
+}
+
+func (p *InvalidOperation) Write(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteStructBegin("InvalidOperation")
+  if err != nil {
+    return NewTProtocolExceptionWriteStruct(p.ThriftName(), err)
+  }
+  err = p.WriteField1(oprot)
+  if err != nil {
+    return err
+  }
+  err = p.WriteField2(oprot)
+  if err != nil {
+    return err
+  }
+  err = oprot.WriteFieldStop()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(-1, "STOP", p.ThriftName(), err)
+  }
+  err = oprot.WriteStructEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteStruct(p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *InvalidOperation) WriteField1(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteFieldBegin("what", I32, 1)
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "what", p.ThriftName(), err)
+  }
+  err = oprot.WriteI32(int32(p.What))
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "what", p.ThriftName(), err)
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(1, "what", p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *InvalidOperation) WriteFieldWhat(oprot TProtocol) TProtocolException {
+  return p.WriteField1(oprot)
+}
+
+func (p *InvalidOperation) WriteField2(oprot TProtocol) (err TProtocolException) {
+  err = oprot.WriteFieldBegin("why", STRING, 2)
+  if err != nil {
+    return NewTProtocolExceptionWriteField(2, "why", p.ThriftName(), err)
+  }
+  err = oprot.WriteString(string(p.Why))
+  if err != nil {
+    return NewTProtocolExceptionWriteField(2, "why", p.ThriftName(), err)
+  }
+  err = oprot.WriteFieldEnd()
+  if err != nil {
+    return NewTProtocolExceptionWriteField(2, "why", p.ThriftName(), err)
+  }
+  return err
+}
+
+func (p *InvalidOperation) WriteFieldWhy(oprot TProtocol) TProtocolException {
+  return p.WriteField2(oprot)
+}
+
+func (p *InvalidOperation) TStructName() string {
+  return "InvalidOperation"
+}
+
+func (p *InvalidOperation) ThriftName() string {
+  return "InvalidOperation"
+}
+
+func (p *InvalidOperation) String() string {
+  if p == nil {
+    return "<nil>"
+  }
+  return fmt.Sprintf("InvalidOperation(%+v)", *p)
+}
+
+func (p *InvalidOperation) CompareTo(other interface{}) (int, bool) {
+  if other == nil {
+    return 1, true
+  }
+  data, ok := other.(*InvalidOperation)
+  if !ok {
+    return 0, false
+  }
+  if p.What != data.What {
+    if p.What < data.What {
+      return -1, true
+    }
+    return 1, true
+  }
+  if p.Why != data.Why {
+    if p.Why < data.Why {
+      return -1, true
+    }
+    return 1, true
+  }
+  return 0, true
+}
+
+func (p *InvalidOperation) AttributeByFieldId(id int) interface{} {
+  switch id {
+  default:
+    return nil
+  case 1:
+    return p.What
+  case 2:
+    return p.Why
+  }
+  return nil
+}
+
+func (p *InvalidOperation) TStructFields() TFieldContainer {
+  return NewTFieldContainer([]TField{
+    NewTField("what", I32, 1),
+    NewTField("why", STRING, 2),
+  })
+}
diff --git a/lib/go/thrift/tserver.go b/lib/go/thrift/tserver.go
new file mode 100644
index 0000000..6bc3167
--- /dev/null
+++ b/lib/go/thrift/tserver.go
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "os"
+)
+
+type TServer interface {
+  /**
+   * Core processor
+   */
+  ProcessorFactory() TProcessorFactory
+  /**
+   * Server transport
+   */
+  ServerTransport() TServerTransport
+  /**
+   * Input Transport Factory
+   */
+  InputTransportFactory() TTransportFactory
+  /**
+   * Output Transport Factory
+   */
+  OutputTransportFactory() TTransportFactory
+  /**
+   * Input Protocol Factory
+   */
+  InputProtocolFactory() TProtocolFactory
+  /**
+   * Output Protocol Factory
+   */
+  OutputProtocolFactory() TProtocolFactory
+
+  /**
+   * The run method fires up the server and gets things going.
+   */
+  Serve() os.Error
+  /**
+   * Stop the server. This is optional on a per-implementation basis. Not
+   * all servers are required to be cleanly stoppable.
+   */
+  Stop() os.Error
+}
diff --git a/lib/go/thrift/tserver_socket.go b/lib/go/thrift/tserver_socket.go
new file mode 100644
index 0000000..dc3e748
--- /dev/null
+++ b/lib/go/thrift/tserver_socket.go
@@ -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.
+ */
+
+package thrift
+
+import (
+  "net"
+  "os"
+)
+
+
+type TServerSocket struct {
+  /**
+   * Underlying socket conection object
+   */
+  conn net.Conn
+  /**
+   * Underlying socket conection object
+   */
+  listener net.Listener
+
+  /**
+   * Address to listen on
+   */
+  addr net.Addr
+
+  /**
+   * Client timeout in nanoseconds
+   */
+  nsecClientTimeout int64
+}
+
+type TServerSocketTransportFactory struct {
+  addr              net.Addr
+  nsecClientTimeout int64
+}
+
+func (p *TServerSocketTransportFactory) GetTransport(trans TTransport) TTransport {
+  if trans != nil {
+    t, ok := trans.(*TServerSocket)
+    if ok && t.addr != nil {
+      s, _ := NewTServerSocketAddrTimeout(t.addr, t.nsecClientTimeout)
+      return s
+    }
+  }
+  s, _ := NewTServerSocketAddrTimeout(p.addr, p.nsecClientTimeout)
+  return s
+}
+
+func NewTServerSocketTransportFactory(addr net.Addr, nsecClientTimeout int64) *TServerSocketTransportFactory {
+  return &TServerSocketTransportFactory{addr: addr, nsecClientTimeout: nsecClientTimeout}
+}
+
+func NewTServerSocketConn(conn net.Conn) *TServerSocket {
+  return NewTServerSocketConnTimeout(conn, 0)
+}
+
+func NewTServerSocketConnTimeout(conn net.Conn, nsecClientTimeout int64) *TServerSocket {
+  v := &TServerSocket{conn: conn, addr: conn.LocalAddr(), nsecClientTimeout: nsecClientTimeout}
+  conn.SetTimeout(nsecClientTimeout)
+  return v
+}
+
+func NewTServerSocketAddr(addr net.Addr) (*TServerSocket, TTransportException) {
+  return NewTServerSocketAddrTimeout(addr, 0)
+}
+
+func NewTServerSocketAddrTimeout(addr net.Addr, nsecClientTimeout int64) (*TServerSocket, TTransportException) {
+  s := &TServerSocket{addr: addr, nsecClientTimeout: nsecClientTimeout}
+  return s, nil
+}
+
+func (p *TServerSocket) Listen() (err os.Error) {
+  if p.listener == nil {
+    if p.listener, err = net.Listen("tcp", p.addr.String()); err != nil {
+      return err
+    }
+  }
+  return nil
+}
+
+func (p *TServerSocket) Accept() (TTransport, os.Error) {
+  if p.listener == nil {
+    if err := p.Listen(); err != nil {
+      return nil, NewTTransportExceptionFromOsError(err)
+    }
+    if p.listener == nil {
+      return nil, NewTTransportException(NOT_OPEN, "No underlying server socket")
+    }
+  }
+  conn, err := p.listener.Accept()
+  if err != nil {
+    return nil, NewTTransportExceptionFromOsError(err)
+  }
+  conn.SetTimeout(p.nsecClientTimeout)
+  return NewTSocketConn(conn)
+}
+
+/**
+ * Checks whether the socket is connected.
+ */
+func (p *TServerSocket) IsOpen() bool {
+  return p.listener != nil
+}
+
+/**
+ * Connects the socket, creating a new socket object if necessary.
+ */
+func (p *TServerSocket) Open() os.Error {
+  if !p.IsOpen() {
+    l, err := net.Listen(p.addr.Network(), p.addr.String())
+    if err != nil {
+      return err
+    }
+    p.listener = l
+    return nil
+  }
+  return NewTTransportException(ALREADY_OPEN, "Server socket already open")
+}
+
+/**
+ * Perform a nonblocking read into buffer.
+ */
+func (p *TServerSocket) Read(buf []byte) (int, os.Error) {
+  return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TServerSocket.Read([]byte) is not implemented")
+}
+
+func (p *TServerSocket) ReadAll(buf []byte) (int, os.Error) {
+  return ReadAllTransport(p, buf)
+}
+
+/**
+ * Perform a nonblocking write of the data in buffer;
+ */
+func (p *TServerSocket) Write(buf []byte) (int, os.Error) {
+  return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TServerSocket.Write([]byte) is not implemented")
+}
+
+/**
+ * Flushes the underlying output stream if not null.
+ */
+func (p *TServerSocket) Flush() os.Error {
+  return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "TServerSocket.Flush() is not implemented")
+}
+
+func (p *TServerSocket) Addr() net.Addr {
+  return p.addr
+}
+
+func (p *TServerSocket) Peek() bool {
+  return p.IsOpen()
+}
+
+/**
+ * Closes the socket.
+ */
+func (p *TServerSocket) Close() (err os.Error) {
+  if p.IsOpen() {
+    err := p.listener.Close()
+    if err != nil {
+      return NewTTransportExceptionFromOsError(err)
+    }
+    p.listener = nil
+  }
+  if p.conn != nil {
+    err := p.conn.Close()
+    if err != nil {
+      return NewTTransportExceptionFromOsError(err)
+    }
+    p.conn = nil
+  }
+  return nil
+}
+
+func (p *TServerSocket) Interrupt() os.Error {
+  // TODO(pomack) fix Interrupt as it is probably not right
+  return NewTTransportExceptionFromOsError(p.Close())
+}
diff --git a/lib/go/thrift/tserver_test.go b/lib/go/thrift/tserver_test.go
new file mode 100644
index 0000000..3cbe879
--- /dev/null
+++ b/lib/go/thrift/tserver_test.go
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  "testing"
+)
+
+func TestNothing(t *testing.T) {
+
+}
diff --git a/lib/go/thrift/tserver_transport.go b/lib/go/thrift/tserver_transport.go
new file mode 100644
index 0000000..ef3a462
--- /dev/null
+++ b/lib/go/thrift/tserver_transport.go
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import "os"
+
+/**
+ * Server transport. Object which provides client transports.
+ *
+ */
+type TServerTransport interface {
+  Listen() os.Error
+  Accept() (TTransport, os.Error)
+  Close() os.Error
+
+  /**
+   * Optional method implementation. This signals to the server transport
+   * that it should break out of any accept() or listen() that it is currently
+   * blocked on. This method, if implemented, MUST be thread safe, as it may
+   * be called from a different thread context than the other TServerTransport
+   * methods.
+   */
+  Interrupt() os.Error
+}
diff --git a/lib/go/thrift/tset.go b/lib/go/thrift/tset.go
new file mode 100644
index 0000000..f868109
--- /dev/null
+++ b/lib/go/thrift/tset.go
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "container/list"
+)
+
+/**
+ * Helper class that encapsulates set metadata.
+ *
+ */
+type TSet interface {
+  TContainer
+  ElemType() TType
+  Add(data interface{})
+  Remove(data interface{})
+  Less(other interface{}) bool
+  Front() *list.Element
+  Back() *list.Element
+  Values() []interface{}
+}
+
+type tSet struct {
+  elemType TType
+  size     int
+  l        *list.List
+}
+
+func NewTSet(t TType, s int) TSet {
+  return &tSet{elemType: t, size: s, l: list.New()}
+}
+
+func NewTSetDefault() TSet {
+  return NewTSet(STOP, 0)
+}
+
+func (p *tSet) ElemType() TType {
+  return p.elemType
+}
+
+func (p *tSet) Front() *list.Element {
+  return p.l.Front()
+}
+
+func (p *tSet) Back() *list.Element {
+  return p.l.Back()
+}
+
+func (p *tSet) Len() int {
+  if p.l.Len() != 0 {
+    return p.l.Len()
+  }
+  return p.size
+}
+
+func (p *tSet) Contains(data interface{}) bool {
+  return p.find(data) != nil
+}
+
+func (p *tSet) Add(other interface{}) {
+  if data, ok := p.elemType.CoerceData(other); ok {
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      if cmp, ok := p.elemType.Compare(data, elem.Value); ok && cmp >= 0 {
+        if cmp > 0 {
+          p.l.InsertBefore(data, elem)
+        }
+        return
+      }
+    }
+  }
+}
+
+func (p *tSet) Remove(data interface{}) {
+  elem := p.find(data)
+  if elem != nil {
+    p.l.Remove(elem)
+  }
+}
+
+func (p *tSet) Less(other interface{}) bool {
+  cmp, ok := p.CompareTo(other)
+  return ok && cmp > 0
+}
+
+func (p *tSet) Equals(other interface{}) bool {
+  c, cok := p.CompareTo(other)
+  return cok && c == 0
+}
+
+func (p *tSet) CompareTo(other interface{}) (int, bool) {
+  return TType(SET).Compare(p, other)
+}
+
+func (p *tSet) find(data interface{}) *list.Element {
+  if data == nil {
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      if elem.Value == nil {
+        return elem
+      }
+    }
+    return nil
+  }
+  data, ok := p.elemType.CoerceData(data)
+  if data == nil || !ok {
+    return nil
+  }
+  if p.elemType.IsBaseType() || p.elemType.IsEnum() {
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      if data == elem.Value {
+        return elem
+      }
+    }
+    return nil
+  }
+  if cmp, ok := data.(EqualsOtherInterface); ok {
+    for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+      if cmp.Equals(elem.Value) {
+        return elem
+      }
+    }
+    return nil
+  }
+  switch p.elemType {
+  case MAP:
+    if cmp, ok := data.(EqualsMap); ok {
+      for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+        v := elem.Value
+        if v == nil {
+          continue
+        }
+        if cmp.Equals(v.(TMap)) {
+          return elem
+        }
+      }
+      return nil
+    }
+  case SET:
+    if cmp, ok := data.(EqualsSet); ok {
+      for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+        v := elem.Value
+        if v == nil {
+          continue
+        }
+        if cmp.Equals(v.(TSet)) {
+          return elem
+        }
+      }
+      return nil
+    }
+  case LIST:
+    if cmp, ok := data.(EqualsList); ok {
+      for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+        v := elem.Value
+        if v == nil {
+          continue
+        }
+        if cmp.Equals(v.(TList)) {
+          return elem
+        }
+      }
+      return nil
+    }
+  case STRUCT:
+    if cmp, ok := data.(EqualsStruct); ok {
+      for elem := p.l.Front(); elem != nil; elem = elem.Next() {
+        v := elem.Value
+        if v == nil {
+          continue
+        }
+        if cmp.Equals(v.(TStruct)) {
+          return elem
+        }
+      }
+      return nil
+    }
+  }
+  return nil
+}
+
+func (p *tSet) Values() []interface{} {
+  size := p.l.Len()
+  values := make([]interface{}, size, size)
+  i := 0
+  for v := p.l.Front(); v != nil; v = v.Next() {
+    values[i] = v.Value
+    i++
+  }
+  return values
+}
diff --git a/lib/go/thrift/tsimple_json_protocol.go b/lib/go/thrift/tsimple_json_protocol.go
new file mode 100644
index 0000000..569dd9c
--- /dev/null
+++ b/lib/go/thrift/tsimple_json_protocol.go
@@ -0,0 +1,1281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "bufio"
+  "bytes"
+  "container/vector"
+  "encoding/base64"
+  "fmt"
+  "io"
+  "json"
+  "math"
+  "os"
+  "strconv"
+  "strings"
+)
+
+type _ParseContext int
+
+const (
+  _CONTEXT_IN_TOPLEVEL          _ParseContext = 1
+  _CONTEXT_IN_LIST_FIRST        _ParseContext = 2
+  _CONTEXT_IN_LIST              _ParseContext = 3
+  _CONTEXT_IN_OBJECT_FIRST      _ParseContext = 4
+  _CONTEXT_IN_OBJECT_NEXT_KEY   _ParseContext = 5
+  _CONTEXT_IN_OBJECT_NEXT_VALUE _ParseContext = 6
+)
+
+func (p _ParseContext) String() string {
+  switch p {
+  case _CONTEXT_IN_TOPLEVEL:
+    return "TOPLEVEL"
+  case _CONTEXT_IN_LIST_FIRST:
+    return "LIST-FIRST"
+  case _CONTEXT_IN_LIST:
+    return "LIST"
+  case _CONTEXT_IN_OBJECT_FIRST:
+    return "OBJECT-FIRST"
+  case _CONTEXT_IN_OBJECT_NEXT_KEY:
+    return "OBJECT-NEXT-KEY"
+  case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+    return "OBJECT-NEXT-VALUE"
+  }
+  return "UNKNOWN-PARSE-CONTEXT"
+}
+
+/**
+ * JSON protocol implementation for thrift.
+ *
+ * This protocol produces/consumes a simple output format
+ * suitable for parsing by scripting languages.  It should not be
+ * confused with the full-featured TJSONProtocol.
+ *
+ */
+type TSimpleJSONProtocol struct {
+  //TProtocolBase;
+  trans TTransport
+
+  /**
+   * Stack of nested contexts that we may be in.
+   */
+  parseContextStack vector.IntVector
+  /**
+   * Stack of nested contexts that we may be in.
+   */
+  dumpContext vector.IntVector
+
+  /**
+   * Current context that we are in
+   */
+  writer TTransport
+  reader *bufio.Reader
+}
+
+/**
+ * Constructor
+ */
+func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol {
+  v := &TSimpleJSONProtocol{trans: t,
+    writer: t,
+    reader: bufio.NewReader(t),
+  }
+  v.parseContextStack.Push(int(_CONTEXT_IN_TOPLEVEL))
+  v.dumpContext.Push(int(_CONTEXT_IN_TOPLEVEL))
+  return v
+}
+
+/**
+ * Factory
+ */
+type TSimpleJSONProtocolFactory struct{}
+
+func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol {
+  return NewTSimpleJSONProtocol(trans)
+}
+
+func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory {
+  return &TSimpleJSONProtocolFactory{}
+}
+
+var (
+  JSON_COMMA                   []byte
+  JSON_COLON                   []byte
+  JSON_LBRACE                  []byte
+  JSON_RBRACE                  []byte
+  JSON_LBRACKET                []byte
+  JSON_RBRACKET                []byte
+  JSON_QUOTE                   byte
+  JSON_QUOTE_BYTES             []byte
+  JSON_NULL                    []byte
+  JSON_TRUE                    []byte
+  JSON_FALSE                   []byte
+  JSON_INFINITY                string
+  JSON_NEGATIVE_INFINITY       string
+  JSON_NAN                     string
+  JSON_INFINITY_BYTES          []byte
+  JSON_NEGATIVE_INFINITY_BYTES []byte
+  JSON_NAN_BYTES               []byte
+  json_nonbase_map_elem_bytes  []byte
+)
+
+func init() {
+  JSON_COMMA = []byte{','}
+  JSON_COLON = []byte{':'}
+  JSON_LBRACE = []byte{'{'}
+  JSON_RBRACE = []byte{'}'}
+  JSON_LBRACKET = []byte{'['}
+  JSON_RBRACKET = []byte{']'}
+  JSON_QUOTE = '"'
+  JSON_QUOTE_BYTES = []byte{'"'}
+  JSON_NULL = []byte{'n', 'u', 'l', 'l'}
+  JSON_TRUE = []byte{'t', 'r', 'u', 'e'}
+  JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'}
+  JSON_INFINITY = "Infinity"
+  JSON_NEGATIVE_INFINITY = "-Infinity"
+  JSON_NAN = "NaN"
+  JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
+  JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'}
+  JSON_NAN_BYTES = []byte{'N', 'a', 'N'}
+  json_nonbase_map_elem_bytes = []byte{']', ',', '['}
+}
+
+func JsonQuote(s string) string {
+  b, _ := json.Marshal(s)
+  s1 := string(b)
+  return s1
+}
+
+func JsonUnquote(s string) (string, bool) {
+  s1 := new(string)
+  err := json.Unmarshal([]byte(s), s1)
+  return *s1, err == nil
+}
+
+
+func (p *TSimpleJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) TProtocolException {
+  if e := p.OutputListBegin(); e != nil {
+    return e
+  }
+  if e := p.WriteString(name); e != nil {
+    return e
+  }
+  if e := p.WriteByte(byte(typeId)); e != nil {
+    return e
+  }
+  if e := p.WriteI32(seqId); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteMessageEnd() TProtocolException {
+  return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteStructBegin(name string) TProtocolException {
+  if e := p.OutputObjectBegin(); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteStructEnd() TProtocolException {
+  return p.OutputObjectEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) TProtocolException {
+  if e := p.WriteString(name); e != nil {
+    return e
+  }
+  return nil
+  /*
+    	if e := p.OutputListBegin(); e != nil {
+        return e
+      }
+      if e := p.WriteByte(byte(typeId)); e != nil {
+        return e
+      }
+      return p.WriteI16(id)
+  */
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldEnd() TProtocolException {
+  //return p.OutputListEnd()
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldStop() TProtocolException { return nil }
+
+func (p *TSimpleJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) TProtocolException {
+  if e := p.OutputListBegin(); e != nil {
+    return e
+  }
+  if e := p.WriteByte(byte(keyType)); e != nil {
+    return e
+  }
+  if e := p.WriteByte(byte(valueType)); e != nil {
+    return e
+  }
+  return p.WriteI32(int32(size))
+}
+
+func (p *TSimpleJSONProtocol) WriteMapEnd() TProtocolException {
+  return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteListBegin(elemType TType, size int) TProtocolException {
+  return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TSimpleJSONProtocol) WriteListEnd() TProtocolException {
+  return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteSetBegin(elemType TType, size int) TProtocolException {
+  return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TSimpleJSONProtocol) WriteSetEnd() TProtocolException {
+  return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteBool(b bool) TProtocolException {
+  return p.OutputBool(b)
+}
+
+func (p *TSimpleJSONProtocol) WriteByte(b byte) TProtocolException {
+  return p.WriteI32(int32(b))
+}
+
+func (p *TSimpleJSONProtocol) WriteI16(v int16) TProtocolException {
+  return p.WriteI32(int32(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteI32(v int32) TProtocolException {
+  return p.OutputI64(int64(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteI64(v int64) TProtocolException {
+  return p.OutputI64(int64(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteDouble(v float64) TProtocolException {
+  return p.OutputF64(v)
+}
+
+func (p *TSimpleJSONProtocol) WriteString(v string) TProtocolException {
+  return p.OutputString(v)
+}
+
+func (p *TSimpleJSONProtocol) WriteBinary(v []byte) TProtocolException {
+  // JSON library only takes in a string, 
+  // not an arbitrary byte array, to ensure bytes are transmitted
+  // efficiently we must convert this into a valid JSON string
+  // therefore we use base64 encoding to avoid excessive escaping/quoting
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  if _, e := p.writer.Write(JSON_QUOTE_BYTES); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  writer := base64.NewEncoder(base64.StdEncoding, p.writer)
+  if _, e := writer.Write(v); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  if e := writer.Close(); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  if _, e := p.writer.Write(JSON_QUOTE_BYTES); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  return p.OutputPostValue()
+}
+
+/**
+ * Reading methods.
+ */
+
+func (p *TSimpleJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err TProtocolException) {
+  if isNull, err := p.ParseListBegin(); isNull || err != nil {
+    return name, typeId, seqId, err
+  }
+  if name, err = p.ReadString(); err != nil {
+    return name, typeId, seqId, err
+  }
+  bTypeId, err := p.ReadByte()
+  typeId = TMessageType(bTypeId)
+  if err != nil {
+    return name, typeId, seqId, err
+  }
+  if seqId, err = p.ReadI32(); err != nil {
+    return name, typeId, seqId, err
+  }
+  return name, typeId, seqId, nil
+}
+
+func (p *TSimpleJSONProtocol) ReadMessageEnd() TProtocolException {
+  return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadStructBegin() (name string, err TProtocolException) {
+  _, err = p.ParseObjectStart()
+  return "", err
+}
+
+func (p *TSimpleJSONProtocol) ReadStructEnd() TProtocolException {
+  return p.ParseObjectEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadFieldBegin() (string, TType, int16, TProtocolException) {
+  if err := p.ParsePreValue(); err != nil {
+    return "", STOP, 0, err
+  }
+  if p.reader.Buffered() < 1 {
+    return "", STOP, 0, nil
+  }
+  b, _ := p.reader.Peek(1)
+  if len(b) > 0 {
+    switch b[0] {
+    case JSON_RBRACE[0]:
+      return "", STOP, 0, nil
+    case JSON_QUOTE:
+      p.reader.ReadByte()
+      name, err := p.ParseStringBody()
+      if err != nil {
+        return name, STOP, 0, err
+      }
+      return name, GENERIC, -1, p.ParsePostValue()
+      /*
+         if err = p.ParsePostValue(); err != nil {
+           return name, STOP, 0, err
+         }
+         if isNull, err := p.ParseListBegin(); isNull || err != nil {
+           return name, STOP, 0, err
+         }
+         bType, err := p.ReadByte()
+         thetype := TType(bType)
+         if err != nil {
+           return name, thetype, 0, err
+         }
+         id, err := p.ReadI16()
+         return name, thetype, id, err
+      */
+    }
+    return "", STOP, 0, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected \"}\" or '\"', but found: '", string(b), "'"))
+  }
+  return "", STOP, 0, NewTProtocolExceptionFromOsError(os.EOF)
+}
+
+func (p *TSimpleJSONProtocol) ReadFieldEnd() TProtocolException {
+  return nil
+  //return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e TProtocolException) {
+  if isNull, e := p.ParseListBegin(); isNull || e != nil {
+    return VOID, VOID, 0, e
+  }
+
+  // read keyType
+  bKeyType, e := p.ReadByte()
+  keyType = TType(bKeyType)
+  if e != nil {
+    return keyType, valueType, size, e
+  }
+
+  // read valueType
+  bValueType, e := p.ReadByte()
+  valueType = TType(bValueType)
+  if e != nil {
+    return keyType, valueType, size, e
+  }
+
+  // read size
+  iSize, err := p.ReadI64()
+  size = int(iSize)
+  return keyType, valueType, size, err
+}
+
+func (p *TSimpleJSONProtocol) ReadMapEnd() TProtocolException {
+  return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadListBegin() (elemType TType, size int, e TProtocolException) {
+  return p.ParseElemListBegin()
+}
+
+func (p *TSimpleJSONProtocol) ReadListEnd() TProtocolException {
+  return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadSetBegin() (elemType TType, size int, e TProtocolException) {
+  return p.ParseElemListBegin()
+}
+
+func (p *TSimpleJSONProtocol) ReadSetEnd() TProtocolException {
+  return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadBool() (bool, TProtocolException) {
+  var value bool
+  if err := p.ParsePreValue(); err != nil {
+    return value, err
+  }
+  b, _ := p.reader.Peek(len(JSON_FALSE))
+  if len(b) > 0 {
+    switch b[0] {
+    case JSON_TRUE[0]:
+      if string(b[0:len(JSON_TRUE)]) == string(JSON_TRUE) {
+        p.reader.Read(b[0:len(JSON_TRUE)])
+        value = true
+      } else {
+        return value, NewTProtocolException(INVALID_DATA, "Expected \"true\" but found: "+string(b))
+      }
+      break
+    case JSON_FALSE[0]:
+      if string(b[0:len(JSON_FALSE)]) == string(JSON_FALSE) {
+        p.reader.Read(b[0:len(JSON_FALSE)])
+        value = false
+      } else {
+        return value, NewTProtocolException(INVALID_DATA, "Expected \"false\" but found: "+string(b))
+      }
+      break
+    case JSON_NULL[0]:
+      if string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+        p.reader.Read(b[0:len(JSON_NULL)])
+        value = false
+      } else {
+        return value, NewTProtocolException(INVALID_DATA, "Expected \"null\" but found: "+string(b))
+      }
+    default:
+      return value, NewTProtocolException(INVALID_DATA, "Expected \"true\", \"false\", or \"null\" but found: "+string(b))
+    }
+  }
+  return value, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ReadByte() (byte, TProtocolException) {
+  v, err := p.ReadI64()
+  return byte(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI16() (int16, TProtocolException) {
+  v, err := p.ReadI64()
+  return int16(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI32() (int32, TProtocolException) {
+  v, err := p.ReadI64()
+  return int32(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI64() (int64, TProtocolException) {
+  v, _, err := p.ParseI64()
+  return v, err
+}
+
+func (p *TSimpleJSONProtocol) ReadDouble() (float64, TProtocolException) {
+  v, _, err := p.ParseF64()
+  return v, err
+}
+
+func (p *TSimpleJSONProtocol) ReadString() (string, TProtocolException) {
+  var v string
+  if err := p.ParsePreValue(); err != nil {
+    return v, err
+  }
+  b, _ := p.reader.Peek(len(JSON_NULL))
+  if len(b) > 0 && b[0] == JSON_QUOTE {
+    p.reader.ReadByte()
+    value, err := p.ParseStringBody()
+    v = value
+    if err != nil {
+      return v, err
+    }
+  } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+    _, err := p.reader.Read(b[0:len(JSON_NULL)])
+    if err != nil {
+      return v, NewTProtocolExceptionFromOsError(err)
+    }
+  } else {
+    return v, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected a JSON string, found ", string(b)))
+  }
+  return v, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, TProtocolException) {
+  var v []byte
+  if err := p.ParsePreValue(); err != nil {
+    return nil, err
+  }
+  b, _ := p.reader.Peek(len(JSON_NULL))
+  if len(b) > 0 && b[0] == JSON_QUOTE {
+    p.reader.ReadByte()
+    value, err := p.ParseBase64EncodedBody()
+    v = value
+    if err != nil {
+      return v, err
+    }
+  } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+    _, err := p.reader.Read(b[0:len(JSON_NULL)])
+    if err != nil {
+      return v, NewTProtocolExceptionFromOsError(err)
+    }
+  } else {
+    return v, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected a JSON string, found ", string(b)))
+  }
+  return v, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) Flush() (err TProtocolException) {
+  return NewTProtocolExceptionFromOsError(p.writer.Flush())
+}
+
+func (p *TSimpleJSONProtocol) Skip(fieldType TType) (err TProtocolException) {
+  return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TSimpleJSONProtocol) Transport() TTransport {
+  return p.trans
+}
+
+
+func (p *TSimpleJSONProtocol) OutputPreValue() TProtocolException {
+  cxt := _ParseContext(p.dumpContext.Last())
+  switch cxt {
+  case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+    if _, e := p.writer.Write(JSON_COMMA); e != nil {
+      return NewTProtocolExceptionFromOsError(e)
+    }
+    break
+  case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+    if _, e := p.writer.Write(JSON_COLON); e != nil {
+      return NewTProtocolExceptionFromOsError(e)
+    }
+    break
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputPostValue() TProtocolException {
+  cxt := _ParseContext(p.dumpContext.Last())
+  switch cxt {
+  case _CONTEXT_IN_LIST_FIRST:
+    p.dumpContext.Pop()
+    p.dumpContext.Push(int(_CONTEXT_IN_LIST))
+    break
+  case _CONTEXT_IN_OBJECT_FIRST:
+    p.dumpContext.Pop()
+    p.dumpContext.Push(int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+    break
+  case _CONTEXT_IN_OBJECT_NEXT_KEY:
+    p.dumpContext.Pop()
+    p.dumpContext.Push(int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+    break
+  case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+    p.dumpContext.Pop()
+    p.dumpContext.Push(int(_CONTEXT_IN_OBJECT_NEXT_KEY))
+    break
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputBool(value bool) TProtocolException {
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  var v string
+  if value {
+    v = string(JSON_TRUE)
+  } else {
+    v = string(JSON_FALSE)
+  }
+  switch _ParseContext(p.dumpContext.Last()) {
+  case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+    v = JsonQuote(v)
+  default:
+  }
+  if e := p.OutputStringData(v); e != nil {
+    return e
+  }
+  return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputNull() TProtocolException {
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  if _, e := p.writer.Write(JSON_NULL); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputF64(value float64) TProtocolException {
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  var v string
+  if math.IsNaN(value) {
+    v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE)
+  } else if math.IsInf(value, 1) {
+    v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE)
+  } else if math.IsInf(value, -1) {
+    v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE)
+  } else {
+    v = strconv.Ftoa64(value, 'g', -1)
+    switch _ParseContext(p.dumpContext.Last()) {
+    case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+      v = string(JSON_QUOTE) + v + string(JSON_QUOTE)
+    default:
+    }
+  }
+  if e := p.OutputStringData(v); e != nil {
+    return e
+  }
+  return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputI64(value int64) TProtocolException {
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  v := strconv.Itoa64(value)
+  switch _ParseContext(p.dumpContext.Last()) {
+  case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+    v = JsonQuote(v)
+  default:
+  }
+  if e := p.OutputStringData(v); e != nil {
+    return e
+  }
+  return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputString(s string) TProtocolException {
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  if e := p.OutputStringData(JsonQuote(s)); e != nil {
+    return e
+  }
+  return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputStringData(s string) TProtocolException {
+  _, e := io.Copyn(p.writer, strings.NewReader(s), int64(len(s)))
+  return NewTProtocolExceptionFromOsError(e)
+}
+
+func (p *TSimpleJSONProtocol) OutputObjectBegin() TProtocolException {
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  if _, e := p.writer.Write(JSON_LBRACE); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  p.dumpContext.Push(int(_CONTEXT_IN_OBJECT_FIRST))
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputObjectEnd() TProtocolException {
+  if _, e := p.writer.Write(JSON_RBRACE); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  p.dumpContext.Pop()
+  if e := p.OutputPostValue(); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputListBegin() TProtocolException {
+  if e := p.OutputPreValue(); e != nil {
+    return e
+  }
+  if _, e := p.writer.Write(JSON_LBRACKET); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  p.dumpContext.Push(int(_CONTEXT_IN_LIST_FIRST))
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputListEnd() TProtocolException {
+  if _, e := p.writer.Write(JSON_RBRACKET); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  p.dumpContext.Pop()
+  if e := p.OutputPostValue(); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) TProtocolException {
+  if e := p.OutputListBegin(); e != nil {
+    return e
+  }
+  if e := p.WriteByte(byte(elemType)); e != nil {
+    return e
+  }
+  if e := p.WriteI64(int64(size)); e != nil {
+    return e
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) ParsePreValue() TProtocolException {
+  if e := p.readNonSignificantWhitespace(); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  cxt := _ParseContext(p.parseContextStack.Last())
+  if p.reader.Buffered() < 1 {
+    return nil
+  }
+  b, _ := p.reader.Peek(1)
+  switch cxt {
+  case _CONTEXT_IN_LIST:
+    if len(b) > 0 {
+      switch b[0] {
+      case JSON_RBRACKET[0]:
+        return nil
+      case JSON_COMMA[0]:
+        p.reader.ReadByte()
+        if e := p.readNonSignificantWhitespace(); e != nil {
+          return NewTProtocolExceptionFromOsError(e)
+        }
+        return nil
+      default:
+        return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected \"]\" or \",\" in list context, but found \"", string(b), "\""))
+      }
+    }
+    break
+  case _CONTEXT_IN_OBJECT_NEXT_KEY:
+    if len(b) > 0 {
+      switch b[0] {
+      case JSON_RBRACE[0]:
+        return nil
+      case JSON_COMMA[0]:
+        p.reader.ReadByte()
+        if e := p.readNonSignificantWhitespace(); e != nil {
+          return NewTProtocolExceptionFromOsError(e)
+        }
+        return nil
+      default:
+        return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected \"}\" or \",\" in object context, but found \"", string(b), "\""))
+      }
+    }
+    break
+  case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+    if len(b) > 0 {
+      switch b[0] {
+      case JSON_COLON[0]:
+        p.reader.ReadByte()
+        if e := p.readNonSignificantWhitespace(); e != nil {
+          return NewTProtocolExceptionFromOsError(e)
+        }
+        return nil
+      default:
+        return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected \":\" in object context, but found \"", string(b), "\""))
+      }
+    }
+    break
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) ParsePostValue() TProtocolException {
+  if e := p.readNonSignificantWhitespace(); e != nil {
+    return NewTProtocolExceptionFromOsError(e)
+  }
+  cxt := _ParseContext(p.parseContextStack.Last())
+  switch cxt {
+  case _CONTEXT_IN_LIST_FIRST:
+    p.parseContextStack.Pop()
+    p.parseContextStack.Push(int(_CONTEXT_IN_LIST))
+    break
+  case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+    p.parseContextStack.Pop()
+    p.parseContextStack.Push(int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+    break
+  case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+    p.parseContextStack.Pop()
+    p.parseContextStack.Push(int(_CONTEXT_IN_OBJECT_NEXT_KEY))
+    break
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() os.Error {
+  for p.reader.Buffered() > 0 {
+    b, _ := p.reader.Peek(1)
+    if len(b) < 1 {
+      return nil
+    }
+    switch b[0] {
+    case ' ', '\r', '\n', '\t':
+      p.reader.ReadByte()
+      continue
+    default:
+      break
+    }
+    break
+  }
+  return nil
+}
+
+func (p *TSimpleJSONProtocol) ParseStringBody() (string, TProtocolException) {
+  line, err := p.reader.ReadString(JSON_QUOTE)
+  if err != nil {
+    return "", NewTProtocolExceptionFromOsError(err)
+  }
+  l := len(line)
+  // count number of escapes to see if we need to keep going
+  i := 1
+  for ; i < l; i++ {
+    if line[l-i-1] != '\\' {
+      break
+    }
+  }
+  if i&0x01 == 1 {
+    v, ok := JsonUnquote(string(JSON_QUOTE) + line)
+    if !ok {
+      return "", NewTProtocolExceptionFromOsError(err)
+    }
+    return v, nil
+  }
+  s, err := p.ParseQuotedStringBody()
+  if err != nil {
+    return "", NewTProtocolExceptionFromOsError(err)
+  }
+  str := string(JSON_QUOTE) + line + s
+  v, ok := JsonUnquote(str)
+  if !ok {
+    return "", NewTProtocolException(INVALID_DATA, "Unable to parse as JSON string "+str)
+  }
+  return v, nil
+}
+
+func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, TProtocolException) {
+  line, err := p.reader.ReadString(JSON_QUOTE)
+  if err != nil {
+    return "", NewTProtocolExceptionFromOsError(err)
+  }
+  l := len(line)
+  // count number of escapes to see if we need to keep going
+  i := 1
+  for ; i < l; i++ {
+    if line[l-i-1] != '\\' {
+      break
+    }
+  }
+  if i&0x01 == 1 {
+    return line, nil
+  }
+  s, err := p.ParseQuotedStringBody()
+  if err != nil {
+    return "", NewTProtocolExceptionFromOsError(err)
+  }
+  v := line + s
+  return v, nil
+}
+
+func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, TProtocolException) {
+  line, err := p.reader.ReadBytes(JSON_QUOTE)
+  if err != nil {
+    return line, NewTProtocolExceptionFromOsError(err)
+  }
+  line2 := line[0 : len(line)-1]
+  l := len(line2)
+  output := make([]byte, base64.StdEncoding.DecodedLen(l))
+  n, err := base64.StdEncoding.Decode(output, line2)
+  return output[0:n], NewTProtocolExceptionFromOsError(err)
+}
+
+func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, TProtocolException) {
+  if err := p.ParsePreValue(); err != nil {
+    return 0, false, err
+  }
+  var value int64
+  var isnull bool
+  b, _ := p.reader.Peek(len(JSON_NULL))
+  if len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
+    p.reader.Read(b[0:len(JSON_NULL)])
+    isnull = true
+  } else {
+    num, err := p.readNumeric()
+    isnull = (num == nil)
+    if !isnull {
+      value = num.Int64()
+    }
+    if err != nil {
+      return value, isnull, err
+    }
+  }
+  return value, isnull, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, TProtocolException) {
+  if err := p.ParsePreValue(); err != nil {
+    return 0, false, err
+  }
+  var value float64
+  var isnull bool
+  b, _ := p.reader.Peek(len(JSON_NULL))
+  if len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
+    p.reader.Read(b[0:len(JSON_NULL)])
+    isnull = true
+  } else {
+    num, err := p.readNumeric()
+    isnull = (num == nil)
+    if !isnull {
+      value = num.Float64()
+    }
+    if err != nil {
+      return value, isnull, err
+    }
+  }
+  return value, isnull, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, TProtocolException) {
+  if err := p.ParsePreValue(); err != nil {
+    return false, err
+  }
+  b, _ := p.reader.Peek(len(JSON_NULL))
+  if len(b) > 0 && b[0] == JSON_LBRACE[0] {
+    p.reader.ReadByte()
+    p.parseContextStack.Push(int(_CONTEXT_IN_OBJECT_FIRST))
+    return false, nil
+  } else if len(b) >= len(JSON_NULL) && string(b[0:len(JSON_NULL)]) == string(JSON_NULL) {
+    return true, nil
+  }
+  return false, NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected '{' or null, but found '", string(b), "'"))
+}
+
+func (p *TSimpleJSONProtocol) ParseObjectEnd() TProtocolException {
+  if isNull, err := p.readIfNull(); isNull || err != nil {
+    return err
+  }
+  cxt := _ParseContext(p.parseContextStack.Last())
+  if cxt != _CONTEXT_IN_OBJECT_FIRST && cxt != _CONTEXT_IN_OBJECT_NEXT_KEY {
+    return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expected to be in the Object Context, but not in Object Context"))
+  }
+  line, err := p.reader.ReadString(JSON_RBRACE[0])
+  if err != nil {
+    return NewTProtocolExceptionFromOsError(err)
+  }
+  for _, char := range line {
+    switch char {
+    default:
+      return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expecting end of object \"}\", but found: \"", line, "\""))
+    case ' ', '\n', '\r', '\t', '}':
+      break
+    }
+  }
+  p.parseContextStack.Pop()
+  return p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ParseListBegin() (bool, TProtocolException) {
+  if e := p.ParsePreValue(); e != nil {
+    return false, e
+  }
+  b, e := p.reader.Peek(len(JSON_NULL))
+  if e == nil && len(b) >= 1 && b[0] == JSON_LBRACKET[0] {
+    p.parseContextStack.Push(int(_CONTEXT_IN_LIST_FIRST))
+    p.reader.ReadByte()
+    return false, nil
+  } else if e == nil && len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
+    return true, nil
+  }
+  return false, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Expected 'null' or '{', received '%q'", b))
+}
+
+func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e TProtocolException) {
+  if isNull, e := p.ParseListBegin(); isNull || e != nil {
+    return VOID, 0, e
+  }
+  bElemType, err := p.ReadByte()
+  elemType = TType(bElemType)
+  if err != nil {
+    return elemType, size, err
+  }
+  nSize, err2 := p.ReadI64()
+  size = int(nSize)
+  return elemType, size, err2
+}
+
+func (p *TSimpleJSONProtocol) ParseListEnd() TProtocolException {
+  if isNull, err := p.readIfNull(); isNull || err != nil {
+    return err
+  }
+  if _ParseContext(p.parseContextStack.Last()) != _CONTEXT_IN_LIST {
+    return NewTProtocolException(INVALID_DATA, "Expected to be in the List Context, but not in List Context")
+  }
+  line, err := p.reader.ReadString(JSON_RBRACKET[0])
+  if err != nil {
+    return NewTProtocolExceptionFromOsError(err)
+  }
+  for _, char := range line {
+    switch char {
+    default:
+      return NewTProtocolException(INVALID_DATA, fmt.Sprint("Expecting end of list \"]\", but found: \"", line, "\""))
+    case ' ', '\n', '\r', '\t', int(JSON_RBRACKET[0]):
+      break
+    }
+  }
+  p.parseContextStack.Pop()
+  return p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, TProtocolException) {
+  e := p.readNonSignificantWhitespace()
+  if e != nil {
+    return nil, VOID, NewTProtocolExceptionFromOsError(e)
+  }
+  b, e := p.reader.Peek(10)
+  if len(b) > 0 {
+    c := b[0]
+    switch c {
+    case JSON_NULL[0]:
+      buf := make([]byte, len(JSON_NULL))
+      _, e := p.reader.Read(buf)
+      if e != nil {
+        return nil, VOID, NewTProtocolExceptionFromOsError(e)
+      }
+      if string(JSON_NULL) != string(buf) {
+        e := NewTProtocolException(INVALID_DATA, "Expected '"+string(JSON_NULL)+"' but found '"+string(buf)+"' while parsing JSON.")
+        return nil, VOID, e
+      }
+      return nil, VOID, nil
+    case JSON_QUOTE:
+      p.reader.ReadByte()
+      v, e := p.ParseStringBody()
+      if e != nil {
+        return v, UTF8, NewTProtocolExceptionFromOsError(e)
+      }
+      if v == JSON_INFINITY {
+        return INFINITY, DOUBLE, nil
+      } else if v == JSON_NEGATIVE_INFINITY {
+        return NEGATIVE_INFINITY, DOUBLE, nil
+      } else if v == JSON_NAN {
+        return NAN, DOUBLE, nil
+      }
+      return v, UTF8, nil
+    case JSON_TRUE[0]:
+      buf := make([]byte, len(JSON_TRUE))
+      _, e := p.reader.Read(buf)
+      if e != nil {
+        return true, BOOL, NewTProtocolExceptionFromOsError(e)
+      }
+      if string(JSON_TRUE) != string(buf) {
+        e := NewTProtocolException(INVALID_DATA, "Expected '"+string(JSON_TRUE)+"' but found '"+string(buf)+"' while parsing JSON.")
+        return true, BOOL, NewTProtocolExceptionFromOsError(e)
+      }
+      return true, BOOL, nil
+    case JSON_FALSE[0]:
+      buf := make([]byte, len(JSON_FALSE))
+      _, e := p.reader.Read(buf)
+      if e != nil {
+        return false, BOOL, NewTProtocolExceptionFromOsError(e)
+      }
+      if string(JSON_FALSE) != string(buf) {
+        e := NewTProtocolException(INVALID_DATA, "Expected '"+string(JSON_FALSE)+"' but found '"+string(buf)+"' while parsing JSON.")
+        return false, BOOL, NewTProtocolExceptionFromOsError(e)
+      }
+      return false, BOOL, nil
+    case JSON_LBRACKET[0]:
+      _, e := p.reader.ReadByte()
+      return make([]interface{}, 0), LIST, NewTProtocolExceptionFromOsError(e)
+    case JSON_LBRACE[0]:
+      _, e := p.reader.ReadByte()
+      return make(map[string]interface{}), STRUCT, NewTProtocolExceptionFromOsError(e)
+    case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-', JSON_INFINITY[0], JSON_NAN[0]:
+      // assume numeric
+      v, e := p.readNumeric()
+      return v, DOUBLE, e
+    default:
+      return nil, VOID, NewTProtocolException(INVALID_DATA, "Expected element in list but found '"+string(c)+"' while parsing JSON.")
+    }
+  }
+  return nil, VOID, NewTProtocolException(INVALID_DATA, "Cannot read a single element while parsing JSON.")
+
+}
+
+
+func (p *TSimpleJSONProtocol) readIfNull() (bool, TProtocolException) {
+  cont := true
+  for p.reader.Buffered() > 0 && cont {
+    b, _ := p.reader.Peek(1)
+    if len(b) < 1 {
+      return false, nil
+    }
+    switch b[0] {
+    default:
+      return false, nil
+    case JSON_NULL[0]:
+      cont = false
+      break
+    case ' ', '\n', '\r', '\t':
+      p.reader.ReadByte()
+      break
+    }
+  }
+  if p.reader.Buffered() == 0 {
+    return false, nil
+  }
+  b, _ := p.reader.Peek(len(JSON_NULL))
+  if string(b) == string(JSON_NULL) {
+    p.reader.Read(b[0:len(JSON_NULL)])
+    return true, nil
+  }
+  return false, nil
+}
+
+func (p *TSimpleJSONProtocol) readQuoteIfNext() {
+  if p.reader.Buffered() < 1 {
+    return
+  }
+  b, _ := p.reader.Peek(1)
+  if len(b) > 0 && b[0] == JSON_QUOTE {
+    p.reader.ReadByte()
+  }
+}
+
+func (p *TSimpleJSONProtocol) readNumeric() (Numeric, TProtocolException) {
+  isNull, err := p.readIfNull()
+  if isNull || err != nil {
+    return NUMERIC_NULL, err
+  }
+  hasDecimalPoint := false
+  nextCanBeSign := true
+  hasE := false
+  MAX_LEN := 40
+  buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN))
+  continueFor := true
+  inQuotes := false
+  for continueFor {
+    c, err := p.reader.ReadByte()
+    if err != nil {
+      if err == os.EOF {
+        break
+      }
+      return NUMERIC_NULL, NewTProtocolExceptionFromOsError(err)
+    }
+    switch c {
+    case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+      buf.WriteByte(c)
+      nextCanBeSign = false
+    case '.':
+      if hasDecimalPoint {
+        return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number with multiple decimal points '%s.'", buf.String()))
+      }
+      if hasE {
+        return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number with decimal points in the exponent '%s.'", buf.String()))
+      }
+      buf.WriteByte(c)
+      hasDecimalPoint, nextCanBeSign = true, false
+    case 'e', 'E':
+      if hasE {
+        return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c))
+      }
+      buf.WriteByte(c)
+      hasE, nextCanBeSign = true, true
+    case '-', '+':
+      if !nextCanBeSign {
+        return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprint("Negative sign within number"))
+      }
+      buf.WriteByte(c)
+      nextCanBeSign = false
+    case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]:
+      p.reader.UnreadByte()
+      continueFor = false
+    case JSON_NAN[0]:
+      if buf.Len() == 0 {
+        buffer := make([]byte, len(JSON_NAN))
+        buffer[0] = c
+        _, e := p.reader.Read(buffer[1:])
+        if e != nil {
+          return NUMERIC_NULL, NewTProtocolExceptionFromOsError(e)
+        }
+        if JSON_NAN != string(buffer) {
+          e := NewTProtocolException(INVALID_DATA, "Expected '"+JSON_NAN+"' but found '"+string(buffer)+"' while parsing JSON.")
+          return NUMERIC_NULL, e
+        }
+        if inQuotes {
+          p.readQuoteIfNext()
+        }
+        return NAN, nil
+      } else {
+        return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number starting with character '%c'", c))
+      }
+    case JSON_INFINITY[0]:
+      if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') {
+        buffer := make([]byte, len(JSON_INFINITY))
+        buffer[0] = c
+        _, e := p.reader.Read(buffer[1:])
+        if e != nil {
+          return NUMERIC_NULL, NewTProtocolExceptionFromOsError(e)
+        }
+        if JSON_INFINITY != string(buffer) {
+          e := NewTProtocolException(INVALID_DATA, "Expected '"+JSON_INFINITY+"' but found '"+string(buffer)+"' while parsing JSON.")
+          return NUMERIC_NULL, e
+        }
+        if inQuotes {
+          p.readQuoteIfNext()
+        }
+        return INFINITY, nil
+      } else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] {
+        buffer := make([]byte, len(JSON_NEGATIVE_INFINITY))
+        buffer[0] = JSON_NEGATIVE_INFINITY[0]
+        buffer[1] = c
+        _, e := p.reader.Read(buffer[2:])
+        if e != nil {
+          return NUMERIC_NULL, NewTProtocolExceptionFromOsError(e)
+        }
+        if JSON_NEGATIVE_INFINITY != string(buffer) {
+          e := NewTProtocolException(INVALID_DATA, "Expected '"+JSON_NEGATIVE_INFINITY+"' but found '"+string(buffer)+"' while parsing JSON.")
+          return NUMERIC_NULL, e
+        }
+        if inQuotes {
+          p.readQuoteIfNext()
+        }
+        return NEGATIVE_INFINITY, nil
+      } else {
+        return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String()))
+      }
+    case JSON_QUOTE:
+      if !inQuotes {
+        inQuotes = true
+      } else {
+        break
+      }
+    default:
+      return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprintf("Unable to parse number starting with character '%c'", c))
+    }
+  }
+  if buf.Len() == 0 {
+    return NUMERIC_NULL, NewTProtocolException(INVALID_DATA, fmt.Sprint("Unable to parse number from empty string ''"))
+  }
+  return NewNumericFromJSONString(buf.String(), false), nil
+}
diff --git a/lib/go/thrift/tsimple_json_protocol_test.go b/lib/go/thrift/tsimple_json_protocol_test.go
new file mode 100644
index 0000000..e57d55b
--- /dev/null
+++ b/lib/go/thrift/tsimple_json_protocol_test.go
@@ -0,0 +1,662 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "encoding/base64"
+  "fmt"
+  "json"
+  "math"
+  "strconv"
+  "strings"
+  "testing"
+)
+
+func TestWriteSimpleJSONProtocolBool(t *testing.T) {
+  thetype := "boolean"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  for _, value := range BOOL_VALUES {
+    if e := p.WriteBool(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := false
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadSimpleJSONProtocolBool(t *testing.T) {
+  thetype := "boolean"
+  for _, value := range BOOL_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTSimpleJSONProtocol(trans)
+    if value {
+      trans.Write(JSON_TRUE)
+    } else {
+      trans.Write(JSON_FALSE)
+    }
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadBool()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteSimpleJSONProtocolByte(t *testing.T) {
+  thetype := "byte"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  for _, value := range BYTE_VALUES {
+    if e := p.WriteByte(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := byte(0)
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadSimpleJSONProtocolByte(t *testing.T) {
+  thetype := "byte"
+  for _, value := range BYTE_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTSimpleJSONProtocol(trans)
+    trans.WriteString(strconv.Itoa(int(value)))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadByte()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteSimpleJSONProtocolI16(t *testing.T) {
+  thetype := "int16"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  for _, value := range INT16_VALUES {
+    if e := p.WriteI16(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := int16(0)
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadSimpleJSONProtocolI16(t *testing.T) {
+  thetype := "int16"
+  for _, value := range INT16_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTSimpleJSONProtocol(trans)
+    trans.WriteString(strconv.Itoa(int(value)))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadI16()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteSimpleJSONProtocolI32(t *testing.T) {
+  thetype := "int32"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  for _, value := range INT32_VALUES {
+    if e := p.WriteI32(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := int32(0)
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadSimpleJSONProtocolI32(t *testing.T) {
+  thetype := "int32"
+  for _, value := range INT32_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTSimpleJSONProtocol(trans)
+    trans.WriteString(strconv.Itoa(int(value)))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadI32()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteSimpleJSONProtocolI64(t *testing.T) {
+  thetype := "int64"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  for _, value := range INT64_VALUES {
+    if e := p.WriteI64(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s != fmt.Sprint(value) {
+      t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+    }
+    v := int64(0)
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadSimpleJSONProtocolI64(t *testing.T) {
+  thetype := "int64"
+  for _, value := range INT64_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTSimpleJSONProtocol(trans)
+    trans.WriteString(strconv.Itoa64(value))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadI64()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteSimpleJSONProtocolDouble(t *testing.T) {
+  thetype := "double"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  for _, value := range DOUBLE_VALUES {
+    if e := p.WriteDouble(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if math.IsInf(value, 1) {
+      if s != JsonQuote(JSON_INFINITY) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_INFINITY))
+      }
+    } else if math.IsInf(value, -1) {
+      if s != JsonQuote(JSON_NEGATIVE_INFINITY) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_NEGATIVE_INFINITY))
+      }
+    } else if math.IsNaN(value) {
+      if s != JsonQuote(JSON_NAN) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, expected: %v", thetype, value, s, JsonQuote(JSON_NAN))
+      }
+    } else {
+      if s != fmt.Sprint(value) {
+        t.Fatalf("Bad value for %s %v: %s", thetype, value, s)
+      }
+      v := float64(0)
+      if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+      }
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadSimpleJSONProtocolDouble(t *testing.T) {
+  thetype := "double"
+  for _, value := range DOUBLE_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTSimpleJSONProtocol(trans)
+    n := NewNumericFromDouble(value)
+    trans.WriteString(n.String())
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadDouble()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if math.IsInf(value, 1) {
+      if !math.IsInf(v, 1) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+      }
+    } else if math.IsInf(value, -1) {
+      if !math.IsInf(v, -1) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+      }
+    } else if math.IsNaN(value) {
+      if !math.IsNaN(v) {
+        t.Fatalf("Bad value for %s %v, wrote: %v, received: %v", thetype, value, s, v)
+      }
+    } else {
+      if v != value {
+        t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+      }
+      if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+      }
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteSimpleJSONProtocolString(t *testing.T) {
+  thetype := "string"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  for _, value := range STRING_VALUES {
+    if e := p.WriteString(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if e := p.Flush(); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+    }
+    s := trans.String()
+    if s[0] != '"' || s[len(s)-1] != '"' {
+      t.Fatalf("Bad value for %s '%v', wrote '%v', expected: %v", thetype, value, s, fmt.Sprint("\"", value, "\""))
+    }
+    v := new(string)
+    if err := json.Unmarshal([]byte(s), v); err != nil || *v != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v)
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestReadSimpleJSONProtocolString(t *testing.T) {
+  thetype := "string"
+  for _, value := range STRING_VALUES {
+    trans := NewTMemoryBuffer()
+    p := NewTSimpleJSONProtocol(trans)
+    trans.WriteString(JsonQuote(value))
+    trans.Flush()
+    s := trans.String()
+    v, e := p.ReadString()
+    if e != nil {
+      t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+    }
+    if v != value {
+      t.Fatalf("Bad value for %s value %v, wrote: %v, received: %v", thetype, value, s, v)
+    }
+    v1 := new(string)
+    if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != value {
+      t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1)
+    }
+    trans.Reset()
+    trans.Close()
+  }
+}
+
+func TestWriteSimpleJSONProtocolBinary(t *testing.T) {
+  thetype := "binary"
+  value := protocol_bdata
+  b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata)))
+  base64.StdEncoding.Encode(b64value, value)
+  b64String := string(b64value)
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  if e := p.WriteBinary(value); e != nil {
+    t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+  }
+  if e := p.Flush(); e != nil {
+    t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.String())
+  }
+  s := trans.String()
+  if s != fmt.Sprint("\"", b64String, "\"") {
+    t.Fatalf("Bad value for %s %v\n  wrote: %v\nexpected: %v", thetype, value, s, "\""+b64String+"\"")
+  }
+  v1 := new(string)
+  if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != b64String {
+    t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1)
+  }
+  trans.Close()
+}
+
+func TestReadSimpleJSONProtocolBinary(t *testing.T) {
+  thetype := "binary"
+  value := protocol_bdata
+  b64value := make([]byte, base64.StdEncoding.EncodedLen(len(protocol_bdata)))
+  base64.StdEncoding.Encode(b64value, value)
+  b64String := string(b64value)
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  trans.WriteString(JsonQuote(b64String))
+  trans.Flush()
+  s := trans.String()
+  v, e := p.ReadBinary()
+  if e != nil {
+    t.Fatalf("Unable to read %s value %v due to error: %s", thetype, value, e.String())
+  }
+  if len(v) != len(value) {
+    t.Fatalf("Bad value for %s value length %v, wrote: %v, received length: %v", thetype, len(value), s, len(v))
+  }
+  for i := 0; i < len(v); i++ {
+    if v[i] != value[i] {
+      t.Fatalf("Bad value for %s at index %d value %v, wrote: %v, received: %v", thetype, i, value[i], s, v[i])
+    }
+  }
+  v1 := new(string)
+  if err := json.Unmarshal([]byte(s), v1); err != nil || *v1 != b64String {
+    t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, *v1)
+  }
+  trans.Reset()
+  trans.Close()
+}
+
+func TestWriteSimpleJSONProtocolList(t *testing.T) {
+  thetype := "list"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  p.WriteListBegin(TType(DOUBLE), len(DOUBLE_VALUES))
+  for _, value := range DOUBLE_VALUES {
+    if e := p.WriteDouble(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+  }
+  p.WriteListEnd()
+  if e := p.Flush(); e != nil {
+    t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+  }
+  str := trans.String()
+  str1 := new([]interface{})
+  err := json.Unmarshal([]byte(str), str1)
+  if err != nil {
+    t.Fatalf("Unable to decode %s, wrote: %s", thetype, str)
+  }
+  l := *str1
+  if len(l) < 2 {
+    t.Fatalf("List must be at least of length two to include metadata")
+  }
+  if int(l[0].(float64)) != DOUBLE {
+    t.Fatal("Invalid type for list, expected: ", DOUBLE, ", but was: ", l[0])
+  }
+  if int(l[1].(float64)) != len(DOUBLE_VALUES) {
+    t.Fatal("Invalid length for list, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1])
+  }
+  for k, value := range DOUBLE_VALUES {
+    s := l[k+2]
+    if math.IsInf(value, 1) {
+      if s.(string) != JSON_INFINITY {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_INFINITY), str)
+      }
+    } else if math.IsInf(value, 0) {
+      if s.(string) != JSON_NEGATIVE_INFINITY {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY), str)
+      }
+    } else if math.IsNaN(value) {
+      if s.(string) != JSON_NAN {
+        t.Fatalf("Bad value for %s at index %v  %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NAN), str)
+      }
+    } else {
+      if s.(float64) != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s)
+      }
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestWriteSimpleJSONProtocolSet(t *testing.T) {
+  thetype := "set"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  p.WriteSetBegin(TType(DOUBLE), len(DOUBLE_VALUES))
+  for _, value := range DOUBLE_VALUES {
+    if e := p.WriteDouble(value); e != nil {
+      t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.String())
+    }
+  }
+  p.WriteSetEnd()
+  if e := p.Flush(); e != nil {
+    t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+  }
+  str := trans.String()
+  str1 := new([]interface{})
+  err := json.Unmarshal([]byte(str), str1)
+  if err != nil {
+    t.Fatalf("Unable to decode %s, wrote: %s", thetype, str)
+  }
+  l := *str1
+  if len(l) < 2 {
+    t.Fatalf("Set must be at least of length two to include metadata")
+  }
+  if int(l[0].(float64)) != DOUBLE {
+    t.Fatal("Invalid type for set, expected: ", DOUBLE, ", but was: ", l[0])
+  }
+  if int(l[1].(float64)) != len(DOUBLE_VALUES) {
+    t.Fatal("Invalid length for set, expected: ", len(DOUBLE_VALUES), ", but was: ", l[1])
+  }
+  for k, value := range DOUBLE_VALUES {
+    s := l[k+2]
+    if math.IsInf(value, 1) {
+      if s.(string) != JSON_INFINITY {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_INFINITY), str)
+      }
+    } else if math.IsInf(value, 0) {
+      if s.(string) != JSON_NEGATIVE_INFINITY {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY), str)
+      }
+    } else if math.IsNaN(value) {
+      if s.(string) != JSON_NAN {
+        t.Fatalf("Bad value for %s at index %v  %v, wrote: %q, expected: %q, originally wrote: %q", thetype, k, value, s, JsonQuote(JSON_NAN), str)
+      }
+    } else {
+      if s.(float64) != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s'", thetype, value, s)
+      }
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+func TestWriteSimpleJSONProtocolMap(t *testing.T) {
+  thetype := "map"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  p.WriteMapBegin(TType(I32), TType(DOUBLE), len(DOUBLE_VALUES))
+  for k, value := range DOUBLE_VALUES {
+    if e := p.WriteI32(int32(k)); e != nil {
+      t.Fatalf("Unable to write %s key int32 value %v due to error: %s", thetype, k, e.String())
+    }
+    if e := p.WriteDouble(value); e != nil {
+      t.Fatalf("Unable to write %s value float64 value %v due to error: %s", thetype, value, e.String())
+    }
+  }
+  p.WriteMapEnd()
+  if e := p.Flush(); e != nil {
+    t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.String())
+  }
+  str := trans.String()
+  if str[0] != '[' || str[len(str)-1] != ']' {
+    t.Fatalf("Bad value for %s, wrote: %q, in go: %q", thetype, str, DOUBLE_VALUES)
+  }
+  l := strings.Split(str[1:len(str)-1], ",", -1)
+  if len(l) < 3 {
+    t.Fatal("Expected list of at least length 3 for map for metadata, but was of length ", len(l))
+  }
+  expectedKeyType, _ := strconv.Atoi(l[0])
+  expectedValueType, _ := strconv.Atoi(l[1])
+  expectedSize, _ := strconv.Atoi(l[2])
+  if expectedKeyType != I32 {
+    t.Fatal("Expected map key type ", I32, ", but was ", l[0])
+  }
+  if expectedValueType != DOUBLE {
+    t.Fatal("Expected map value type ", DOUBLE, ", but was ", l[1])
+  }
+  if expectedSize != len(DOUBLE_VALUES) {
+    t.Fatal("Expected map size of ", len(DOUBLE_VALUES), ", but was ", l[2])
+  }
+  for k, value := range DOUBLE_VALUES {
+    strk := l[k*2+3]
+    strv := l[k*2+4]
+    ik, err := strconv.Atoi(strk)
+    if err != nil {
+      t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, strk, string(k), err.String())
+    }
+    if ik != k {
+      t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v", thetype, k, strk, k)
+    }
+    s := strv
+    if math.IsInf(value, 1) {
+      if s != JsonQuote(JSON_INFINITY) {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_INFINITY))
+      }
+    } else if math.IsInf(value, 0) {
+      if s != JsonQuote(JSON_NEGATIVE_INFINITY) {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_NEGATIVE_INFINITY))
+      }
+    } else if math.IsNaN(value) {
+      if s != JsonQuote(JSON_NAN) {
+        t.Fatalf("Bad value for %s at index %v  %v, wrote: %v, expected: %v", thetype, k, value, s, JsonQuote(JSON_NAN))
+      }
+    } else {
+      expected := strconv.Ftoa64(value, 'g', 10)
+      if s != expected {
+        t.Fatalf("Bad value for %s at index %v %v, wrote: %v, expected %v", thetype, k, value, s, expected)
+      }
+      v := float64(0)
+      if err := json.Unmarshal([]byte(s), &v); err != nil || v != value {
+        t.Fatalf("Bad json-decoded value for %s %v, wrote: '%s', expected: '%v'", thetype, value, s, v)
+      }
+    }
+    trans.Reset()
+  }
+  trans.Close()
+}
+
+
+func TestReadWriteSimpleJSONStruct(t *testing.T) {
+  thetype := "struct"
+  trans := NewTMemoryBuffer()
+  p := NewTSimpleJSONProtocol(trans)
+  orig := NewWork()
+  orig.Num1 = 25
+  orig.Num2 = 102
+  orig.Op = ADD
+  orig.Comment = "Add: 25 + 102"
+  if e := orig.Write(p); e != nil {
+    t.Fatalf("Unable to write %s value %#v due to error: %s", thetype, orig, e.String())
+  }
+  t.Log("Memory buffer contents: ", trans.String())
+  read := NewWork()
+  e := read.Read(p)
+  t.Logf("Read %s value: %#v", thetype, read)
+  if e != nil {
+    t.Fatalf("Unable to read %s due to error: %s", thetype, e.String())
+  }
+  if !orig.Equals(read) {
+    t.Fatalf("Original Write != Read: %#v != %#v ", orig, read)
+  }
+}
+
+func TestReadWriteSimpleJSONProtocol(t *testing.T) {
+  ReadWriteProtocolTest(t, NewTSimpleJSONProtocolFactory())
+}
diff --git a/lib/go/thrift/tsimple_server.go b/lib/go/thrift/tsimple_server.go
new file mode 100644
index 0000000..6c7d656
--- /dev/null
+++ b/lib/go/thrift/tsimple_server.go
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "os"
+)
+
+
+/**
+ * Simple singlethreaded server for testing.
+ *
+ */
+type TSimpleServer struct {
+  stopped bool
+
+  processorFactory       TProcessorFactory
+  serverTransport        TServerTransport
+  inputTransportFactory  TTransportFactory
+  outputTransportFactory TTransportFactory
+  inputProtocolFactory   TProtocolFactory
+  outputProtocolFactory  TProtocolFactory
+}
+
+func NewTSimpleServer2(processor TProcessor, serverTransport TServerTransport) *TSimpleServer {
+  return NewTSimpleServerFactory2(NewTProcessorFactory(processor), serverTransport)
+}
+
+func NewTSimpleServer4(processor TProcessor, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer {
+  return NewTSimpleServerFactory4(NewTProcessorFactory(processor),
+    serverTransport,
+    transportFactory,
+    protocolFactory,
+  )
+}
+
+func NewTSimpleServer6(processor TProcessor, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer {
+  return NewTSimpleServerFactory6(NewTProcessorFactory(processor),
+    serverTransport,
+    inputTransportFactory,
+    outputTransportFactory,
+    inputProtocolFactory,
+    outputProtocolFactory,
+  )
+}
+
+func NewTSimpleServerFactory2(processorFactory TProcessorFactory, serverTransport TServerTransport) *TSimpleServer {
+  return NewTSimpleServerFactory6(processorFactory,
+    serverTransport,
+    NewTTransportFactory(),
+    NewTTransportFactory(),
+    NewTBinaryProtocolFactoryDefault(),
+    NewTBinaryProtocolFactoryDefault(),
+  )
+}
+
+func NewTSimpleServerFactory4(processorFactory TProcessorFactory, serverTransport TServerTransport, transportFactory TTransportFactory, protocolFactory TProtocolFactory) *TSimpleServer {
+  return NewTSimpleServerFactory6(processorFactory,
+    serverTransport,
+    transportFactory,
+    transportFactory,
+    protocolFactory,
+    protocolFactory,
+  )
+}
+
+func NewTSimpleServerFactory6(processorFactory TProcessorFactory, serverTransport TServerTransport, inputTransportFactory TTransportFactory, outputTransportFactory TTransportFactory, inputProtocolFactory TProtocolFactory, outputProtocolFactory TProtocolFactory) *TSimpleServer {
+  return &TSimpleServer{processorFactory: processorFactory,
+    serverTransport:        serverTransport,
+    inputTransportFactory:  inputTransportFactory,
+    outputTransportFactory: outputTransportFactory,
+    inputProtocolFactory:   inputProtocolFactory,
+    outputProtocolFactory:  outputProtocolFactory,
+  }
+}
+
+func (p *TSimpleServer) ProcessorFactory() TProcessorFactory {
+  return p.processorFactory
+}
+
+func (p *TSimpleServer) ServerTransport() TServerTransport {
+  return p.serverTransport
+}
+
+func (p *TSimpleServer) InputTransportFactory() TTransportFactory {
+  return p.inputTransportFactory
+}
+
+func (p *TSimpleServer) OutputTransportFactory() TTransportFactory {
+  return p.outputTransportFactory
+}
+
+func (p *TSimpleServer) InputProtocolFactory() TProtocolFactory {
+  return p.inputProtocolFactory
+}
+
+func (p *TSimpleServer) OutputProtocolFactory() TProtocolFactory {
+  return p.outputProtocolFactory
+}
+
+func (p *TSimpleServer) Serve() os.Error {
+  p.stopped = false
+  err := p.serverTransport.Listen()
+  if err != nil {
+    return err
+  }
+  for !p.stopped {
+    client, err := p.serverTransport.Accept()
+    if err != nil {
+      return err
+    }
+    if client != nil {
+      p.processRequest(client)
+    }
+  }
+  return nil
+}
+
+func (p *TSimpleServer) Stop() os.Error {
+  p.stopped = true
+  p.serverTransport.Interrupt()
+  return nil
+}
+
+func (p *TSimpleServer) processRequest(client TTransport) {
+  processor := p.processorFactory.GetProcessor(client)
+  inputTransport := p.inputTransportFactory.GetTransport(client)
+  outputTransport := p.outputTransportFactory.GetTransport(client)
+  inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport)
+  outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport)
+  if inputTransport != nil {
+    defer inputTransport.Close()
+  }
+  if outputTransport != nil {
+    defer outputTransport.Close()
+  }
+  for {
+    ok, e := processor.Process(inputProtocol, outputProtocol)
+    if e != nil {
+      if !p.stopped {
+        // TODO(pomack) log error
+        break
+      }
+    }
+    if !ok {
+      break
+    }
+  }
+}
diff --git a/lib/go/thrift/tsocket.go b/lib/go/thrift/tsocket.go
new file mode 100644
index 0000000..758c132
--- /dev/null
+++ b/lib/go/thrift/tsocket.go
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "net"
+  "os"
+  "bytes"
+)
+
+/**
+ * Socket implementation of the TTransport interface. To be commented soon!
+ *
+ */
+type TSocket struct {
+  writeBuffer *bytes.Buffer
+  /**
+   * Wrapped Socket object
+   */
+  conn net.Conn
+  /**
+   * Remote Addr
+   */
+  addr net.Addr
+  /**
+   * Socket timeout in nanoseconds
+   */
+  nsecTimeout int64
+}
+
+/**
+ * Constructor that takes an already created socket.
+ *
+ * @param socket Already created socket object
+ * @throws TTransportException if there is an error setting up the streams
+ */
+func NewTSocketConn(connection net.Conn) (*TSocket, TTransportException) {
+  address := connection.RemoteAddr()
+  if address == nil {
+    address = connection.LocalAddr()
+  }
+  p := &TSocket{conn: connection, addr: address, nsecTimeout: 0, writeBuffer: bytes.NewBuffer(make([]byte, 0, 4096))}
+  return p, nil
+}
+
+/**
+ * Creates a new unconnected socket that will connect to the given host
+ * on the given port.
+ *
+ * @param host Remote host
+ * @param port Remote port
+ */
+func NewTSocketAddr(address net.Addr) *TSocket {
+  return NewTSocket(address, 0)
+}
+
+/**
+ * Creates a new unconnected socket that will connect to the given host
+ * on the given port.
+ *
+ * @param host    Remote host
+ * @param port    Remote port
+ * @param nsecTimeout Socket timeout
+ */
+func NewTSocket(address net.Addr, nsecTimeout int64) *TSocket {
+  sock := &TSocket{addr: address, nsecTimeout: nsecTimeout, writeBuffer: bytes.NewBuffer(make([]byte, 0, 4096))}
+  return sock
+}
+
+/**
+ * Sets the socket timeout
+ *
+ * @param timeout Nanoseconds timeout
+ */
+func (p *TSocket) SetTimeout(nsecTimeout int64) os.Error {
+  p.nsecTimeout = nsecTimeout
+  if p.IsOpen() {
+    if err := p.conn.SetTimeout(nsecTimeout); err != nil {
+      LOGGER.Print("Could not set socket timeout.", err)
+      return err
+    }
+  }
+  return nil
+}
+
+/**
+ * Returns a reference to the underlying socket.
+ */
+func (p *TSocket) Conn() net.Conn {
+  return p.conn
+}
+
+/**
+ * Checks whether the socket is connected.
+ */
+func (p *TSocket) IsOpen() bool {
+  if p.conn == nil {
+    return false
+  }
+  return true
+}
+
+/**
+ * Connects the socket, creating a new socket object if necessary.
+ */
+func (p *TSocket) Open() os.Error {
+  if p.IsOpen() {
+    return NewTTransportException(ALREADY_OPEN, "Socket already connected.")
+  }
+  if p.addr == nil {
+    return NewTTransportException(NOT_OPEN, "Cannot open nil address.")
+  }
+  if len(p.addr.Network()) == 0 {
+    return NewTTransportException(NOT_OPEN, "Cannot open bad network name.")
+  }
+  if len(p.addr.String()) == 0 {
+    return NewTTransportException(NOT_OPEN, "Cannot open bad address.")
+  }
+  var err os.Error
+  if p.conn, err = net.Dial(p.addr.Network(), "", p.addr.String()); err != nil {
+    LOGGER.Print("Could not open socket", err.String())
+    return NewTTransportException(NOT_OPEN, err.String())
+  }
+  if p.conn != nil {
+    p.conn.SetTimeout(p.nsecTimeout)
+  }
+  return nil
+}
+
+/**
+ * Closes the socket.
+ */
+func (p *TSocket) Close() os.Error {
+  // Close the socket
+  if p.conn != nil {
+    err := p.conn.Close()
+    if err != nil {
+      LOGGER.Print("Could not close socket. ", err.String())
+      return err
+    }
+    p.conn = nil
+  }
+  return nil
+}
+
+
+func (p *TSocket) Read(buf []byte) (int, os.Error) {
+  if !p.IsOpen() {
+    return 0, NewTTransportException(NOT_OPEN, "Connection not open")
+  }
+  n, err := p.conn.Read(buf)
+  return n, NewTTransportExceptionFromOsError(err)
+}
+
+
+func (p *TSocket) ReadAll(buf []byte) (int, os.Error) {
+  return ReadAllTransport(p, buf)
+}
+
+func (p *TSocket) Write(buf []byte) (int, os.Error) {
+  if !p.IsOpen() {
+    return 0, NewTTransportException(NOT_OPEN, "Connection not open")
+  }
+  p.writeBuffer.Write(buf)
+  return len(buf), nil
+}
+
+func (p *TSocket) Peek() bool {
+  return p.IsOpen()
+}
+
+func (p *TSocket) Flush() os.Error {
+  if !p.IsOpen() {
+    return NewTTransportException(NOT_OPEN, "Connection not open")
+  }
+  _, err := p.writeBuffer.WriteTo(p.conn)
+  return NewTTransportExceptionFromOsError(err)
+}
+
+func (p *TSocket) Interrupt() os.Error {
+  if !p.IsOpen() {
+    return nil
+  }
+  // TODO(pomack) fix Interrupt as this is probably wrong
+  return p.conn.Close()
+}
diff --git a/lib/go/thrift/tstruct.go b/lib/go/thrift/tstruct.go
new file mode 100644
index 0000000..5eaffae
--- /dev/null
+++ b/lib/go/thrift/tstruct.go
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * Helper class that encapsulates struct metadata.
+ *
+ */
+type TStruct interface {
+  TFieldContainer
+  TStructName() string
+  ThriftName() string
+  TStructFields() TFieldContainer
+  String() string
+  AttributeFromFieldId(fieldId int) interface{}
+  AttributeFromFieldName(fieldName string) interface{}
+}
+
+type tStruct struct {
+  TFieldContainer
+  name string
+}
+
+func NewTStructEmpty(name string) TStruct {
+  return &tStruct{
+    name:            name,
+    TFieldContainer: NewTFieldContainer(make([]TField, 0, 0)),
+  }
+}
+
+func NewTStruct(name string, fields []TField) TStruct {
+  return &tStruct{
+    name:            name,
+    TFieldContainer: NewTFieldContainer(fields),
+  }
+}
+
+func (p *tStruct) TStructName() string {
+  return p.name
+}
+
+func (p *tStruct) ThriftName() string {
+  return p.name
+}
+
+func (p *tStruct) TStructFields() TFieldContainer {
+  return p.TFieldContainer
+}
+
+func (p *tStruct) String() string {
+  return p.name
+}
+
+func (p *tStruct) Equals(other interface{}) bool {
+  cmp, ok := p.CompareTo(other)
+  return ok && cmp == 0
+}
+
+func (p *tStruct) CompareTo(other interface{}) (int, bool) {
+  return TType(STRUCT).Compare(p, other)
+}
+
+func (p *tStruct) AttributeFromFieldId(fieldId int) interface{} {
+  return nil
+}
+
+func (p *tStruct) AttributeFromFieldName(fieldName string) interface{} {
+  return p.AttributeFromFieldId(p.FieldIdFromFieldName(fieldName))
+}
+
+
+var ANONYMOUS_STRUCT TStruct
+
+func init() {
+  ANONYMOUS_STRUCT = NewTStructEmpty("")
+}
diff --git a/lib/go/thrift/ttransport.go b/lib/go/thrift/ttransport.go
new file mode 100644
index 0000000..45557f8
--- /dev/null
+++ b/lib/go/thrift/ttransport.go
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "os"
+  "log"
+)
+
+type Flusher interface {
+  Flush() (err os.Error)
+}
+
+/**
+ * Generic class that encapsulates the I/O layer. This is basically a thin
+ * wrapper around the combined functionality of Java input/output streams.
+ *
+ */
+type TTransport interface {
+  /**
+   * Queries whether the transport is open.
+   *
+   * @return True if the transport is open.
+   */
+  IsOpen() bool
+
+  /**
+   * Opens the transport for reading/writing.
+   *
+   * @returns TTransportException if the transport could not be opened
+   */
+  Open() (err os.Error)
+
+  /**
+   * Closes the transport.
+   */
+  Close() (err os.Error)
+
+  /**
+   * Reads up to len bytes into buffer buf, starting att offset off.
+   *
+   * @param buf Array to read into
+   * @param off Index to start reading at
+   * @param len Maximum number of bytes to read
+   * @return The number of bytes actually read
+   * @return TTransportException if there was an error reading data
+   */
+  Read(buf []byte) (n int, err os.Error)
+
+  /**
+   * Guarantees that all of len bytes are actually read off the transport.
+   *
+   * @param buf Array to read into
+   * @param off Index to start reading at
+   * @param len Maximum number of bytes to read
+   * @return The number of bytes actually read, which must be equal to len
+   * @return TTransportException if there was an error reading data
+   */
+  ReadAll(buf []byte) (n int, err os.Error)
+
+  /**
+   * Writes the buffer to the output
+   *
+   * @param buf The output data buffer
+   * @return Number of bytes written
+   * @return TTransportException if an error occurs writing data
+   */
+  Write(buf []byte) (n int, err os.Error)
+
+  /**
+   * Flush any pending data out of a transport buffer.
+   *
+   * @return TTransportException if there was an error writing out data.
+   */
+  Flush() (err os.Error)
+
+  /**
+   * Is there more data to be read?
+   *
+   * @return True if the remote side is still alive and feeding us
+   */
+  Peek() bool
+}
+/*
+type TTransportBase struct {
+}
+
+func (p* TTransportBase) IsOpen() bool {
+  return false;
+};
+
+func (p* TTransportBase) Peek() bool {
+  return p.IsOpen();
+}
+
+func (p* TTransportBase) Open() os.Error {
+  return NewTTransportException(UNKNOWN, "Subclasses must implement TTransportBase.Open()");
+}
+
+func (p* TTransportBase) Close() os.Error {
+  return NewTTransportException(UNKNOWN, "Subclasses must implement TTransportBase.Close()");
+}
+
+func (p* TTransportBase) Read(buf []byte) (int, os.Error) {
+  return 0, NewTTransportExceptionDefaultString("Subclasses must implement TTransportBase.Read()");
+}
+
+func (p* TTransportBase) ReadAll(buf []byte) (n int, err os.Error){
+  ret := 0;
+  size := len(buf);
+  for (n < size) {
+    ret, err = p.Read(buf[n:]);
+    if ret <= 0 {
+      if err != nil {
+        err = NewTTransportExceptionDefaultString("Cannot read. Remote side has closed. Tried to read " + string(size) + " bytes, but only got " + string(n) + " bytes.");
+      }
+      return ret, err;
+    }
+    n += ret;
+  }
+  return n, err;
+}
+
+func (p* TTransportBase) Write(buf []byte) (int, os.Error) {
+  return 0, NewTTransportExceptionDefaultString("Subclasses must implement TTransportBase.Write()");
+}
+
+func (p* TTransportBase) Flush() os.Error {
+  return nil;
+}
+*/
+/**
+ * Guarantees that all of len bytes are actually read off the transport.
+ *
+ * @param buf Array to read into
+ * @param off Index to start reading at
+ * @param len Maximum number of bytes to read
+ * @return The number of bytes actually read, which must be equal to len
+ * @return TTransportException if there was an error reading data
+ */
+func ReadAllTransport(p TTransport, buf []byte) (n int, err os.Error) {
+  ret := 0
+  size := len(buf)
+  for n < size {
+    ret, err = p.Read(buf[n:])
+    if ret <= 0 {
+      if err != nil {
+        err = NewTTransportExceptionDefaultString("Cannot read. Remote side has closed. Tried to read " + string(size) + " bytes, but only got " + string(n) + " bytes.")
+      }
+      return ret, err
+    }
+    n += ret
+  }
+  return n, err
+}
+
+
+var (
+  LOGGER *log.Logger
+)
+
+func init() {
+  LOGGER = log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)
+}
diff --git a/lib/go/thrift/ttransport_exception.go b/lib/go/thrift/ttransport_exception.go
new file mode 100644
index 0000000..b9fae17
--- /dev/null
+++ b/lib/go/thrift/ttransport_exception.go
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+  "os"
+)
+
+/**
+ * Transport exceptions.
+ *
+ */
+type TTransportException interface {
+  TException
+  TypeId() int
+}
+
+const (
+  UNKNOWN_TRANSPORT_EXCEPTION = 0
+  NOT_OPEN                    = 1
+  ALREADY_OPEN                = 2
+  TIMED_OUT                   = 3
+  END_OF_FILE                 = 4
+)
+
+type tTransportException struct {
+  typeId  int
+  message string
+}
+
+func (p *tTransportException) TypeId() int {
+  return p.typeId
+}
+
+func (p *tTransportException) String() string {
+  return p.message
+}
+
+func NewTTransportExceptionDefault() TTransportException {
+  return NewTTransportExceptionDefaultType(UNKNOWN_TRANSPORT_EXCEPTION)
+}
+
+func NewTTransportExceptionDefaultType(t int) TTransportException {
+  return NewTTransportException(t, "")
+}
+
+func NewTTransportExceptionDefaultString(m string) TTransportException {
+  return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, m)
+}
+
+func NewTTransportException(t int, m string) TTransportException {
+  return &tTransportException{typeId: t, message: m}
+}
+
+func NewTTransportExceptionFromOsError(e os.Error) TTransportException {
+  if e == nil {
+    return nil
+  }
+  t, ok := e.(TTransportException)
+  if ok {
+    return t
+  }
+  if e == os.EOF {
+    return NewTTransportException(END_OF_FILE, e.String())
+  }
+  return NewTTransportExceptionDefaultString(e.String())
+}
diff --git a/lib/go/thrift/ttransport_factory.go b/lib/go/thrift/ttransport_factory.go
new file mode 100644
index 0000000..4ab4dbe
--- /dev/null
+++ b/lib/go/thrift/ttransport_factory.go
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+/**
+ * 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)
+ *
+ */
+type TTransportFactory interface {
+  GetTransport(trans TTransport) TTransport
+}
+
+type tTransportFactory struct{}
+
+/**
+ * Return a wrapped instance of the base Transport.
+ *
+ * @param trans The base transport
+ * @return Wrapped Transport
+ */
+func (p *tTransportFactory) GetTransport(trans TTransport) TTransport {
+  return trans
+}
+
+func NewTTransportFactory() TTransportFactory {
+  return &tTransportFactory{}
+}
diff --git a/lib/go/thrift/ttransport_test.go b/lib/go/thrift/ttransport_test.go
new file mode 100644
index 0000000..b9630de
--- /dev/null
+++ b/lib/go/thrift/ttransport_test.go
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift_test
+
+import (
+  . "thrift"
+  "testing"
+  "net"
+  "os"
+  "strconv"
+)
+
+const TRANSPORT_BINARY_DATA_SIZE = 4096
+
+var (
+  transport_bdata []byte // test data for writing; same as data
+)
+
+func init() {
+  transport_bdata = make([]byte, TRANSPORT_BINARY_DATA_SIZE)
+  for i := 0; i < TRANSPORT_BINARY_DATA_SIZE; i++ {
+    transport_bdata[i] = byte((i + 'a') % 255)
+  }
+}
+
+func TransportTest(t *testing.T, writeTrans TTransport, readTrans TTransport) {
+  buf := make([]byte, TRANSPORT_BINARY_DATA_SIZE)
+  if !writeTrans.IsOpen() {
+    err := writeTrans.Open()
+    if err != nil {
+      t.Fatalf("Transport %T cannot open write transport: %s", writeTrans, err)
+    }
+  }
+  if !readTrans.IsOpen() {
+    err := readTrans.Open()
+    if err != nil {
+      t.Fatalf("Transport %T cannot open read transport: %s", readTrans, err)
+    }
+  }
+  _, err := writeTrans.Write(transport_bdata)
+  if err != nil {
+    t.Fatalf("Transport %T cannot write binary data of length %d: %s", writeTrans, len(transport_bdata), err)
+  }
+  err = writeTrans.Flush()
+  if err != nil {
+    t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err)
+  }
+  n, err := readTrans.ReadAll(buf)
+  if err != nil {
+    t.Errorf("Transport %T cannot read binary data of length %d: %s", readTrans, TRANSPORT_BINARY_DATA_SIZE, err)
+  }
+  if n != TRANSPORT_BINARY_DATA_SIZE {
+    t.Errorf("Transport %T read only %d instead of %d bytes of binary data", readTrans, n, TRANSPORT_BINARY_DATA_SIZE)
+  }
+  for k, v := range buf {
+    if v != transport_bdata[k] {
+      t.Fatalf("Transport %T read %d instead of %d for index %d of binary data 2", readTrans, v, transport_bdata[k], k)
+    }
+  }
+  _, err = writeTrans.Write(transport_bdata)
+  if err != nil {
+    t.Fatalf("Transport %T cannot write binary data 2 of length %d: %s", writeTrans, len(transport_bdata), err)
+  }
+  err = writeTrans.Flush()
+  if err != nil {
+    t.Fatalf("Transport %T cannot flush write binary data 2: %s", writeTrans, err)
+  }
+  b := readTrans.Peek()
+  if b != true {
+    t.Errorf("Transport %T returned %s for Peek()", readTrans, b)
+  }
+  buf = make([]byte, TRANSPORT_BINARY_DATA_SIZE)
+  read := 1
+  for n = 0; n < TRANSPORT_BINARY_DATA_SIZE && read != 0; {
+    read, err = readTrans.Read(buf[n:])
+    if err != nil {
+      t.Errorf("Transport %T cannot read binary data 2 of total length %d from offset %d: %s", readTrans, TRANSPORT_BINARY_DATA_SIZE, n, err)
+    }
+    n += read
+  }
+  if n != TRANSPORT_BINARY_DATA_SIZE {
+    t.Errorf("Transport %T read only %d instead of %d bytes of binary data 2", readTrans, n, TRANSPORT_BINARY_DATA_SIZE)
+  }
+  for k, v := range buf {
+    if v != transport_bdata[k] {
+      t.Fatalf("Transport %T read %d instead of %d for index %d of binary data 2", readTrans, v, transport_bdata[k], k)
+    }
+  }
+}
+
+func CloseTransports(t *testing.T, readTrans TTransport, writeTrans TTransport) {
+  err := readTrans.Close()
+  if err != nil {
+    t.Errorf("Transport %T cannot close read transport: %s", readTrans, err)
+  }
+  if writeTrans != readTrans {
+    err = writeTrans.Close()
+    if err != nil {
+      t.Errorf("Transport %T cannot close write transport: %s", writeTrans, err)
+    }
+  }
+}
+
+func FindAvailableTCPServerPort(startPort int) (net.Addr, os.Error) {
+  for i := startPort; i < 65535; i++ {
+    s := "127.0.0.1:" + strconv.Itoa(i)
+    l, err := net.Listen("tcp", s)
+    if err == nil {
+      l.Close()
+      return net.ResolveTCPAddr(s)
+    }
+  }
+  return nil, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "Could not find available server port")
+}
diff --git a/lib/go/thrift/ttype.go b/lib/go/thrift/ttype.go
new file mode 100644
index 0000000..d024b39
--- /dev/null
+++ b/lib/go/thrift/ttype.go
@@ -0,0 +1,975 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package thrift
+
+import (
+  "container/list"
+  "container/vector"
+  "strconv"
+)
+
+/**
+ * Type constants in the Thrift protocol.
+ */
+type TType byte
+
+const (
+  STOP    = 0
+  VOID    = 1
+  BOOL    = 2
+  BYTE    = 3
+  I08     = 3
+  DOUBLE  = 4
+  I16     = 6
+  I32     = 8
+  I64     = 10
+  STRING  = 11
+  UTF7    = 11
+  STRUCT  = 12
+  MAP     = 13
+  SET     = 14
+  LIST    = 15
+  ENUM    = 16
+  UTF8    = 16
+  UTF16   = 17
+  GENERIC = 127
+)
+
+func (p TType) String() string {
+  switch p {
+  case STOP:
+    return "STOP"
+  case VOID:
+    return "VOID"
+  case BOOL:
+    return "BOOL"
+  case BYTE:
+    return "BYTE"
+  case DOUBLE:
+    return "DOUBLE"
+  case I16:
+    return "I16"
+  case I32:
+    return "I32"
+  case I64:
+    return "I64"
+  case STRING:
+    return "STRING"
+  case STRUCT:
+    return "STRUCT"
+  case MAP:
+    return "MAP"
+  case SET:
+    return "SET"
+  case LIST:
+    return "LIST"
+  case ENUM:
+    return "ENUM"
+  case UTF16:
+    return "UTF16"
+  case GENERIC:
+    return "GENERIC"
+  }
+  return "Unknown"
+}
+
+func (p TType) IsBaseType() bool {
+  switch p {
+  case BOOL, BYTE, DOUBLE, I16, I32, I64, STRING, UTF8, UTF16:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsEmptyType() bool {
+  switch p {
+  case STOP, VOID:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsEnum() bool {
+  switch p {
+  case ENUM:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsNumericType() bool {
+  switch p {
+  case ENUM, BOOL, BYTE, DOUBLE, I16, I32, I64:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsStringType() bool {
+  switch p {
+  case STRING, UTF8, UTF16:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsContainer() bool {
+  switch p {
+  case MAP, SET, LIST:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsStruct() bool {
+  switch p {
+  case STRUCT:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsMap() bool {
+  switch p {
+  case MAP:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsList() bool {
+  switch p {
+  case LIST:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsSet() bool {
+  switch p {
+  case SET:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) IsInt() bool {
+  switch p {
+  case BYTE, I16, I32, I64:
+    return true
+  default:
+    return false
+  }
+  return false
+}
+
+func (p TType) Coerce(other interface{}) TType {
+  if other == nil {
+    return TType(STOP)
+  }
+  switch b := other.(type) {
+  default:
+    return TType(STOP)
+  case nil:
+    return TType(STOP)
+  case TType:
+    return b
+  case byte:
+    return TType(b)
+  case int:
+    return TType(byte(b))
+  case int8:
+    return TType(byte(b))
+  case int32:
+    return TType(byte(b))
+  case int64:
+    return TType(byte(b))
+  case uint:
+    return TType(byte(b))
+  case uint32:
+    return TType(byte(b))
+  case uint64:
+    return TType(byte(b))
+  case float32:
+    return TType(byte(int(b)))
+  case float64:
+    return TType(byte(int(b)))
+  }
+  return TType(STOP)
+}
+
+func (p TType) LessType(other interface{}) bool {
+  return p < p.Coerce(other)
+}
+
+func (p TType) Less(i, j interface{}) bool {
+  cmp, ok := p.Compare(i, j)
+  return ok && cmp > 0
+}
+
+
+func (p TType) Compare(i, j interface{}) (int, bool) {
+  if i == j {
+    return 0, true
+  }
+  if i == nil {
+    if j == nil {
+      return 0, true
+    }
+    return -1, true
+  }
+  if j == nil {
+    return 1, true
+  }
+  ci, iok := p.CoerceData(i)
+  cj, jok := p.CoerceData(j)
+  if iok && !jok {
+    return 1, true
+  }
+  if !iok && jok {
+    return -1, true
+  }
+  // hopefully this doesn't happen as Compare() would continuously return 0, false
+  if !iok && !jok {
+    return 0, false
+  }
+  if ci == cj {
+    return 0, true
+  }
+  if ci == nil {
+    if cj == nil {
+      return 0, true
+    }
+    return -1, true
+  }
+  if cj == nil {
+    return 1, true
+  }
+  switch p {
+  case STOP, VOID:
+    // hopefully this doesn't happen as Compare() would continuously return 0, false
+    return 0, false
+  case BOOL:
+    vi := ci.(bool)
+    vj := cj.(bool)
+    if vi == vj {
+      return 0, true
+    }
+    if vi == false {
+      return -1, true
+    }
+    return 1, true
+  case BYTE:
+    vi := ci.(byte)
+    vj := cj.(byte)
+    if vi == vj {
+      return 0, true
+    }
+    if vi < vj {
+      return -1, true
+    }
+    return 1, true
+  case DOUBLE:
+    vi := ci.(float64)
+    vj := cj.(float64)
+    if vi == vj {
+      return 0, true
+    }
+    if vi < vj {
+      return -1, true
+    }
+    return 1, true
+  case I16:
+    vi := ci.(int16)
+    vj := cj.(int16)
+    if vi == vj {
+      return 0, true
+    }
+    if vi < vj {
+      return -1, true
+    }
+    return 1, true
+  case I32:
+    vi := ci.(int32)
+    vj := cj.(int32)
+    if vi == vj {
+      return 0, true
+    }
+    if vi < vj {
+      return -1, true
+    }
+    return 1, true
+  case I64:
+    vi := ci.(int64)
+    vj := cj.(int64)
+    if vi == vj {
+      return 0, true
+    }
+    if vi < vj {
+      return -1, true
+    }
+    return 1, true
+  case STRING, UTF8, UTF16:
+    vi := ci.(string)
+    vj := cj.(string)
+    if vi == vj {
+      return 0, true
+    }
+    if vi < vj {
+      return -1, true
+    }
+    return 1, true
+  case STRUCT:
+    si := ci.(TStruct)
+    sj := cj.(TStruct)
+    if cmp := CompareString(si.ThriftName(), sj.ThriftName()); cmp != 0 {
+      return cmp, true
+    }
+    if cmp, ok := si.TStructFields().CompareTo(sj.TStructFields()); !ok || cmp != 0 {
+      return cmp, ok
+    }
+    for field := range si.TStructFields().Iter() {
+      a := si.AttributeFromFieldId(field.Id())
+      b := sj.AttributeFromFieldId(field.Id())
+      if cmp, ok := field.TypeId().Compare(a, b); !ok || cmp != 0 {
+        return cmp, ok
+      }
+    }
+    return 0, true
+  case MAP:
+    mi := ci.(TMap)
+    mj := cj.(TMap)
+    ei := mi.KeyType()
+    if ej := mj.KeyType(); ei != ej {
+      return CompareInt(int(ei), int(ej)), true
+    }
+    if size := mi.Len(); size != mj.Len() {
+      return CompareInt(size, mj.Len()), true
+    }
+    if c, cok := ei.Compare(mi.Keys(), mj.Keys()); c != 0 || !cok {
+      return c, cok
+    }
+    return ei.Compare(mi.Values(), mj.Values())
+  case LIST:
+    li := ci.(TList)
+    lj := cj.(TList)
+    ei := li.ElemType()
+    ej := lj.ElemType()
+    if ei != ej {
+      return CompareInt(int(ei), int(ej)), true
+    }
+    size := li.Len()
+    if size != lj.Len() {
+      return CompareInt(size, lj.Len()), true
+    }
+    for k := 0; k < size; k++ {
+      vi := li.At(k)
+      vj := lj.At(k)
+      c, cok := ei.Compare(vi, vj)
+      if c != 0 || !cok {
+        return c, cok
+      }
+    }
+    return 0, true
+  case SET:
+    li := ci.(TSet)
+    lj := cj.(TSet)
+    ei := li.ElemType()
+    ej := lj.ElemType()
+    if ei != ej {
+      return CompareInt(int(ei), int(ej)), true
+    }
+    size := li.Len()
+    if size != lj.Len() {
+      return CompareInt(size, lj.Len()), true
+    }
+    return ei.Compare(li.Values(), lj.Values())
+  default:
+    panic("Invalid thrift type to coerce")
+  }
+  return 0, false
+}
+
+func (p TType) CompareValueArrays(li, lj []interface{}) (int, bool) {
+  size := len(li)
+  if cmp := CompareInt(size, len(lj)); cmp != 0 {
+    return cmp, true
+  }
+  for i := 0; i < size; i++ {
+    vi := li[i]
+    vj := lj[i]
+    c, cok := p.Compare(vi, vj)
+    if c != 0 || !cok {
+      return c, cok
+    }
+  }
+  return 0, true
+}
+
+func (p TType) Equals(other interface{}) bool {
+  return p == p.Coerce(other)
+}
+
+type Stringer interface {
+  String() string
+}
+
+type Enumer interface {
+  String() string
+  Value() int
+  IsEnum() bool
+}
+
+func TypeFromValue(data interface{}) TType {
+  switch i := data.(type) {
+  default:
+    return STOP
+  case nil:
+    return VOID
+  case bool:
+    return BOOL
+  case float32, float64:
+    return DOUBLE
+  case int, int32:
+    return I32
+  case byte:
+    return BYTE
+  case int8:
+    return I08
+  case int16:
+    return I16
+  case int64:
+    return I64
+  case string:
+    return STRING
+  case TStruct:
+    return STRUCT
+  case TMap:
+    return MAP
+  case TSet:
+    return SET
+  case []interface{}, *list.List, *vector.Vector, TList:
+    return LIST
+  }
+  return STOP
+}
+
+func (p TType) CoerceData(data interface{}) (interface{}, bool) {
+  if data == nil {
+    switch p {
+    case STOP:
+      return nil, true
+    case VOID:
+      return nil, true
+    case BOOL:
+      return false, true
+    case BYTE:
+      return byte(0), true
+    case DOUBLE:
+      return float64(0), true
+    case I16:
+      return int16(0), true
+    case I32:
+      return int32(0), true
+    case I64:
+      return int64(0), true
+    case STRING, UTF8, UTF16:
+      return "", true
+    case STRUCT:
+      return NewTStructEmpty(""), true
+    case MAP:
+      return NewTMapDefault(), true
+    case LIST:
+      return NewTListDefault(), true
+    case SET:
+      return NewTSetDefault(), true
+    default:
+      panic("Invalid thrift type to coerce")
+    }
+  }
+  switch p {
+  case STOP:
+    return nil, true
+  case VOID:
+    return nil, true
+  case BOOL:
+    switch b := data.(type) {
+    default:
+      return false, false
+    case bool:
+      return b, true
+    case Numeric:
+      return bool(b.Int() != 0), true
+    case int:
+      return b != 0, true
+    case byte:
+      return b != 0, true
+    case int8:
+      return b != 0, true
+    case int16:
+      return b != 0, true
+    case int32:
+      return b != 0, true
+    case int64:
+      return b != 0, true
+    case uint:
+      return b != 0, true
+    case uint16:
+      return b != 0, true
+    case uint32:
+      return b != 0, true
+    case uint64:
+      return b != 0, true
+    case float32:
+      return b != 0, true
+    case float64:
+      return b != 0, true
+    case Stringer:
+      v := b.String()
+      if v == "false" || v == "0" || len(v) == 0 {
+        return false, true
+      }
+      return true, true
+    case string:
+      if b == "false" || b == "0" || len(b) == 0 {
+        return false, true
+      }
+      return true, true
+    }
+  case BYTE:
+    if b, ok := data.(byte); ok {
+      return b, true
+    }
+    if b, ok := data.(Numeric); ok {
+      return b.Byte(), true
+    }
+    if b, ok := data.(bool); ok {
+      if b {
+        return byte(1), true
+      }
+      return byte(0), true
+    }
+    if b, ok := data.(int); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(int8); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(int16); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(int32); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(int64); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(uint); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(uint8); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(uint16); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(uint32); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(uint64); ok {
+      return byte(b), true
+    }
+    if b, ok := data.(float32); ok {
+      return byte(int(b)), true
+    }
+    if b, ok := data.(float64); ok {
+      return byte(int(b)), true
+    }
+    if b, ok := data.(Stringer); ok {
+      data = b.String()
+    }
+    if b, ok := data.(string); ok {
+      i1, err := strconv.Atoi(b)
+      if err != nil {
+        return byte(int(i1)), true
+      }
+    }
+    return byte(0), false
+  case DOUBLE:
+    if b, ok := data.(float32); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(float64); ok {
+      return b, true
+    }
+    if b, ok := data.(Numeric); ok {
+      return bool(b.Float64() != 0.0), true
+    }
+    if b, ok := data.(byte); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(bool); ok {
+      if b {
+        return float64(1.0), true
+      }
+      return float64(0.0), true
+    }
+    if b, ok := data.(int); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(int8); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(int16); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(int32); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(int64); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(uint); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(uint8); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(uint16); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(uint32); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(uint64); ok {
+      return float64(b), true
+    }
+    if b, ok := data.(Stringer); ok {
+      data = b.String()
+    }
+    if b, ok := data.(string); ok {
+      d1, err := strconv.Atof64(b)
+      if err != nil {
+        return d1, true
+      }
+    }
+    return float64(0), false
+  case I16:
+    if b, ok := data.(int16); ok {
+      return b, true
+    }
+    if b, ok := data.(int); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(Numeric); ok {
+      return bool(b.Int16() != 0), true
+    }
+    if b, ok := data.(byte); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(bool); ok {
+      if b {
+        return int16(1.0), true
+      }
+      return int16(0.0), true
+    }
+    if b, ok := data.(int8); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(int32); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(int64); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(uint); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(uint8); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(uint16); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(uint32); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(uint64); ok {
+      return int16(b), true
+    }
+    if b, ok := data.(float32); ok {
+      return int16(int(b)), true
+    }
+    if b, ok := data.(float64); ok {
+      return int16(int(b)), true
+    }
+    if b, ok := data.(Stringer); ok {
+      data = b.String()
+    }
+    if b, ok := data.(string); ok {
+      i1, err := strconv.Atoi(b)
+      if err != nil {
+        return int16(i1), true
+      }
+    }
+    return int16(0), false
+  case I32:
+    if b, ok := data.(int32); ok {
+      return b, true
+    }
+    if b, ok := data.(int); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(Numeric); ok {
+      return bool(b.Int32() != 0), true
+    }
+    if b, ok := data.(byte); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(bool); ok {
+      if b {
+        return int32(1.0), true
+      }
+      return int32(0.0), true
+    }
+    if b, ok := data.(int8); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(int16); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(int64); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(uint); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(uint8); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(uint16); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(uint32); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(uint64); ok {
+      return int32(b), true
+    }
+    if b, ok := data.(float32); ok {
+      return int32(int(b)), true
+    }
+    if b, ok := data.(float64); ok {
+      return int32(int(b)), true
+    }
+    if b, ok := data.(Stringer); ok {
+      data = b.String()
+    }
+    if b, ok := data.(string); ok {
+      i1, err := strconv.Atoi(b)
+      if err != nil {
+        return int32(i1), true
+      }
+    }
+    return int32(0), false
+  case I64:
+    if b, ok := data.(int64); ok {
+      return b, true
+    }
+    if b, ok := data.(int32); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(int); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(Numeric); ok {
+      return bool(b.Int64() != 0), true
+    }
+    if b, ok := data.(byte); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(bool); ok {
+      if b {
+        return int64(1.0), true
+      }
+      return int64(0.0), true
+    }
+    if b, ok := data.(int8); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(int16); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(uint); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(uint8); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(uint16); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(uint32); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(uint64); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(float32); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(float64); ok {
+      return int64(b), true
+    }
+    if b, ok := data.(Stringer); ok {
+      data = b.String()
+    }
+    if b, ok := data.(string); ok {
+      i1, err := strconv.Atoi64(b)
+      if err != nil {
+        return i1, true
+      }
+    }
+    return int64(0), false
+  case STRING, UTF8, UTF16:
+    if b, ok := data.(Enumer); ok {
+      if i1, ok := data.(int); ok {
+        return i1, true
+      }
+      return b.String(), true
+    }
+    if b, ok := data.(Stringer); ok {
+      return b.String(), true
+    }
+    if b, ok := data.(string); ok {
+      return b, true
+    }
+    if b, ok := data.(int); ok {
+      return string(b), true
+    }
+    if b, ok := data.(byte); ok {
+      return string(b), true
+    }
+    if b, ok := data.(bool); ok {
+      if b {
+        return "true", true
+      }
+      return "false", true
+    }
+    if b, ok := data.(int8); ok {
+      return string(b), true
+    }
+    if b, ok := data.(int16); ok {
+      return string(b), true
+    }
+    if b, ok := data.(int32); ok {
+      return string(b), true
+    }
+    if b, ok := data.(int64); ok {
+      return string(b), true
+    }
+    if b, ok := data.(uint); ok {
+      return string(b), true
+    }
+    if b, ok := data.(uint8); ok {
+      return string(b), true
+    }
+    if b, ok := data.(uint16); ok {
+      return string(b), true
+    }
+    if b, ok := data.(uint32); ok {
+      return string(b), true
+    }
+    if b, ok := data.(uint64); ok {
+      return string(b), true
+    }
+    if b, ok := data.(float32); ok {
+      return strconv.Ftoa32(b, 'g', -1), true
+    }
+    if b, ok := data.(float64); ok {
+      return strconv.Ftoa64(b, 'g', -1), true
+    }
+    return "", false
+  case STRUCT:
+    if b, ok := data.(TStruct); ok {
+      return b, true
+    }
+    return NewTStructEmpty(""), true
+  case MAP:
+    if b, ok := data.(TMap); ok {
+      return b, true
+    }
+    return NewTMapDefault(), false
+  case LIST:
+    if b, ok := data.(TList); ok {
+      return b, true
+    }
+    return NewTListDefault(), false
+  case SET:
+    if b, ok := data.(TSet); ok {
+      return b, true
+    }
+    return NewTSetDefault(), false
+  default:
+    panic("Invalid thrift type to coerce")
+  }
+  return nil, false
+}
+
+type EqualsOtherInterface interface {
+  Equals(other interface{}) bool
+}
+
+type EqualsMap interface {
+  Equals(other TMap) bool
+}
+
+type EqualsSet interface {
+  Equals(other TSet) bool
+}
+
+type EqualsList interface {
+  Equals(other TList) bool
+}
+
+type EqualsStruct interface {
+  Equals(other TStruct) bool
+}
