diff --git a/lib/go/Make.deps b/lib/go/Make.deps
new file mode 100644
index 0000000..c233e7e
--- /dev/null
+++ b/lib/go/Make.deps
@@ -0,0 +1,134 @@
+thrift/.install: bufio.install bytes.install container/list.install container/vector.install encoding/base64.install encoding/binary.install fmt.install http.install io.install json.install log.install math.install net.install os.install reflect.install sort.install strconv.install strings.install
+archive/tar.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/archive/tar.a
+archive/zip.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/archive/zip.a
+asn1.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/asn1.a
+big.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/big.a
+bufio.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/bufio.a
+bytes.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/bytes.a
+cmath.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/cmath.a
+compress/flate.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/flate.a
+compress/gzip.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/gzip.a
+compress/zlib.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/zlib.a
+container/heap.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/container/heap.a
+container/list.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/container/list.a
+container/ring.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/container/ring.a
+container/vector.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/container/vector.a
+crypto.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto.a
+crypto/aes.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/aes.a
+crypto/block.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/block.a
+crypto/blowfish.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/blowfish.a
+crypto/cast5.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/cast5.a
+crypto/cipher.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/cipher.a
+crypto/dsa.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/dsa.a
+crypto/elliptic.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/elliptic.a
+crypto/hmac.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/hmac.a
+crypto/md4.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/md4.a
+crypto/md5.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/md5.a
+crypto/ocsp.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/ocsp.a
+crypto/rand.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/rand.a
+crypto/rc4.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/rc4.a
+crypto/ripemd160.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/ripemd160.a
+crypto/rsa.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/rsa.a
+crypto/sha1.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/sha1.a
+crypto/sha256.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/sha256.a
+crypto/sha512.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/sha512.a
+crypto/subtle.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/subtle.a
+crypto/tls.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/tls.a
+crypto/twofish.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/twofish.a
+crypto/x509.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/x509.a
+crypto/xtea.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/xtea.a
+debug/dwarf.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/dwarf.a
+debug/macho.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/macho.a
+debug/elf.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/elf.a
+debug/gosym.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/gosym.a
+debug/pe.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/pe.a
+debug/proc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/debug/proc.a
+ebnf.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/ebnf.a
+encoding/ascii85.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/ascii85.a
+encoding/base32.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/base32.a
+encoding/base64.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/base64.a
+encoding/binary.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/binary.a
+encoding/git85.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/git85.a
+encoding/hex.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/hex.a
+encoding/line.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/line.a
+encoding/pem.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/encoding/pem.a
+exec.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exec.a
+exp/datafmt.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exp/datafmt.a
+exp/draw.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exp/draw.a
+exp/draw/x11.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exp/draw/x11.a
+exp/eval.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/exp/eval.a
+expvar.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/expvar.a
+flag.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/flag.a
+fmt.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/fmt.a
+go/ast.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/ast.a
+go/doc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/doc.a
+go/parser.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/parser.a
+go/printer.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/printer.a
+go/scanner.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/scanner.a
+go/token.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/token.a
+go/typechecker.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/typechecker.a
+gob.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/gob.a
+hash.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash.a
+hash/adler32.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash/adler32.a
+hash/crc32.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash/crc32.a
+hash/crc64.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash/crc64.a
+html.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/html.a
+http.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http.a
+http/pprof.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http/pprof.a
+image.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image.a
+image/jpeg.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/jpeg.a
+image/png.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/png.a
+index/suffixarray.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/index/suffixarray.a
+io.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/io.a
+io/ioutil.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/io/ioutil.a
+json.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/json.a
+log.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/log.a
+math.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/math.a
+mime.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/mime.a
+mime/multipart.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/mime/multipart.a
+net.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/net.a
+net/dict.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/net/dict.a
+net/textproto.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/net/textproto.a
+netchan.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/netchan.a
+os.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/os.a
+os/signal.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/os/signal.a
+patch.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/patch.a
+path.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/path.a
+rand.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/rand.a
+reflect.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/reflect.a
+regexp.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/regexp.a
+rpc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/rpc.a
+rpc/jsonrpc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/rpc/jsonrpc.a
+runtime.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/runtime.a
+runtime/cgo.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/runtime/cgo.a
+runtime/debug.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/runtime/debug.a
+runtime/pprof.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/runtime/pprof.a
+scanner.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/scanner.a
+smtp.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/smtp.a
+sort.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/sort.a
+strconv.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/strconv.a
+strings.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/strings.a
+sync.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/sync.a
+syscall.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/syscall.a
+syslog.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/syslog.a
+tabwriter.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/tabwriter.a
+template.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/template.a
+testing.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/testing.a
+testing/iotest.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/testing/iotest.a
+testing/quick.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/testing/quick.a
+testing/script.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/testing/script.a
+time.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/time.a
+try.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/try.a
+unicode.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/unicode.a
+utf16.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/utf16.a
+utf8.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/utf8.a
+websocket.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/websocket.a
+xml.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/xml.a
+../cmd/cgo.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/cgo.a
+../cmd/ebnflint.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/ebnflint.a
+../cmd/godoc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/godoc.a
+../cmd/gofmt.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/gofmt.a
+../cmd/goinstall.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/goinstall.a
+../cmd/govet.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/govet.a
+../cmd/goyacc.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/goyacc.a
+../cmd/hgpatch.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/hgpatch.a
diff --git a/lib/go/Makefile b/lib/go/Makefile
new file mode 100644
index 0000000..8e81d8d
--- /dev/null
+++ b/lib/go/Makefile
@@ -0,0 +1,64 @@
+# 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.
+
+# After editing the DIRS= list or adding imports to any Go files
+# in any of those directories, run:
+#
+#	./deps.bash
+#
+# to rebuild the dependency information in Make.deps.
+
+
+include $(GOROOT)/src/Make.inc
+
+all: Make.deps install
+
+DIRS=\
+     thrift/\
+
+TEST=\
+	$(filter-out $(NOTEST),$(DIRS))
+
+
+clean.dirs: $(addsuffix .clean, $(DIRS))
+install.dirs: $(addsuffix .install, $(DIRS))
+nuke.dirs: $(addsuffix .nuke, $(DIRS))
+test.dirs: $(addsuffix .test, $(DIRS))
+check.dirs: $(addsuffix .check, $(DIRS))
+
+%.clean:
+	+cd $* && gomake clean
+
+%.install:
+	+cd $* && gomake install
+
+%.nuke:
+	+cd $* && gomake nuke
+
+%.test:
+	+cd $* && gomake test
+
+%.check:
+	+cd $* && gomake check
+
+clean: clean.dirs
+
+install: install.dirs
+
+test:	test.dirs
+
+check:	check.dirs
+
+#nuke: nuke.dirs
+#	rm -rf "$(GOROOT)"/pkg/thrift.*
+
+echo-dirs:
+	@echo $(DIRS)
+
+Make.deps:
+	./deps.bash
+
+deps:
+	./deps.bash
+
diff --git a/lib/go/deps.bash b/lib/go/deps.bash
new file mode 100644
index 0000000..dabd404
--- /dev/null
+++ b/lib/go/deps.bash
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+# 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.
+
+OUT="Make.deps"
+TMP="Make.deps.tmp"
+
+if [ -f $OUT ] && ! [ -w $OUT ]; then
+	echo "$0: $OUT is read-only; aborting." 1>&2
+	exit 1
+fi
+
+# Get list of directories from Makefile
+dirs=$(sed '1,/^DIRS=/d; /^$/,$d; s/\\//g' Makefile)
+dirs2=$(sed '1,/^DIRS=/d; /^$/,$d; s/\\//g' $GOROOT/src/pkg/Makefile)
+dirpat=$(echo $dirs $dirs2 | sed 's/ /|/g; s/.*/^(&)$/')
+
+for dir in $dirs; do (
+	cd $dir || exit 1
+
+	sources=$(sed -n 's/\.go\\/.go/p' Makefile)
+	sources=$(ls $sources 2> /dev/null)  # remove .s, .c, etc.
+
+	deps=$(
+		sed -n '/^import.*"/p; /^import[ \t]*(/,/^)/p' $sources /dev/null |
+		cut -d '"' -f2 |
+		egrep "$dirpat" |
+		grep -v "^$dir\$" |
+		sed 's/$/.install/' |
+		sort -u
+	)
+
+	echo $dir.install: $deps
+) done > $TMP
+
+for dir in $dirs2; do (
+  echo $dir.install: \${GOROOT}/pkg/\${GOOS}_\${GOARCH}/${dir}.a
+) done >> $TMP
+
+mv $TMP $OUT
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
+}
