diff --git a/lib/Makefile.am b/lib/Makefile.am
index 9dbc1c1..8538afa 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -66,4 +66,5 @@
   ocaml \
   js \
   as3 \
-  st
+  st \
+  go
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
+}
