diff --git a/lib/go/Make.deps b/lib/go/Make.deps
deleted file mode 100644
index 56e75da..0000000
--- a/lib/go/Make.deps
+++ /dev/null
@@ -1,159 +0,0 @@
-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/bzip2.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/bzip2.a
-compress/flate.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/flate.a
-compress/gzip.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/gzip.a
-compress/lzw.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/compress/lzw.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/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/des.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/des.a
-crypto/dsa.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/dsa.a
-crypto/ecdsa.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/ecdsa.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/openpgp.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/openpgp.a
-crypto/openpgp/armor.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/openpgp/armor.a
-crypto/openpgp/error.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/openpgp/error.a
-crypto/openpgp/packet.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/openpgp/packet.a
-crypto/openpgp/s2k.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/openpgp/s2k.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/x509/crl.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/crypto/x509/crl.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
-go/types.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/go/types.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
-hash/fnv.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/hash/fnv.a
-html.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/html.a
-http.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http.a
-http/cgi.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http/cgi.a
-http/fcgi.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http/fcgi.a
-http/pprof.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http/pprof.a
-http/httptest.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http/httptest.a
-http/spdy.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/http/spdy.a
-image.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image.a
-image/bmp.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/bmp.a
-image/gif.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/gif.a
-image/jpeg.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/jpeg.a
-image/png.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/png.a
-image/tiff.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/tiff.a
-image/ycbcr.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/image/ycbcr.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
-os/user.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/os/user.a
-patch.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/patch.a
-path.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/path.a
-path/filepath.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/path/filepath.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
-sync/atomic.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/sync/atomic.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/gofix.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/gofix.a
-../cmd/gofmt.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/gofmt.a
-../cmd/goinstall.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/goinstall.a
-../cmd/gotest.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/gotest.a
-../cmd/gotype.install: ${GOROOT}/pkg/${GOOS}_${GOARCH}/../cmd/gotype.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
deleted file mode 100644
index 8e81d8d..0000000
--- a/lib/go/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-# 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/Makefile.am b/lib/go/Makefile.am
new file mode 100644
index 0000000..7c82467
--- /dev/null
+++ b/lib/go/Makefile.am
@@ -0,0 +1,12 @@
+install:
+	@echo '##############################################################'
+	@echo '##############################################################'
+	@echo 'The Go client library should be insalled via "go get", please see /lib/go/README'
+	@echo '##############################################################'
+	@echo '##############################################################'
+
+check-local:
+	go test ./thrift
+
+all-local: check-local
+
diff --git a/lib/go/README b/lib/go/README
new file mode 100644
index 0000000..94628d9
--- /dev/null
+++ b/lib/go/README
@@ -0,0 +1,31 @@
+Thrift Python Software Library
+
+License
+=======
+
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+
+Using Thrift with Go
+====================
+
+In following Go conventions, we reccomend you use the 'go' tool to install
+Thrift for go.
+
+$ go get git.apache.org/thrift.git/lib/go/thrift
+
+Will install the last stable release.
diff --git a/lib/go/deps.bash b/lib/go/deps.bash
deleted file mode 100644
index dabd404..0000000
--- a/lib/go/deps.bash
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/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
deleted file mode 100644
index 59f7862..0000000
--- a/lib/go/thrift/Makefile
+++ /dev/null
@@ -1,58 +0,0 @@
-# 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
deleted file mode 100644
index 3b0abfb..0000000
--- a/lib/go/thrift/_testmain.go
+++ /dev/null
@@ -1,68 +0,0 @@
-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/application_exception.go b/lib/go/thrift/application_exception.go
new file mode 100644
index 0000000..6655cc5
--- /dev/null
+++ b/lib/go/thrift/application_exception.go
@@ -0,0 +1,142 @@
+/*
+ * 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 (
+	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 Thrift exception
+type TApplicationException interface {
+	TException
+	TypeId() int32
+	Read(iprot TProtocol) (TApplicationException, error)
+	Write(oprot TProtocol) error
+}
+
+type tApplicationException struct {
+	message string
+	type_   int32
+}
+
+func (e tApplicationException) Error() string {
+	return e.message
+}
+
+func NewTApplicationException(type_ int32, message string) TApplicationException {
+	return &tApplicationException{message, type_}
+}
+
+func (p *tApplicationException) TypeId() int32 {
+	return p.type_
+}
+
+func (p *tApplicationException) Read(iprot TProtocol) (TApplicationException, error) {
+	_, err := iprot.ReadStructBegin()
+	if err != nil {
+		return nil, err
+	}
+
+	message := ""
+	type_ := int32(UNKNOWN_APPLICATION_EXCEPTION)
+
+	for {
+		_, ttype, id, err := iprot.ReadFieldBegin()
+		if err != nil {
+			return nil, err
+		}
+		if ttype == STOP {
+			break
+		}
+		switch id {
+		case 1:
+			if ttype == STRING {
+				if message, err = iprot.ReadString(); err != nil {
+					return nil, err
+				}
+			} else {
+				if err = SkipDefaultDepth(iprot, ttype); err != nil {
+					return nil, err
+				}
+			}
+		case 2:
+			if ttype == I32 {
+				if type_, err = iprot.ReadI32(); err != nil {
+					return nil, err
+				}
+			} else {
+				if err = SkipDefaultDepth(iprot, ttype); err != nil {
+					return nil, err
+				}
+			}
+		default:
+			if err = SkipDefaultDepth(iprot, ttype); err != nil {
+				return nil, err
+			}
+		}
+		if err = iprot.ReadFieldEnd(); err != nil {
+			return nil, err
+		}
+	}
+	return NewTApplicationException(type_, message), iprot.ReadStructEnd()
+}
+
+func (p *tApplicationException) Write(oprot TProtocol) (err error) {
+	err = oprot.WriteStructBegin("TApplicationException")
+	if len(p.Error()) > 0 {
+		err = oprot.WriteFieldBegin("message", STRING, 1)
+		if err != nil {
+			return
+		}
+		err = oprot.WriteString(p.Error())
+		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/application_exception_test.go b/lib/go/thrift/application_exception_test.go
new file mode 100644
index 0000000..7010f86
--- /dev/null
+++ b/lib/go/thrift/application_exception_test.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 (
+	"testing"
+)
+
+func TestTApplicationException(t *testing.T) {
+	exc := NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "")
+	if exc.Error() != "" {
+		t.Fatalf("Expected empty string for exception but found '%s'", exc.Error())
+	}
+	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.Error() != "junk_method" {
+		t.Fatalf("Expected 'junk_method' for exception but found '%s'", exc.Error())
+	}
+	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/binary_protocol.go b/lib/go/thrift/binary_protocol.go
new file mode 100644
index 0000000..5880f65
--- /dev/null
+++ b/lib/go/thrift/binary_protocol.go
@@ -0,0 +1,489 @@
+/*
+ * 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"
+	"fmt"
+	"io"
+	"math"
+	"strings"
+)
+
+type TBinaryProtocol struct {
+	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) error {
+	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() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) WriteStructBegin(name string) error {
+	return nil
+}
+
+func (p *TBinaryProtocol) WriteStructEnd() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
+	e := p.WriteByte(byte(typeId))
+	if e != nil {
+		return e
+	}
+	e = p.WriteI16(id)
+	return e
+}
+
+func (p *TBinaryProtocol) WriteFieldEnd() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) WriteFieldStop() error {
+	e := p.WriteByte(STOP)
+	return e
+}
+
+func (p *TBinaryProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
+	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() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) WriteListBegin(elemType TType, size int) error {
+	e := p.WriteByte(byte(elemType))
+	if e != nil {
+		return e
+	}
+	e = p.WriteI32(int32(size))
+	return e
+}
+
+func (p *TBinaryProtocol) WriteListEnd() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) WriteSetBegin(elemType TType, size int) error {
+	e := p.WriteByte(byte(elemType))
+	if e != nil {
+		return e
+	}
+	e = p.WriteI32(int32(size))
+	return e
+}
+
+func (p *TBinaryProtocol) WriteSetEnd() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) WriteBool(value bool) error {
+	if value {
+		return p.WriteByte(1)
+	}
+	return p.WriteByte(0)
+}
+
+func (p *TBinaryProtocol) WriteByte(value byte) error {
+	v := []byte{value}
+	_, e := p.trans.Write(v)
+	return NewTProtocolException(e)
+}
+
+func (p *TBinaryProtocol) WriteI16(value int16) error {
+	h := byte(0xff & (value >> 8))
+	l := byte(0xff & value)
+	v := []byte{h, l}
+	_, e := p.trans.Write(v)
+	return NewTProtocolException(e)
+}
+
+func (p *TBinaryProtocol) WriteI32(value int32) error {
+	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 NewTProtocolException(e)
+}
+
+func (p *TBinaryProtocol) WriteI64(value int64) error {
+	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 NewTProtocolException(err)
+}
+
+func (p *TBinaryProtocol) WriteDouble(value float64) error {
+	return p.WriteI64(int64(math.Float64bits(value)))
+}
+
+func (p *TBinaryProtocol) WriteString(value string) error {
+	return p.WriteBinaryFromReader(strings.NewReader(value), len(value))
+}
+
+func (p *TBinaryProtocol) WriteBinary(value []byte) error {
+	e := p.WriteI32(int32(len(value)))
+	if e != nil {
+		return e
+	}
+	_, err := p.trans.Write(value)
+	return NewTProtocolException(err)
+}
+
+func (p *TBinaryProtocol) WriteBinaryFromReader(reader io.Reader, size int) error {
+	e := p.WriteI32(int32(size))
+	if e != nil {
+		return e
+	}
+	_, err := io.CopyN(p.trans, reader, int64(size))
+	return NewTProtocolException(err)
+}
+
+/**
+ * Reading methods
+ */
+
+func (p *TBinaryProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
+	size, e := p.ReadI32()
+	if e != nil {
+		return "", typeId, 0, NewTProtocolException(e)
+	}
+	if size < 0 {
+		typeId = TMessageType(size & 0x0ff)
+		version := int64(int64(size) & VERSION_MASK)
+		if version != VERSION_1 {
+			return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Bad version in ReadMessageBegin"))
+		}
+		name, e = p.ReadString()
+		if e != nil {
+			return name, typeId, seqId, NewTProtocolException(e)
+		}
+		seqId, e = p.ReadI32()
+		if e != nil {
+			return name, typeId, seqId, NewTProtocolException(e)
+		}
+		return name, typeId, seqId, nil
+	}
+	if p.strictRead {
+		return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("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() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) ReadStructBegin() (name string, err error) {
+	return
+}
+
+func (p *TBinaryProtocol) ReadStructEnd() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) ReadFieldBegin() (name string, typeId TType, seqId int16, err error) {
+	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() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err error) {
+	k, e := p.ReadByte()
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	kType = TType(k)
+	v, e := p.ReadByte()
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	vType = TType(v)
+	size32, e := p.ReadI32()
+	size = int(size32)
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	return kType, vType, size, nil
+}
+
+func (p *TBinaryProtocol) ReadMapEnd() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err error) {
+	b, e := p.ReadByte()
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	elemType = TType(b)
+	size32, e := p.ReadI32()
+	size = int(size32)
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	return elemType, size, nil
+}
+
+func (p *TBinaryProtocol) ReadListEnd() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err error) {
+	b, e := p.ReadByte()
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	elemType = TType(b)
+	size32, e := p.ReadI32()
+	size = int(size32)
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	return elemType, size, nil
+}
+
+func (p *TBinaryProtocol) ReadSetEnd() error {
+	return nil
+}
+
+func (p *TBinaryProtocol) ReadBool() (bool, error) {
+	b, e := p.ReadByte()
+	v := true
+	if b != 1 {
+		v = false
+	}
+	return v, e
+}
+
+func (p *TBinaryProtocol) ReadByte() (value byte, err error) {
+	buf := []byte{0}
+	err = p.readAll(buf)
+	return buf[0], err
+}
+
+func (p *TBinaryProtocol) ReadI16() (value int16, err error) {
+	buf := []byte{0, 0}
+	err = p.readAll(buf)
+	value = int16(binary.BigEndian.Uint16(buf))
+	return value, err
+}
+
+func (p *TBinaryProtocol) ReadI32() (value int32, err error) {
+	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 error) {
+	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 error) {
+	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 error) {
+	size, e := p.ReadI32()
+	if e != nil {
+		return "", e
+	}
+	return p.readStringBody(int(size))
+}
+
+func (p *TBinaryProtocol) ReadBinary() ([]byte, error) {
+	size, e := p.ReadI32()
+	if e != nil {
+		return nil, e
+	}
+	isize := int(size)
+	if e = p.readLengthOk(isize); e != nil {
+		return nil, e
+	}
+	buf := make([]byte, isize)
+	_, err := io.ReadFull(p.trans, buf)
+	return buf, NewTProtocolException(err)
+}
+
+func (p *TBinaryProtocol) Flush() (err error) {
+	return NewTProtocolException(p.trans.Flush())
+}
+
+func (p *TBinaryProtocol) Skip(fieldType TType) (err error) {
+	return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TBinaryProtocol) Transport() TTransport {
+	return p.trans
+}
+
+func (p *TBinaryProtocol) readAll(buf []byte) error {
+	if e := p.readLengthOk(len(buf)); e != nil {
+		return e
+	}
+	_, err := io.ReadFull(p.trans, buf)
+	return NewTProtocolException(err)
+}
+
+func (p *TBinaryProtocol) setReadLength(readLength int) {
+	p.readLength = readLength
+	p.checkReadLength = true
+}
+
+func (p *TBinaryProtocol) readLengthOk(length int) error {
+	if p.checkReadLength {
+		p.readLength = p.readLength - length
+		if p.readLength < 0 {
+			return NewTProtocolExceptionWithType(UNKNOWN_PROTOCOL_EXCEPTION, fmt.Errorf("Message length exceeded: %d", length))
+		}
+	}
+	return nil
+}
+
+func (p *TBinaryProtocol) readStringBody(size int) (value string, err error) {
+	if size < 0 {
+		return "", nil
+	}
+	if err := p.readLengthOk(size); err != nil {
+		return "", err
+	}
+	isize := int(size)
+	buf := make([]byte, isize)
+	_, e := io.ReadFull(p.trans, buf)
+	return string(buf), NewTProtocolException(e)
+}
diff --git a/lib/go/thrift/tbinary_protocol_test.go b/lib/go/thrift/binary_protocol_test.go
similarity index 87%
rename from lib/go/thrift/tbinary_protocol_test.go
rename to lib/go/thrift/binary_protocol_test.go
index b21b248..0462cc7 100644
--- a/lib/go/thrift/tbinary_protocol_test.go
+++ b/lib/go/thrift/binary_protocol_test.go
@@ -17,15 +17,12 @@
  * under the License.
  */
 
-package thrift_test
+package thrift
 
 import (
-  . "thrift"
-  "testing"
-  //"bytes";
+	"testing"
 )
 
-
 func TestReadWriteBinaryProtocol(t *testing.T) {
-  ReadWriteProtocolTest(t, NewTBinaryProtocolFactoryDefault())
+	ReadWriteProtocolTest(t, NewTBinaryProtocolFactoryDefault())
 }
diff --git a/lib/go/thrift/compact_protocol.go b/lib/go/thrift/compact_protocol.go
new file mode 100644
index 0000000..ba5f722
--- /dev/null
+++ b/lib/go/thrift/compact_protocol.go
@@ -0,0 +1,752 @@
+/*
+ * 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"
+	"fmt"
+	"io"
+	"math"
+	"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 map[TType]tCompactType
+)
+
+func init() {
+	ttypeToCompactType = map[TType]tCompactType{
+		STOP:   STOP,
+		BOOL:   COMPACT_BOOLEAN_TRUE,
+		BYTE:   COMPACT_BYTE,
+		I16:    COMPACT_I16,
+		I32:    COMPACT_I32,
+		I64:    COMPACT_I64,
+		DOUBLE: COMPACT_DOUBLE,
+		STRING: COMPACT_BINARY,
+		LIST:   COMPACT_LIST,
+		SET:    COMPACT_SET,
+		MAP:    COMPACT_MAP,
+		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   []int
+	lastFieldId int
+
+	// If we encounter a boolean field begin, save the TField here so it can
+	// have the value incorporated.
+	booleanField *field
+
+	// 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 given a TTransport
+func NewTCompactProtocol(trans TTransport) *TCompactProtocol {
+	return &TCompactProtocol{trans: trans, lastField: []int{}}
+}
+
+//
+// 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) error {
+	_, err := p.writeByteDirect(COMPACT_PROTOCOL_ID)
+	if err != nil {
+		return NewTProtocolException(err)
+	}
+	_, err = p.writeByteDirect((COMPACT_VERSION & COMPACT_VERSION_MASK) | ((byte(typeId) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK))
+	if err != nil {
+		return NewTProtocolException(err)
+	}
+	_, err = p.writeVarint32(seqid)
+	if err != nil {
+		return NewTProtocolException(err)
+	}
+	e := p.WriteString(name)
+	return e
+
+}
+
+func (p *TCompactProtocol) WriteMessageEnd() error { 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) error {
+	p.lastField = append(p.lastField, 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() error {
+	p.lastFieldId = p.lastField[len(p.lastField)-1]
+	p.lastField = p.lastField[:len(p.lastField)-1]
+	return nil
+}
+
+func (p *TCompactProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
+	if typeId == BOOL {
+		// we want to possibly include the value, so we'll wait.
+		p.booleanField = newField(name, typeId, int(id))
+		return nil
+	}
+	_, err := p.writeFieldBeginInternal(name, typeId, id, 0xFF)
+	return NewTProtocolException(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, 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() error { return nil }
+
+func (p *TCompactProtocol) WriteFieldStop() error {
+	_, err := p.writeByteDirect(STOP)
+	return NewTProtocolException(err)
+}
+
+func (p *TCompactProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
+	if size == 0 {
+		_, err := p.writeByteDirect(0)
+		return NewTProtocolException(err)
+	}
+	_, err := p.writeVarint32(int32(size))
+	if err != nil {
+		return NewTProtocolException(err)
+	}
+	_, err = p.writeByteDirect(byte(p.getCompactType(keyType))<<4 | byte(p.getCompactType(valueType)))
+	return NewTProtocolException(err)
+}
+
+func (p *TCompactProtocol) WriteMapEnd() error { return nil }
+
+// Write a list header.
+func (p *TCompactProtocol) WriteListBegin(elemType TType, size int) error {
+	_, err := p.writeCollectionBegin(elemType, size)
+	return NewTProtocolException(err)
+}
+
+func (p *TCompactProtocol) WriteListEnd() error { return nil }
+
+// Write a set header.
+func (p *TCompactProtocol) WriteSetBegin(elemType TType, size int) error {
+	_, err := p.writeCollectionBegin(elemType, size)
+	return NewTProtocolException(err)
+}
+
+func (p *TCompactProtocol) WriteSetEnd() error { return nil }
+
+func (p *TCompactProtocol) WriteBool(value bool) error {
+	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 NewTProtocolException(err)
+	}
+	// we're not part of a field, so just write the value.
+	_, err := p.writeByteDirect(v)
+	return NewTProtocolException(err)
+}
+
+// Write a byte. Nothing to see here!
+func (p *TCompactProtocol) WriteByte(value byte) error {
+	_, err := p.writeByteDirect(value)
+	return NewTProtocolException(err)
+}
+
+// Write an I16 as a zigzag varint.
+func (p *TCompactProtocol) WriteI16(value int16) error {
+	_, err := p.writeVarint32(p.int32ToZigzag(int32(value)))
+	return NewTProtocolException(err)
+}
+
+// Write an i32 as a zigzag varint.
+func (p *TCompactProtocol) WriteI32(value int32) error {
+	_, err := p.writeVarint32(p.int32ToZigzag(value))
+	return NewTProtocolException(err)
+}
+
+// Write an i64 as a zigzag varint.
+func (p *TCompactProtocol) WriteI64(value int64) error {
+	_, err := p.writeVarint64(p.int64ToZigzag(value))
+	return NewTProtocolException(err)
+}
+
+// Write a double to the wire as 8 bytes.
+func (p *TCompactProtocol) WriteDouble(value float64) error {
+	buf := make([]byte, 8)
+	binary.LittleEndian.PutUint64(buf, math.Float64bits(value))
+	_, err := p.trans.Write(buf)
+	return NewTProtocolException(err)
+}
+
+// Write a string to the wire with a varint size preceeding.
+func (p *TCompactProtocol) WriteString(value string) error {
+	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) error {
+	_, e := p.writeVarint32(int32(len(bin)))
+	if e != nil {
+		return NewTProtocolException(e)
+	}
+	if len(bin) > 0 {
+		_, e = p.trans.Write(bin)
+		return NewTProtocolException(e)
+	}
+	return nil
+}
+
+//
+// Reading methods.
+//
+
+// Read a message header.
+func (p *TCompactProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
+	protocolId, err := p.ReadByte()
+	if protocolId != COMPACT_PROTOCOL_ID {
+		e := fmt.Errorf("Expected protocol id %02x but got %02x", COMPACT_PROTOCOL_ID, protocolId)
+		return "", typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, e)
+	}
+	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 {
+		e := fmt.Errorf("Expected version %02x but got %02x", COMPACT_VERSION, version)
+		err = NewTProtocolExceptionWithType(BAD_VERSION, e)
+		return
+	}
+	seqId, e := p.readVarint32()
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	name, err = p.ReadString()
+	return
+}
+
+func (p *TCompactProtocol) ReadMessageEnd() error { 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 error) {
+	p.lastField = append(p.lastField, 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() error {
+	// consume the last field we read off the wire.
+	p.lastFieldId = p.lastField[len(p.lastField)-1]
+	return nil
+}
+
+// Read a field header off the wire.
+func (p *TCompactProtocol) ReadFieldBegin() (name string, typeId TType, id int16, err error) {
+	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 "", STOP, 0,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 = NewTProtocolException(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() error { 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 error) {
+	size32, e := p.readVarint32()
+	size = int(size32)
+	if e != nil {
+		err = NewTProtocolException(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() error { 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 error) {
+	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 = NewTProtocolException(e)
+			return
+		}
+		size = int(size2)
+	}
+	elemType, e := p.getTType(tCompactType(size_and_type))
+	if e != nil {
+		err = NewTProtocolException(e)
+		return
+	}
+	return
+}
+
+func (p *TCompactProtocol) ReadListEnd() error { 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 error) {
+	return p.ReadListBegin()
+}
+
+func (p *TCompactProtocol) ReadSetEnd() error { 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 error) {
+	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 error) {
+	buf := []byte{0}
+	_, e := io.ReadFull(p.trans, buf)
+	if e != nil {
+		return 0, NewTProtocolException(e)
+	}
+	return buf[0], nil
+}
+
+// Read an i16 from the wire as a zigzag varint.
+func (p *TCompactProtocol) ReadI16() (value int16, err error) {
+	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 error) {
+	v, e := p.readVarint32()
+	if e != nil {
+		return 0, NewTProtocolException(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 error) {
+	v, e := p.readVarint64()
+	if e != nil {
+		return 0, NewTProtocolException(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 error) {
+	longBits := make([]byte, 8)
+	_, e := io.ReadFull(p.trans, longBits)
+	if e != nil {
+		return 0.0, NewTProtocolException(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 error) {
+	v, e := p.ReadBinary()
+	return string(v), NewTProtocolException(e)
+}
+
+// Read a []byte from the wire.
+func (p *TCompactProtocol) ReadBinary() (value []byte, err error) {
+	length, e := p.readVarint32()
+	if e != nil {
+		return []byte{}, NewTProtocolException(e)
+	}
+	if length == 0 {
+		return []byte{}, nil
+	}
+
+	buf := make([]byte, length)
+	_, e = io.ReadFull(p.trans, buf)
+	return buf, NewTProtocolException(e)
+}
+
+func (p *TCompactProtocol) Flush() (err error) {
+	return NewTProtocolException(p.trans.Flush())
+}
+
+func (p *TCompactProtocol) Skip(fieldType TType) (err error) {
+	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, 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, 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, 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, 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, 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, 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, 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, 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, TException(fmt.Errorf("don't know what type: %s", t&0x0f))
+}
+
+// Given a TType value, find the appropriate TCompactProtocol.Types constant.
+func (p *TCompactProtocol) getCompactType(t TType) tCompactType {
+	return ttypeToCompactType[t]
+}
diff --git a/lib/go/thrift/compact_protocol_test.go b/lib/go/thrift/compact_protocol_test.go
new file mode 100644
index 0000000..c874379
--- /dev/null
+++ b/lib/go/thrift/compact_protocol_test.go
@@ -0,0 +1,54 @@
+/*
+ * 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 (
+	"testing"
+)
+
+func TestReadWriteCompactProtocol(t *testing.T) {
+	ReadWriteProtocolTest(t, NewTCompactProtocolFactory())
+	/*
+	   transports := []TTransport{
+	     NewTMemoryBuffer(),
+	     NewStreamTransportRW(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/tnonblocking_transport.go b/lib/go/thrift/exception.go
similarity index 92%
rename from lib/go/thrift/tnonblocking_transport.go
rename to lib/go/thrift/exception.go
index da9c26d..e08ffc0 100644
--- a/lib/go/thrift/tnonblocking_transport.go
+++ b/lib/go/thrift/exception.go
@@ -19,6 +19,7 @@
 
 package thrift
 
-type TNonblockingTransport interface {
-  TTransport
+// Generic Thrift exception
+type TException interface {
+	error
 }
diff --git a/lib/go/thrift/field.go b/lib/go/thrift/field.go
new file mode 100644
index 0000000..9d66525
--- /dev/null
+++ b/lib/go/thrift/field.go
@@ -0,0 +1,79 @@
+/*
+ * 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 field metadata.
+type field struct {
+	name   string
+	typeId TType
+	id     int
+}
+
+func newField(n string, t TType, i int) *field {
+	return &field{name: n, typeId: t, id: i}
+}
+
+func (p *field) Name() string {
+	if p == nil {
+		return ""
+	}
+	return p.name
+}
+
+func (p *field) TypeId() TType {
+	if p == nil {
+		return TType(VOID)
+	}
+	return p.typeId
+}
+
+func (p *field) Id() int {
+	if p == nil {
+		return -1
+	}
+	return p.id
+}
+
+func (p *field) String() string {
+	if p == nil {
+		return "<nil>"
+	}
+	return "<TField name:'" + p.name + "' type:" + string(p.typeId) + " field-id:" + string(p.id) + ">"
+}
+
+var ANONYMOUS_FIELD *field
+
+type fieldSlice []field
+
+func (p fieldSlice) Len() int {
+	return len(p)
+}
+
+func (p fieldSlice) Less(i, j int) bool {
+	return p[i].Id() < p[j].Id()
+}
+
+func (p fieldSlice) Swap(i, j int) {
+	p[i], p[j] = p[j], p[i]
+}
+
+func init() {
+	ANONYMOUS_FIELD = newField("", STOP, 0)
+}
diff --git a/lib/go/thrift/framed_transport.go b/lib/go/thrift/framed_transport.go
new file mode 100644
index 0000000..3a59e7b
--- /dev/null
+++ b/lib/go/thrift/framed_transport.go
@@ -0,0 +1,124 @@
+/*
+ * 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"
+	"encoding/binary"
+	"io"
+)
+
+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() 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() error {
+	return p.transport.Close()
+}
+
+func (p *TFramedTransport) Read(buf []byte) (int, error) {
+	if p.readBuffer.Len() > 0 {
+		got, err := p.readBuffer.Read(buf)
+		if got > 0 {
+			return got, NewTTransportExceptionFromError(err)
+		}
+	}
+
+	// Read another frame of data
+	p.readFrame()
+
+	got, err := p.readBuffer.Read(buf)
+	return got, NewTTransportExceptionFromError(err)
+}
+
+func (p *TFramedTransport) Write(buf []byte) (int, error) {
+	n, err := p.writeBuffer.Write(buf)
+	return n, NewTTransportExceptionFromError(err)
+}
+
+func (p *TFramedTransport) Flush() 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 NewTTransportExceptionFromError(err)
+	}
+	if size > 0 {
+		if n, err := p.writeBuffer.WriteTo(p.transport); err != nil {
+			print("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err, "\n")
+			return NewTTransportExceptionFromError(err)
+		}
+	}
+	err = p.transport.Flush()
+	return NewTTransportExceptionFromError(err)
+}
+
+func (p *TFramedTransport) readFrame() (int, error) {
+	buf := []byte{0, 0, 0, 0}
+	if _, err := io.ReadFull(p.transport, buf); err != nil {
+		return 0, err
+	}
+	size := int(binary.BigEndian.Uint32(buf))
+	if size < 0 {
+		return 0, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "Read a negative frame size ("+string(size)+")")
+	}
+	if size == 0 {
+		return 0, nil
+	}
+	buf2 := make([]byte, size)
+	if n, err := io.ReadFull(p.transport, buf2); 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/framed_transport_test.go
similarity index 87%
rename from lib/go/thrift/tframed_transport_test.go
rename to lib/go/thrift/framed_transport_test.go
index 566318c..8f683ef 100644
--- a/lib/go/thrift/tframed_transport_test.go
+++ b/lib/go/thrift/framed_transport_test.go
@@ -17,14 +17,13 @@
  * under the License.
  */
 
-package thrift_test
+package thrift
 
 import (
-  . "thrift"
-  "testing"
+	"testing"
 )
 
 func TestFramedTransport(t *testing.T) {
-  trans := NewTFramedTransport(NewTMemoryBuffer())
-  TransportTest(t, trans, trans)
+	trans := NewTFramedTransport(NewTMemoryBuffer())
+	TransportTest(t, trans, trans)
 }
diff --git a/lib/go/thrift/http_client.go b/lib/go/thrift/http_client.go
new file mode 100644
index 0000000..18b1671
--- /dev/null
+++ b/lib/go/thrift/http_client.go
@@ -0,0 +1,141 @@
+/*
+ * 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"
+	"net/http"
+	"net/url"
+	"strconv"
+)
+
+type THttpClient struct {
+	response           *http.Response
+	url                *url.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(urlstr string) (TTransport, error) {
+	parsedURL, err := url.Parse(urlstr)
+	if err != nil {
+		return nil, err
+	}
+	response, err := http.Get(urlstr)
+	if err != nil {
+		return nil, err
+	}
+	return &THttpClient{response: response, url: parsedURL}, nil
+}
+
+func NewTHttpPostClient(urlstr string) (TTransport, error) {
+	parsedURL, err := url.Parse(urlstr)
+	if err != nil {
+		return nil, err
+	}
+	buf := make([]byte, 0, 1024)
+	return &THttpClient{url: parsedURL, requestBuffer: bytes.NewBuffer(buf)}, nil
+}
+
+func (p *THttpClient) Open() 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() 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, 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, NewTTransportExceptionFromError(err)
+}
+
+func (p *THttpClient) Write(buf []byte) (int, error) {
+	n, err := p.requestBuffer.Write(buf)
+	return n, err
+}
+
+func (p *THttpClient) Flush() error {
+	response, err := http.Post(p.url.String(), "application/x-thrift", p.requestBuffer)
+	if err != nil {
+		return NewTTransportExceptionFromError(err)
+	}
+	if response.StatusCode != http.StatusOK {
+		// TODO(pomack) log bad response
+		return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "HTTP Response code: "+strconv.Itoa(response.StatusCode))
+	}
+	p.response = response
+	return nil
+}
diff --git a/lib/go/thrift/thttp_client_test.go b/lib/go/thrift/http_client_test.go
similarity index 73%
rename from lib/go/thrift/thttp_client_test.go
rename to lib/go/thrift/http_client_test.go
index fdd2f50..041faec 100644
--- a/lib/go/thrift/thttp_client_test.go
+++ b/lib/go/thrift/http_client_test.go
@@ -17,22 +17,21 @@
  * under the License.
  */
 
-package thrift_test
+package thrift
 
 import (
-  . "thrift"
-  "testing"
+	"testing"
 )
 
 func TestHttpClient(t *testing.T) {
-  l, addr := HttpClientSetupForTest(t)
-  if l != nil {
-    defer l.Close()
-  }
-  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)
+	l, addr := HttpClientSetupForTest(t)
+	if l != nil {
+		defer l.Close()
+	}
+	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/iostream_transport.go b/lib/go/thrift/iostream_transport.go
new file mode 100644
index 0000000..64b2958
--- /dev/null
+++ b/lib/go/thrift/iostream_transport.go
@@ -0,0 +1,168 @@
+/*
+ * 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"
+)
+
+// StreamTransport is a Transport made of an io.Reader and/or an io.Writer
+type StreamTransport struct {
+	Reader       io.Reader
+	Writer       io.Writer
+	isReadWriter bool
+}
+
+type StreamTransportFactory struct {
+	Reader       io.Reader
+	Writer       io.Writer
+	isReadWriter bool
+}
+
+func (p *StreamTransportFactory) GetTransport(trans TTransport) TTransport {
+	if trans != nil {
+		t, ok := trans.(*StreamTransport)
+		if ok {
+			if t.isReadWriter {
+				return NewStreamTransportRW(t.Reader.(io.ReadWriter))
+			}
+			if t.Reader != nil && t.Writer != nil {
+				return NewStreamTransport(t.Reader, t.Writer)
+			}
+			if t.Reader != nil && t.Writer == nil {
+				return NewStreamTransportR(t.Reader)
+			}
+			if t.Reader == nil && t.Writer != nil {
+				return NewStreamTransportW(t.Writer)
+			}
+			return &StreamTransport{}
+		}
+	}
+	if p.isReadWriter {
+		return NewStreamTransportRW(p.Reader.(io.ReadWriter))
+	}
+	if p.Reader != nil && p.Writer != nil {
+		return NewStreamTransport(p.Reader, p.Writer)
+	}
+	if p.Reader != nil && p.Writer == nil {
+		return NewStreamTransportR(p.Reader)
+	}
+	if p.Reader == nil && p.Writer != nil {
+		return NewStreamTransportW(p.Writer)
+	}
+	return &StreamTransport{}
+}
+
+func NewStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *StreamTransportFactory {
+	return &StreamTransportFactory{Reader: reader, Writer: writer, isReadWriter: isReadWriter}
+}
+
+func NewStreamTransport(r io.Reader, w io.Writer) *StreamTransport {
+	return &StreamTransport{Reader: bufio.NewReader(r), Writer: bufio.NewWriter(w)}
+}
+
+func NewStreamTransportR(r io.Reader) *StreamTransport {
+	return &StreamTransport{Reader: bufio.NewReader(r)}
+}
+
+func NewStreamTransportW(w io.Writer) *StreamTransport {
+	return &StreamTransport{Writer: bufio.NewWriter(w)}
+}
+
+func NewStreamTransportRW(rw io.ReadWriter) *StreamTransport {
+	bufrw := bufio.NewReadWriter(bufio.NewReader(rw), bufio.NewWriter(rw))
+	return &StreamTransport{Reader: bufrw, Writer: bufrw, isReadWriter: true}
+}
+
+// (The streams must already be open at construction time, so this should
+// always return true.)
+func (p *StreamTransport) IsOpen() bool {
+	return true
+}
+
+// (The streams must already be open. This method does nothing.)
+func (p *StreamTransport) Open() error {
+	return nil
+}
+
+func (p *StreamTransport) Peek() bool {
+	return p.IsOpen()
+}
+
+// Closes both the input and output streams.
+func (p *StreamTransport) Close() error {
+	closedReader := false
+	if p.Reader != nil {
+		c, ok := p.Reader.(io.Closer)
+		if ok {
+			e := c.Close()
+			closedReader = true
+			if e != nil {
+				return 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 {
+				return e
+			}
+		}
+		p.Writer = nil
+	}
+	return nil
+}
+
+// Reads from the underlying input stream if not null.
+func (p *StreamTransport) Read(buf []byte) (int, error) {
+	if p.Reader == nil {
+		return 0, NewTTransportException(NOT_OPEN, "Cannot read from null inputStream")
+	}
+	n, err := p.Reader.Read(buf)
+	return n, NewTTransportExceptionFromError(err)
+}
+
+// Writes to the underlying output stream if not null.
+func (p *StreamTransport) Write(buf []byte) (int, error) {
+	if p.Writer == nil {
+		return 0, NewTTransportException(NOT_OPEN, "Cannot write to null outputStream")
+	}
+	n, err := p.Writer.Write(buf)
+	return n, NewTTransportExceptionFromError(err)
+}
+
+// Flushes the underlying output stream if not null.
+func (p *StreamTransport) Flush() 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 NewTTransportExceptionFromError(err)
+		}
+	}
+	return nil
+}
diff --git a/lib/go/thrift/tcontainer.go b/lib/go/thrift/iostream_transport_test.go
similarity index 82%
rename from lib/go/thrift/tcontainer.go
rename to lib/go/thrift/iostream_transport_test.go
index 9ea3cba..15ea2d4 100644
--- a/lib/go/thrift/tcontainer.go
+++ b/lib/go/thrift/iostream_transport_test.go
@@ -17,12 +17,14 @@
  * under the License.
  */
 
-
 package thrift
 
-type TContainer interface {
-  Len() int
-  Contains(data interface{}) bool
-  Equals(other interface{}) bool
-  CompareTo(other interface{}) (int, bool)
+import (
+	"bytes"
+	"testing"
+)
+
+func TestStreamTransport(t *testing.T) {
+	trans := NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024)))
+	TransportTest(t, trans, trans)
 }
diff --git a/lib/go/thrift/json_protocol.go b/lib/go/thrift/json_protocol.go
new file mode 100644
index 0000000..5e8453a
--- /dev/null
+++ b/lib/go/thrift/json_protocol.go
@@ -0,0 +1,556 @@
+/*
+ * 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 = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL))
+	v.dumpContext = append(v.dumpContext, 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) error {
+	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() error {
+	return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteStructBegin(name string) error {
+	if e := p.OutputObjectBegin(); e != nil {
+		return e
+	}
+	return nil
+}
+
+func (p *TJSONProtocol) WriteStructEnd() error {
+	return p.OutputObjectEnd()
+}
+
+func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
+	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() error {
+	return p.OutputObjectEnd()
+}
+
+func (p *TJSONProtocol) WriteFieldStop() error { return nil }
+
+func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
+	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() error {
+	return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) error {
+	return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TJSONProtocol) WriteListEnd() error {
+	return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) error {
+	return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TJSONProtocol) WriteSetEnd() error {
+	return p.OutputListEnd()
+}
+
+func (p *TJSONProtocol) WriteBool(b bool) error {
+	return p.OutputBool(b)
+}
+
+func (p *TJSONProtocol) WriteByte(b byte) error {
+	return p.WriteI32(int32(b))
+}
+
+func (p *TJSONProtocol) WriteI16(v int16) error {
+	return p.WriteI32(int32(v))
+}
+
+func (p *TJSONProtocol) WriteI32(v int32) error {
+	return p.OutputI64(int64(v))
+}
+
+func (p *TJSONProtocol) WriteI64(v int64) error {
+	return p.OutputI64(int64(v))
+}
+
+func (p *TJSONProtocol) WriteDouble(v float64) error {
+	return p.OutputF64(v)
+}
+
+func (p *TJSONProtocol) WriteString(v string) error {
+	return p.OutputString(v)
+}
+
+func (p *TJSONProtocol) WriteBinary(v []byte) error {
+	// 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 NewTProtocolException(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 error) {
+	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 {
+		e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION)
+		return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e)
+
+	}
+	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() error {
+	err := p.ParseListEnd()
+	return err
+}
+
+func (p *TJSONProtocol) ReadStructBegin() (name string, err error) {
+	_, err = p.ParseObjectStart()
+	return "", err
+}
+
+func (p *TJSONProtocol) ReadStructEnd() error {
+	return p.ParseObjectEnd()
+}
+
+func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, error) {
+	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() error {
+	return p.ParseObjectEnd()
+}
+
+func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) {
+	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() error {
+	return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e error) {
+	return p.ParseElemListBegin()
+}
+
+func (p *TJSONProtocol) ReadListEnd() error {
+	return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) {
+	return p.ParseElemListBegin()
+}
+
+func (p *TJSONProtocol) ReadSetEnd() error {
+	return p.ParseListEnd()
+}
+
+func (p *TJSONProtocol) ReadBool() (bool, error) {
+	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 {
+				e := fmt.Errorf("Expected \"true\" but found: %s", string(b))
+				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			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 {
+				e := fmt.Errorf("Expected \"false\" but found: %s", string(b))
+				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			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 {
+				e := fmt.Errorf("Expected \"null\" but found: %s", string(b))
+				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+		default:
+			e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(b))
+			return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+		}
+	}
+	return value, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) ReadByte() (byte, error) {
+	v, err := p.ReadI64()
+	return byte(v), err
+}
+
+func (p *TJSONProtocol) ReadI16() (int16, error) {
+	v, err := p.ReadI64()
+	return int16(v), err
+}
+
+func (p *TJSONProtocol) ReadI32() (int32, error) {
+	v, err := p.ReadI64()
+	return int32(v), err
+}
+
+func (p *TJSONProtocol) ReadI64() (int64, error) {
+	v, _, err := p.ParseI64()
+	return v, err
+}
+
+func (p *TJSONProtocol) ReadDouble() (float64, error) {
+	v, _, err := p.ParseF64()
+	return v, err
+}
+
+func (p *TJSONProtocol) ReadString() (string, error) {
+	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, NewTProtocolException(err)
+		}
+	} else {
+		e := fmt.Errorf("Expected a JSON string, found %s", string(b))
+		return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	return v, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) ReadBinary() ([]byte, error) {
+	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, NewTProtocolException(err)
+		}
+	} else {
+		e := fmt.Errorf("Expected a JSON string, found %s", string(b))
+		return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	return v, p.ParsePostValue()
+}
+
+func (p *TJSONProtocol) Flush() (err error) {
+	return NewTProtocolException(p.writer.Flush())
+}
+
+func (p *TJSONProtocol) Skip(fieldType TType) (err error) {
+	return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TJSONProtocol) Transport() TTransport {
+	return p.trans
+}
+
+func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error {
+	if e := p.OutputListBegin(); e != nil {
+		return e
+	}
+	if e := p.WriteString(p.TypeIdToString(elemType)); e != nil {
+		return e
+	}
+	if e := p.WriteI64(int64(size)); e != nil {
+		return e
+	}
+	return nil
+}
+
+
+func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) {
+	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) readElemListBegin() (elemType TType, size int, e error) {
+	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) error {
+	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 UTF16:
+		return "str"
+	}
+	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 "u16":
+		return TType(UTF16)
+	}
+	return TType(STOP)
+}
diff --git a/lib/go/thrift/json_protocol_test.go b/lib/go/thrift/json_protocol_test.go
new file mode 100644
index 0000000..cb626cc
--- /dev/null
+++ b/lib/go/thrift/json_protocol_test.go
@@ -0,0 +1,639 @@
+/*
+ * 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"
+	"encoding/json"
+	"fmt"
+	"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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.FormatInt(value, 10))
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+	}
+	if e := p.Flush(); e != nil {
+		t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+	}
+	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.Error())
+	}
+	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.Error())
+	}
+	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.Error())
+		}
+	}
+	p.WriteListEnd()
+	if e := p.Flush(); e != nil {
+		t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+	}
+	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 l[0] != "dbl" {
+		t.Fatal("Invalid type for list, expected: ", STRING, ", 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.Error())
+		}
+	}
+	p.WriteSetEnd()
+	if e := p.Flush(); e != nil {
+		t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+	}
+	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 l[0] != "dbl" {
+		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.Error())
+		}
+		if e := p.WriteDouble(value); e != nil {
+			t.Fatalf("Unable to write %s value float64 value %v due to error: %s", thetype, value, e.Error())
+		}
+	}
+	p.WriteMapEnd()
+	if e := p.Flush(); e != nil {
+		t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+	}
+	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.Error())
+	}
+	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.Error())
+		}
+		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.Error())
+		}
+		s := strconv.FormatFloat(dv, 'g', 10, 64)
+		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.FormatFloat(value, 'g', 10, 64)
+			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()
+}
diff --git a/lib/go/thrift/memory_buffer.go b/lib/go/thrift/memory_buffer.go
new file mode 100644
index 0000000..c48e089
--- /dev/null
+++ b/lib/go/thrift/memory_buffer.go
@@ -0,0 +1,79 @@
+/*
+ * 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"
+)
+
+// Memory buffer-based implementation of the TTransport interface.
+type TMemoryBuffer struct {
+	*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{Buffer: &bytes.Buffer{}, size: 0}
+}
+
+func NewTMemoryBufferLen(size int) *TMemoryBuffer {
+	buf := make([]byte, 0, size)
+	return &TMemoryBuffer{Buffer: bytes.NewBuffer(buf), size: size}
+}
+
+func (p *TMemoryBuffer) IsOpen() bool {
+	return true
+}
+
+func (p *TMemoryBuffer) Open() error {
+	return nil
+}
+
+func (p *TMemoryBuffer) Peek() bool {
+	return p.IsOpen()
+}
+
+func (p *TMemoryBuffer) Close() error {
+	p.Buffer.Reset()
+	return nil
+}
+
+// Flushing a memory buffer is a no-op
+func (p *TMemoryBuffer) Flush() error {
+	return nil
+}
diff --git a/lib/go/thrift/tmemory_buffer_test.go b/lib/go/thrift/memory_buffer_test.go
similarity index 88%
rename from lib/go/thrift/tmemory_buffer_test.go
rename to lib/go/thrift/memory_buffer_test.go
index 5d17864..af2e8bf 100644
--- a/lib/go/thrift/tmemory_buffer_test.go
+++ b/lib/go/thrift/memory_buffer_test.go
@@ -17,14 +17,13 @@
  * under the License.
  */
 
-package thrift_test
+package thrift
 
 import (
-  . "thrift"
-  "testing"
+	"testing"
 )
 
 func TestMemoryBuffer(t *testing.T) {
-  trans := NewTMemoryBufferLen(1024)
-  TransportTest(t, trans, trans)
+	trans := NewTMemoryBufferLen(1024)
+	TransportTest(t, trans, trans)
 }
diff --git a/lib/go/thrift/tmessagetype.go b/lib/go/thrift/messagetype.go
similarity index 76%
rename from lib/go/thrift/tmessagetype.go
rename to lib/go/thrift/messagetype.go
index b31c66c..25ab2e9 100644
--- a/lib/go/thrift/tmessagetype.go
+++ b/lib/go/thrift/messagetype.go
@@ -19,16 +19,13 @@
 
 package thrift
 
-/**
- * Message type constants in the Thrift protocol.
- *
- */
+// 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
+	INVALID_TMESSAGE_TYPE TMessageType = 0
+	CALL                  TMessageType = 1
+	REPLY                 TMessageType = 2
+	EXCEPTION             TMessageType = 3
+	ONEWAY                TMessageType = 4
 )
diff --git a/lib/go/thrift/numeric.go b/lib/go/thrift/numeric.go
new file mode 100644
index 0000000..aa8daa9
--- /dev/null
+++ b/lib/go/thrift/numeric.go
@@ -0,0 +1,164 @@
+/*
+ * 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.FormatFloat(dValue, 'g', 10, 64)
+	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.ParseInt(sValue, 10, 64)
+	dValue, _ := strconv.ParseFloat(sValue, 64)
+	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.ParseInt(sValue, 10, 64)
+	dValue, _ := strconv.ParseFloat(sValue, 64)
+	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/processor.go
similarity index 80%
rename from lib/go/thrift/tprocessor.go
rename to lib/go/thrift/processor.go
index d2bb5e4..ca0d3fa 100644
--- a/lib/go/thrift/tprocessor.go
+++ b/lib/go/thrift/processor.go
@@ -19,15 +19,12 @@
 
 package thrift
 
-/**
- * A processor is a generic object which operates upon an input stream and
- * writes to some output stream.
- *
- */
+// 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)
+	Process(in, out TProtocol) (bool, TException)
 }
 
 type TProcessorFunction interface {
-  Process(seqId int32, in, out TProtocol) (bool, TException)
+	Process(seqId int32, in, out TProtocol) (bool, TException)
 }
diff --git a/lib/go/thrift/tprocessor_factory.go b/lib/go/thrift/processor_factory.go
similarity index 78%
rename from lib/go/thrift/tprocessor_factory.go
rename to lib/go/thrift/processor_factory.go
index 72681ab..9d645df 100644
--- a/lib/go/thrift/tprocessor_factory.go
+++ b/lib/go/thrift/processor_factory.go
@@ -19,44 +19,40 @@
 
 package thrift
 
-
-/**
- * The default processor factory just returns a singleton
- * instance.
- */
+// The default processor factory just returns a singleton
+// instance.
 type TProcessorFactory interface {
-  GetProcessor(trans TTransport) TProcessor
+	GetProcessor(trans TTransport) TProcessor
 }
 
 type tProcessorFactory struct {
-  processor TProcessor
+	processor TProcessor
 }
 
 func NewTProcessorFactory(p TProcessor) TProcessorFactory {
-  return &tProcessorFactory{processor: p}
+	return &tProcessorFactory{processor: p}
 }
 
 func (p *tProcessorFactory) GetProcessor(trans TTransport) TProcessor {
-  return p.processor
+	return p.processor
 }
 
-
 /**
  * The default processor factory just returns a singleton
  * instance.
  */
 type TProcessorFunctionFactory interface {
-  GetProcessorFunction(trans TTransport) TProcessorFunction
+	GetProcessorFunction(trans TTransport) TProcessorFunction
 }
 
 type tProcessorFunctionFactory struct {
-  processor TProcessorFunction
+	processor TProcessorFunction
 }
 
 func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactory {
-  return &tProcessorFunctionFactory{processor: p}
+	return &tProcessorFunctionFactory{processor: p}
 }
 
 func (p *tProcessorFunctionFactory) GetProcessorFunction(trans TTransport) TProcessorFunction {
-  return p.processor
+	return p.processor
 }
diff --git a/lib/go/thrift/protocol.go b/lib/go/thrift/protocol.go
new file mode 100644
index 0000000..87ceaad
--- /dev/null
+++ b/lib/go/thrift/protocol.go
@@ -0,0 +1,154 @@
+/*
+ * 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 TProtocol interface {
+	WriteMessageBegin(name string, typeId TMessageType, seqid int32) error
+	WriteMessageEnd() error
+	WriteStructBegin(name string) error
+	WriteStructEnd() error
+	WriteFieldBegin(name string, typeId TType, id int16) error
+	WriteFieldEnd() error
+	WriteFieldStop() error
+	WriteMapBegin(keyType TType, valueType TType, size int) error
+	WriteMapEnd() error
+	WriteListBegin(elemType TType, size int) error
+	WriteListEnd() error
+	WriteSetBegin(elemType TType, size int) error
+	WriteSetEnd() error
+	WriteBool(value bool) error
+	WriteByte(value byte) error
+	WriteI16(value int16) error
+	WriteI32(value int32) error
+	WriteI64(value int64) error
+	WriteDouble(value float64) error
+	WriteString(value string) error
+	WriteBinary(value []byte) error
+
+	ReadMessageBegin() (name string, typeId TMessageType, seqid int32, err error)
+	ReadMessageEnd() error
+	ReadStructBegin() (name string, err error)
+	ReadStructEnd() error
+	ReadFieldBegin() (name string, typeId TType, id int16, err error)
+	ReadFieldEnd() error
+	ReadMapBegin() (keyType TType, valueType TType, size int, err error)
+	ReadMapEnd() error
+	ReadListBegin() (elemType TType, size int, err error)
+	ReadListEnd() error
+	ReadSetBegin() (elemType TType, size int, err error)
+	ReadSetEnd() error
+	ReadBool() (value bool, err error)
+	ReadByte() (value byte, err error)
+	ReadI16() (value int16, err error)
+	ReadI32() (value int32, err error)
+	ReadI64() (value int64, err error)
+	ReadDouble() (value float64, err error)
+	ReadString() (value string, err error)
+	ReadBinary() (value []byte, err error)
+
+	Skip(fieldType TType) (err error)
+	Flush() (err error)
+
+	Transport() TTransport
+}
+
+// The maximum recursive depth the skip() function will traverse
+var MaxSkipDepth = 1<<31 - 1
+
+// Skips over the next data element from the provided input TProtocol object.
+func SkipDefaultDepth(prot TProtocol, typeId TType) (err error) {
+	return Skip(prot, typeId, MaxSkipDepth)
+}
+
+// Skips over the next data element from the provided input TProtocol object.
+func Skip(self TProtocol, fieldType TType, maxDepth int) (err error) {
+	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:
+		if _, err = self.ReadStructBegin(); err != nil {
+			return err
+		}
+		for {
+			_, typeId, _, _ := self.ReadFieldBegin()
+			if typeId == STOP {
+				break
+			}
+			Skip(self, typeId, maxDepth-1)
+			self.ReadFieldEnd()
+		}
+		return self.ReadStructEnd()
+	case MAP:
+		keyType, valueType, size, err := self.ReadMapBegin()
+		if err != nil {
+			return err
+		}
+		for i := 0; i < size; i++ {
+			Skip(self, keyType, maxDepth-1)
+			self.Skip(valueType)
+		}
+		return self.ReadMapEnd()
+	case SET:
+		elemType, size, err := self.ReadSetBegin()
+		if err != nil {
+			return err
+		}
+		for i := 0; i < size; i++ {
+			Skip(self, elemType, maxDepth-1)
+		}
+		return self.ReadSetEnd()
+	case LIST:
+		elemType, size, err := self.ReadListBegin()
+		if err != nil {
+			return err
+		}
+		for i := 0; i < size; i++ {
+			Skip(self, elemType, maxDepth-1)
+		}
+		return self.ReadListEnd()
+	}
+	return nil
+}
diff --git a/lib/go/thrift/protocol_exception.go b/lib/go/thrift/protocol_exception.go
new file mode 100644
index 0000000..f1a164a
--- /dev/null
+++ b/lib/go/thrift/protocol_exception.go
@@ -0,0 +1,77 @@
+/*
+ * 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"
+)
+
+// Thrift Protocol exception
+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 (p *tProtocolException) Error() string {
+	return p.message
+}
+
+func NewTProtocolException(err error) TProtocolException {
+	if err == nil {
+		return nil
+	}
+	if e,ok := err.(TProtocolException); ok {
+		return e
+	}
+	if _, ok := err.(base64.CorruptInputError); ok {
+		return &tProtocolException{INVALID_DATA, err.Error()}
+	}
+	return &tProtocolException{UNKNOWN_PROTOCOL_EXCEPTION, err.Error()}
+}
+
+func NewTProtocolExceptionWithType(errType int, err error) TProtocolException {
+	if err == nil {
+		return nil
+	}
+	return &tProtocolException{errType, err.Error()}
+}
+
diff --git a/lib/go/thrift/tprotocol_factory.go b/lib/go/thrift/protocol_factory.go
similarity index 88%
rename from lib/go/thrift/tprotocol_factory.go
rename to lib/go/thrift/protocol_factory.go
index 2eed2c2..c40f796 100644
--- a/lib/go/thrift/tprotocol_factory.go
+++ b/lib/go/thrift/protocol_factory.go
@@ -19,10 +19,7 @@
 
 package thrift
 
-/**
- * Factory interface for constructing protocol instances.
- *
- */
+// Factory interface for constructing protocol instances.
 type TProtocolFactory interface {
-  GetProtocol(trans TTransport) TProtocol
+	GetProtocol(trans TTransport) TProtocol
 }
diff --git a/lib/go/thrift/protocol_test.go b/lib/go/thrift/protocol_test.go
new file mode 100644
index 0000000..632098c
--- /dev/null
+++ b/lib/go/thrift/protocol_test.go
@@ -0,0 +1,458 @@
+/*
+ * 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/ioutil"
+	"math"
+	"net"
+	"net/http"
+	"testing"
+)
+
+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) {
+	buf, err := ioutil.ReadAll(req.Body)
+	if err != nil {
+		w.WriteHeader(http.StatusBadRequest)
+		w.Write(buf)
+	} else {
+		w.WriteHeader(http.StatusOK)
+		w.Write(buf)
+	}
+}
+
+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)
+		return nil, addr
+	}
+	l, err := net.Listen(addr.Network(), addr.String())
+	if err != nil {
+		t.Fatalf("Unable to setup tcp listener on %s: %s", addr.String(), err)
+		return l, addr
+	}
+	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)
+	defer l.Close()
+	transports := []TTransportFactory{
+		NewTMemoryBufferTransportFactory(1024),
+		NewStreamTransportFactory(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);
+	  ReadWriteI64(t, p, trans);
+	  ReadWriteDouble(t, p, trans);
+	  ReadWriteBinary(t, p, trans);
+	  ReadWriteByte(t, p, trans);
+	  trans.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.Error())
+	}
+	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)
+			}
+		}
+	}
+}
diff --git a/lib/go/thrift/tcontainer.go b/lib/go/thrift/server.go
similarity index 64%
copy from lib/go/thrift/tcontainer.go
copy to lib/go/thrift/server.go
index 9ea3cba..f813fa3 100644
--- a/lib/go/thrift/tcontainer.go
+++ b/lib/go/thrift/server.go
@@ -17,12 +17,19 @@
  * under the License.
  */
 
-
 package thrift
 
-type TContainer interface {
-  Len() int
-  Contains(data interface{}) bool
-  Equals(other interface{}) bool
-  CompareTo(other interface{}) (int, bool)
+type TServer interface {
+	ProcessorFactory() TProcessorFactory
+	ServerTransport() TServerTransport
+	InputTransportFactory() TTransportFactory
+	OutputTransportFactory() TTransportFactory
+	InputProtocolFactory() TProtocolFactory
+	OutputProtocolFactory() TProtocolFactory
+
+	// Starts the server
+	Serve() error
+	// Stops the server. This is optional on a per-implementation basis. Not
+	// all servers are required to be cleanly stoppable.
+	Stop() error
 }
diff --git a/lib/go/thrift/server_socket.go b/lib/go/thrift/server_socket.go
new file mode 100644
index 0000000..1a01095
--- /dev/null
+++ b/lib/go/thrift/server_socket.go
@@ -0,0 +1,107 @@
+/*
+ * 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"
+	"time"
+)
+
+type TServerSocket struct {
+	listener      net.Listener
+	addr          net.Addr
+	clientTimeout time.Duration
+	interrupted   bool
+}
+
+func NewTServerSocket(listenAddr string) (*TServerSocket, error) {
+	return NewTServerSocketTimeout(listenAddr, 0)
+}
+
+func NewTServerSocketTimeout(listenAddr string, clientTimeout time.Duration) (*TServerSocket, error) {
+	addr, err := net.ResolveTCPAddr("tcp", listenAddr)
+	if err != nil {
+		return nil, err
+	}
+	return &TServerSocket{addr: addr, clientTimeout: clientTimeout}, nil
+}
+
+func (p *TServerSocket) Listen() error {
+	if p.IsListening() {
+		return nil
+	}
+	l, err := net.Listen(p.addr.Network(), p.addr.String())
+	if err != nil {
+		return err
+	}
+	p.listener = l
+	return nil
+}
+
+func (p *TServerSocket) Accept() (TTransport, error) {
+	if p.interrupted {
+		return nil, errTransportInterrupted
+	}
+	if p.listener == nil {
+		return nil, NewTTransportException(NOT_OPEN, "No underlying server socket")
+	}
+	conn, err := p.listener.Accept()
+	if err != nil {
+		return nil, NewTTransportExceptionFromError(err)
+	}
+	return NewTSocketFromConnTimeout(conn, p.clientTimeout), nil
+}
+
+// Checks whether the socket is listening.
+func (p *TServerSocket) IsListening() bool {
+	return p.listener != nil
+}
+
+// Connects the socket, creating a new socket object if necessary.
+func (p *TServerSocket) Open() error {
+	if p.IsListening() {
+		return NewTTransportException(ALREADY_OPEN, "Server socket already open")
+	}
+	if l, err := net.Listen(p.addr.Network(), p.addr.String()); err != nil {
+		return err
+	} else {
+		p.listener = l
+	}
+	return nil
+}
+
+func (p *TServerSocket) Addr() net.Addr {
+	return p.addr
+}
+
+func (p *TServerSocket) Close() error {
+	defer func() {
+		p.listener = nil
+	}()
+	if p.IsListening() {
+		return p.listener.Close()
+	}
+	return nil
+}
+
+func (p *TServerSocket) Interrupt() error {
+	p.interrupted = true
+	return nil
+}
diff --git a/lib/go/thrift/tserver_test.go b/lib/go/thrift/server_test.go
similarity index 96%
rename from lib/go/thrift/tserver_test.go
rename to lib/go/thrift/server_test.go
index 3cbe879..ffaf457 100644
--- a/lib/go/thrift/tserver_test.go
+++ b/lib/go/thrift/server_test.go
@@ -17,10 +17,10 @@
  * under the License.
  */
 
-package thrift_test
+package thrift
 
 import (
-  "testing"
+	"testing"
 )
 
 func TestNothing(t *testing.T) {
diff --git a/lib/go/thrift/tcontainer.go b/lib/go/thrift/server_transport.go
similarity index 62%
copy from lib/go/thrift/tcontainer.go
copy to lib/go/thrift/server_transport.go
index 9ea3cba..51c40b6 100644
--- a/lib/go/thrift/tcontainer.go
+++ b/lib/go/thrift/server_transport.go
@@ -17,12 +17,18 @@
  * under the License.
  */
 
-
 package thrift
 
-type TContainer interface {
-  Len() int
-  Contains(data interface{}) bool
-  Equals(other interface{}) bool
-  CompareTo(other interface{}) (int, bool)
+// Server transport. Object which provides client transports.
+type TServerTransport interface {
+	Listen() error
+	Accept() (TTransport, error)
+	Close() 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() error
 }
diff --git a/lib/go/thrift/simple_json_protocol.go b/lib/go/thrift/simple_json_protocol.go
new file mode 100644
index 0000000..9d0f68f
--- /dev/null
+++ b/lib/go/thrift/simple_json_protocol.go
@@ -0,0 +1,1298 @@
+/*
+ * 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"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"io"
+	"math"
+	"strconv"
+)
+
+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 {
+	trans TTransport
+
+	parseContextStack []int
+	dumpContext []int
+
+	writer *bufio.Writer
+	reader *bufio.Reader
+}
+
+// Constructor
+func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol {
+	v := &TSimpleJSONProtocol{trans: t,
+		writer: bufio.NewWriter(t),
+		reader: bufio.NewReader(t),
+	}
+	v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL))
+	v.dumpContext = append(v.dumpContext, 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 mismatch(expected, actual string) error {
+	return fmt.Errorf("Expected '%s' but found '%s' while parsing JSON.", expected, actual)
+}
+
+func (p *TSimpleJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error {
+	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() error {
+	return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteStructBegin(name string) error {
+	if e := p.OutputObjectBegin(); e != nil {
+		return e
+	}
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteStructEnd() error {
+	return p.OutputObjectEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
+	if e := p.WriteString(name); e != nil {
+		return e
+	}
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldEnd() error {
+	//return p.OutputListEnd()
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) WriteFieldStop() error { return nil }
+
+func (p *TSimpleJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
+	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() error {
+	return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteListBegin(elemType TType, size int) error {
+	return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TSimpleJSONProtocol) WriteListEnd() error {
+	return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteSetBegin(elemType TType, size int) error {
+	return p.OutputElemListBegin(elemType, size)
+}
+
+func (p *TSimpleJSONProtocol) WriteSetEnd() error {
+	return p.OutputListEnd()
+}
+
+func (p *TSimpleJSONProtocol) WriteBool(b bool) error {
+	return p.OutputBool(b)
+}
+
+func (p *TSimpleJSONProtocol) WriteByte(b byte) error {
+	return p.WriteI32(int32(b))
+}
+
+func (p *TSimpleJSONProtocol) WriteI16(v int16) error {
+	return p.WriteI32(int32(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteI32(v int32) error {
+	return p.OutputI64(int64(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteI64(v int64) error {
+	return p.OutputI64(int64(v))
+}
+
+func (p *TSimpleJSONProtocol) WriteDouble(v float64) error {
+	return p.OutputF64(v)
+}
+
+func (p *TSimpleJSONProtocol) WriteString(v string) error {
+	return p.OutputString(v)
+}
+
+func (p *TSimpleJSONProtocol) WriteBinary(v []byte) error {
+	// 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 NewTProtocolException(e)
+	}
+	writer := base64.NewEncoder(base64.StdEncoding, p.writer)
+	if _, e := writer.Write(v); e != nil {
+		return NewTProtocolException(e)
+	}
+	if e := writer.Close(); e != nil {
+		return NewTProtocolException(e)
+	}
+	if _, e := p.writer.Write(JSON_QUOTE_BYTES); e != nil {
+		return NewTProtocolException(e)
+	}
+	return p.OutputPostValue()
+}
+
+// Reading methods.
+
+func (p *TSimpleJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
+	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() error {
+	return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadStructBegin() (name string, err error) {
+	_, err = p.ParseObjectStart()
+	return "", err
+}
+
+func (p *TSimpleJSONProtocol) ReadStructEnd() error {
+	return p.ParseObjectEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadFieldBegin() (string, TType, int16, error) {
+	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, STOP, -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
+			*/
+		}
+		e := fmt.Errorf("Expected \"}\" or '\"', but found: '%s'", string(b))
+		return "", STOP, 0, NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	return "", STOP, 0, NewTProtocolException(io.EOF)
+}
+
+func (p *TSimpleJSONProtocol) ReadFieldEnd() error {
+	return nil
+	//return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) {
+	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() error {
+	return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadListBegin() (elemType TType, size int, e error) {
+	return p.ParseElemListBegin()
+}
+
+func (p *TSimpleJSONProtocol) ReadListEnd() error {
+	return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) {
+	return p.ParseElemListBegin()
+}
+
+func (p *TSimpleJSONProtocol) ReadSetEnd() error {
+	return p.ParseListEnd()
+}
+
+func (p *TSimpleJSONProtocol) ReadBool() (bool, error) {
+	var value bool
+	if err := p.ParsePreValue(); err != nil {
+		return value, err
+	}
+	b, _ := p.reader.Peek(len(JSON_TRUE))
+	if len(b) > 0 {
+		switch b[0] {
+		case JSON_TRUE[0]:
+			if string(b) == string(JSON_TRUE) {
+				p.reader.Read(b[0:len(JSON_TRUE)])
+				value = true
+			} else {
+				e := fmt.Errorf("Expected \"true\" but found: %s", string(b))
+				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			break
+		case JSON_FALSE[0]:
+			if string(b) == string(JSON_FALSE[:len(b)]) {
+				p.reader.Read(b[0:len(JSON_FALSE)])
+				value = false
+			} else {
+				e := fmt.Errorf("Expected \"false\" but found: %s", string(b))
+				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			break
+		case JSON_NULL[0]:
+			if string(b) == string(JSON_NULL) {
+				p.reader.Read(b[0:len(JSON_NULL)])
+				value = false
+			} else {
+				e := fmt.Errorf("Expected \"null\" but found: %s", string(b))
+				return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+		default:
+			e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(b))
+			return value, NewTProtocolExceptionWithType(INVALID_DATA, e)
+		}
+	}
+	return value, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ReadByte() (byte, error) {
+	v, err := p.ReadI64()
+	return byte(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI16() (int16, error) {
+	v, err := p.ReadI64()
+	return int16(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI32() (int32, error) {
+	v, err := p.ReadI64()
+	return int32(v), err
+}
+
+func (p *TSimpleJSONProtocol) ReadI64() (int64, error) {
+	v, _, err := p.ParseI64()
+	return v, err
+}
+
+func (p *TSimpleJSONProtocol) ReadDouble() (float64, error) {
+	v, _, err := p.ParseF64()
+	return v, err
+}
+
+func (p *TSimpleJSONProtocol) ReadString() (string, error) {
+	var v string
+	if err := p.ParsePreValue(); err != nil {
+		return v, err
+	}
+	var b []byte
+	if p.reader.Buffered() >= len(JSON_NULL) {
+		b, _ = p.reader.Peek(len(JSON_NULL))
+	} else {
+		b, _ = p.reader.Peek(1)
+	}
+	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, NewTProtocolException(err)
+		}
+	} else {
+		e := fmt.Errorf("Expected a JSON string, found %s", string(b))
+		return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	return v, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, error) {
+	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, NewTProtocolException(err)
+		}
+	} else {
+		e := fmt.Errorf("Expected a JSON string, found %s", string(b))
+		return v, NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	return v, p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) Flush() (err error) {
+	return NewTProtocolException(p.writer.Flush())
+}
+
+func (p *TSimpleJSONProtocol) Skip(fieldType TType) (err error) {
+	return SkipDefaultDepth(p, fieldType)
+}
+
+func (p *TSimpleJSONProtocol) Transport() TTransport {
+	return p.trans
+}
+
+func (p *TSimpleJSONProtocol) OutputPreValue() error {
+	cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1])
+	switch cxt {
+	case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+		if _, e := p.writer.Write(JSON_COMMA); e != nil {
+			return NewTProtocolException(e)
+		}
+		break
+	case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+		if _, e := p.writer.Write(JSON_COLON); e != nil {
+			return NewTProtocolException(e)
+		}
+		break
+	}
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputPostValue() error {
+	cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1])
+	switch cxt {
+	case _CONTEXT_IN_LIST_FIRST:
+		p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
+		p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST))
+		break
+	case _CONTEXT_IN_OBJECT_FIRST:
+		p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
+		p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+		break
+	case _CONTEXT_IN_OBJECT_NEXT_KEY:
+		p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
+		p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+		break
+	case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+		p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
+		p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_KEY))
+		break
+	}
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputBool(value bool) error {
+	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[len(p.dumpContext)-1]) {
+	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() error {
+	if e := p.OutputPreValue(); e != nil {
+		return e
+	}
+	if _, e := p.writer.Write(JSON_NULL); e != nil {
+		return NewTProtocolException(e)
+	}
+	return p.OutputPostValue()
+}
+
+func (p *TSimpleJSONProtocol) OutputF64(value float64) error {
+	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.FormatFloat(value, 'g', -1, 64)
+		switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) {
+		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) error {
+	if e := p.OutputPreValue(); e != nil {
+		return e
+	}
+	v := strconv.FormatInt(value, 10)
+	switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) {
+	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) error {
+	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) error {
+	_, e := p.writer.Write([]byte(s))
+	return NewTProtocolException(e)
+}
+
+func (p *TSimpleJSONProtocol) OutputObjectBegin() error {
+	if e := p.OutputPreValue(); e != nil {
+		return e
+	}
+	if _, e := p.writer.Write(JSON_LBRACE); e != nil {
+		return NewTProtocolException(e)
+	}
+	p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_FIRST))
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputObjectEnd() error {
+	if _, e := p.writer.Write(JSON_RBRACE); e != nil {
+		return NewTProtocolException(e)
+	}
+	p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
+	if e := p.OutputPostValue(); e != nil {
+		return e
+	}
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputListBegin() error {
+	if e := p.OutputPreValue(); e != nil {
+		return e
+	}
+	if _, e := p.writer.Write(JSON_LBRACKET); e != nil {
+		return NewTProtocolException(e)
+	}
+	p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST_FIRST))
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputListEnd() error {
+	if _, e := p.writer.Write(JSON_RBRACKET); e != nil {
+		return NewTProtocolException(e)
+	}
+	p.dumpContext = p.dumpContext[:len(p.dumpContext)-1]
+	if e := p.OutputPostValue(); e != nil {
+		return e
+	}
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) error {
+	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() error {
+	if e := p.readNonSignificantWhitespace(); e != nil {
+		return NewTProtocolException(e)
+	}
+	cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
+	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 NewTProtocolException(e)
+				}
+				return nil
+			default:
+				e := fmt.Errorf("Expected \"]\" or \",\" in list context, but found \"%s\"", string(b))
+				return NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+		}
+		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 NewTProtocolException(e)
+				}
+				return nil
+			default:
+				e := fmt.Errorf("Expected \"}\" or \",\" in object context, but found \"%s\"", string(b))
+				return NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+		}
+		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 NewTProtocolException(e)
+				}
+				return nil
+			default:
+				e := fmt.Errorf("Expected \":\" in object context, but found \"%s\"", string(b))
+				return NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+		}
+		break
+	}
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) ParsePostValue() error {
+	if e := p.readNonSignificantWhitespace(); e != nil {
+		return NewTProtocolException(e)
+	}
+	cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
+	switch cxt {
+	case _CONTEXT_IN_LIST_FIRST:
+		p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
+		p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST))
+		break
+	case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY:
+		p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
+		p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_VALUE))
+		break
+	case _CONTEXT_IN_OBJECT_NEXT_VALUE:
+		p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
+		p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_KEY))
+		break
+	}
+	return nil
+}
+
+func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() 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, error) {
+	line, err := p.reader.ReadString(JSON_QUOTE)
+	if err != nil {
+		return "", NewTProtocolException(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 "", NewTProtocolException(err)
+		}
+		return v, nil
+	}
+	s, err := p.ParseQuotedStringBody()
+	if err != nil {
+		return "", NewTProtocolException(err)
+	}
+	str := string(JSON_QUOTE) + line + s
+	v, ok := jsonUnquote(str)
+	if !ok {
+		e := fmt.Errorf("Unable to parse as JSON string %s", str)
+		return "", NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	return v, nil
+}
+
+func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) {
+	line, err := p.reader.ReadString(JSON_QUOTE)
+	if err != nil {
+		return "", NewTProtocolException(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 "", NewTProtocolException(err)
+	}
+	v := line + s
+	return v, nil
+}
+
+func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) {
+	line, err := p.reader.ReadBytes(JSON_QUOTE)
+	if err != nil {
+		return line, NewTProtocolException(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], NewTProtocolException(err)
+}
+
+func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, error) {
+	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, error) {
+	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, error) {
+	if err := p.ParsePreValue(); err != nil {
+		return false, err
+	}
+	var b []byte
+	if p.reader.Buffered() >= len(JSON_NULL) {
+		b, _ = p.reader.Peek(len(JSON_NULL))
+	} else if p.reader.Buffered() >= 1 {
+		b, _ = p.reader.Peek(1)
+	}
+	if len(b) > 0 && b[0] == JSON_LBRACE[0] {
+		p.reader.ReadByte()
+		p.parseContextStack = append(p.parseContextStack, 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
+	}
+	e := fmt.Errorf("Expected '{' or null, but found '%s'", string(b))
+	return false, NewTProtocolExceptionWithType(INVALID_DATA, e)
+}
+
+func (p *TSimpleJSONProtocol) ParseObjectEnd() error {
+	if isNull, err := p.readIfNull(); isNull || err != nil {
+		return err
+	}
+	cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1])
+	if cxt != _CONTEXT_IN_OBJECT_FIRST && cxt != _CONTEXT_IN_OBJECT_NEXT_KEY {
+		e := fmt.Errorf("Expected to be in the Object Context, but not in Object Context")
+		return NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	line, err := p.reader.ReadString(JSON_RBRACE[0])
+	if err != nil {
+		return NewTProtocolException(err)
+	}
+	for _, char := range line {
+		switch char {
+		default:
+			e := fmt.Errorf("Expecting end of object \"}\", but found: \"%s\"", line)
+			return NewTProtocolExceptionWithType(INVALID_DATA, e)
+		case ' ', '\n', '\r', '\t', '}':
+			break
+		}
+	}
+	p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
+	return p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) ParseListBegin() (isNull bool, err error) {
+	if e := p.ParsePreValue(); e != nil {
+		return false, e
+	}
+	var b []byte
+	if p.reader.Buffered() >= len(JSON_NULL) {
+		b, err = p.reader.Peek(len(JSON_NULL))
+	} else {
+		b, err = p.reader.Peek(1)
+	}
+	if err != nil {
+		return false, err
+	}
+	if len(b) >= 1 && b[0] == JSON_LBRACKET[0] {
+		p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST_FIRST))
+		p.reader.ReadByte()
+		isNull = false
+	} else if len(b) >= len(JSON_NULL) && string(b) == string(JSON_NULL) {
+		isNull = true
+	} else {
+		err = fmt.Errorf("Expected \"null\" or \"[\", received %q", b)
+	}
+	return isNull, NewTProtocolExceptionWithType(INVALID_DATA, err)
+}
+
+func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) {
+	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() error {
+	if isNull, err := p.readIfNull(); isNull || err != nil {
+		return err
+	}
+	if _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) != _CONTEXT_IN_LIST {
+		e := fmt.Errorf("Expected to be in the List Context, but not in List Context")
+		return NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	line, err := p.reader.ReadString(JSON_RBRACKET[0])
+	if err != nil {
+		return NewTProtocolException(err)
+	}
+	for _, char := range line {
+		switch char {
+		default:
+			e := fmt.Errorf("Expecting end of list \"]\", but found: \"", line, "\"")
+			return NewTProtocolExceptionWithType(INVALID_DATA, e)
+		case ' ', '\n', '\r', '\t', rune(JSON_RBRACKET[0]):
+			break
+		}
+	}
+	p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1]
+	return p.ParsePostValue()
+}
+
+func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, error) {
+	e := p.readNonSignificantWhitespace()
+	if e != nil {
+		return nil, VOID, NewTProtocolException(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, NewTProtocolException(e)
+			}
+			if string(JSON_NULL) != string(buf) {
+				e = mismatch(string(JSON_NULL), string(buf))
+				return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			return nil, VOID, nil
+		case JSON_QUOTE:
+			p.reader.ReadByte()
+			v, e := p.ParseStringBody()
+			if e != nil {
+				return v, UTF8, NewTProtocolException(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, NewTProtocolException(e)
+			}
+			if string(JSON_TRUE) != string(buf) {
+				e := mismatch(string(JSON_TRUE), string(buf))
+				return true, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, 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, NewTProtocolException(e)
+			}
+			if string(JSON_FALSE) != string(buf) {
+				e := mismatch(string(JSON_FALSE), string(buf))
+				return false, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			return false, BOOL, nil
+		case JSON_LBRACKET[0]:
+			_, e := p.reader.ReadByte()
+			return make([]interface{}, 0), LIST, NewTProtocolException(e)
+		case JSON_LBRACE[0]:
+			_, e := p.reader.ReadByte()
+			return make(map[string]interface{}), STRUCT, NewTProtocolException(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:
+			e := fmt.Errorf("Expected element in list but found '%s' while parsing JSON.", string(c))
+			return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
+		}
+	}
+	e = fmt.Errorf("Cannot read a single element while parsing JSON.")
+	return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e)
+
+}
+
+func (p *TSimpleJSONProtocol) readIfNull() (bool, error) {
+	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, error) {
+	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 == io.EOF {
+				break
+			}
+			return NUMERIC_NULL, NewTProtocolException(err)
+		}
+		switch c {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			buf.WriteByte(c)
+			nextCanBeSign = false
+		case '.':
+			if hasDecimalPoint {
+				e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String())
+				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			if hasE {
+				e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String())
+				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			buf.WriteByte(c)
+			hasDecimalPoint, nextCanBeSign = true, false
+		case 'e', 'E':
+			if hasE {
+				e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c)
+				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			buf.WriteByte(c)
+			hasE, nextCanBeSign = true, true
+		case '-', '+':
+			if !nextCanBeSign {
+				e := fmt.Errorf("Negative sign within number")
+				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+			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, NewTProtocolException(e)
+				}
+				if JSON_NAN != string(buffer) {
+					e := mismatch(JSON_NAN, string(buffer))
+					return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+				}
+				if inQuotes {
+					p.readQuoteIfNext()
+				}
+				return NAN, nil
+			} else {
+				e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
+				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+		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, NewTProtocolException(e)
+				}
+				if JSON_INFINITY != string(buffer) {
+					e := mismatch(JSON_INFINITY, string(buffer))
+					return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, 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, NewTProtocolException(e)
+				}
+				if JSON_NEGATIVE_INFINITY != string(buffer) {
+					e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer))
+					return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+				}
+				if inQuotes {
+					p.readQuoteIfNext()
+				}
+				return NEGATIVE_INFINITY, nil
+			} else {
+				e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String())
+				return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+			}
+		case JSON_QUOTE:
+			if !inQuotes {
+				inQuotes = true
+			} else {
+				break
+			}
+		default:
+			e := fmt.Errorf("Unable to parse number starting with character '%c'", c)
+			return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+		}
+	}
+	if buf.Len() == 0 {
+		e := fmt.Errorf("Unable to parse number from empty string ''")
+		return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e)
+	}
+	return NewNumericFromJSONString(buf.String(), false), nil
+}
diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go
new file mode 100644
index 0000000..87a5c64
--- /dev/null
+++ b/lib/go/thrift/simple_json_protocol_test.go
@@ -0,0 +1,632 @@
+/*
+ * 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"
+	"encoding/json"
+	"fmt"
+	"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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.FormatInt(value, 10))
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+		}
+		if e := p.Flush(); e != nil {
+			t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+		}
+		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.Error())
+		}
+		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.Error())
+	}
+	if e := p.Flush(); e != nil {
+		t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
+	}
+	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.Error())
+	}
+	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.Error())
+		}
+	}
+	p.WriteListEnd()
+	if e := p.Flush(); e != nil {
+		t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+	}
+	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.Error())
+		}
+	}
+	p.WriteSetEnd()
+	if e := p.Flush(); e != nil {
+		t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+	}
+	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.Error())
+		}
+		if e := p.WriteDouble(value); e != nil {
+			t.Fatalf("Unable to write %s value float64 value %v due to error: %s", thetype, value, e.Error())
+		}
+	}
+	p.WriteMapEnd()
+	if e := p.Flush(); e != nil {
+		t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
+	}
+	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], ",")
+	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.Error())
+		}
+		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.FormatFloat(value, 'g', 10, 64)
+			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()
+}
diff --git a/lib/go/thrift/simple_server.go b/lib/go/thrift/simple_server.go
new file mode 100644
index 0000000..17be8d8
--- /dev/null
+++ b/lib/go/thrift/simple_server.go
@@ -0,0 +1,164 @@
+/*
+ * 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 (
+	"log"
+)
+
+// Simple, non-concurrent 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() 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 {
+			if err := p.processRequest(client); err != nil {
+				log.Println("error processing request:", err)
+			}
+		}
+	}
+	return nil
+}
+
+func (p *TSimpleServer) Stop() error {
+	p.stopped = true
+	p.serverTransport.Interrupt()
+	return nil
+}
+
+func (p *TSimpleServer) processRequest(client TTransport) error {
+	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, err := processor.Process(inputProtocol, outputProtocol)
+		if err, ok := err.(TTransportException); ok && err.TypeId() == END_OF_FILE{
+			return nil
+		} else if err != nil {
+			return err
+		}
+		if !ok || !inputProtocol.Transport().Peek() {
+			break
+		}
+	}
+	return nil
+}
diff --git a/lib/go/thrift/socket.go b/lib/go/thrift/socket.go
new file mode 100644
index 0000000..a381ea2
--- /dev/null
+++ b/lib/go/thrift/socket.go
@@ -0,0 +1,159 @@
+/*
+ * 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"
+	"time"
+)
+
+type TSocket struct {
+	conn    net.Conn
+	addr    net.Addr
+	timeout time.Duration
+}
+
+// NewTSocket creates a net.Conn-backed TTransport, given a host and port
+//
+// Example:
+// 	trans, err := thrift.NewTSocket("localhost:9090")
+func NewTSocket(hostPort string) (*TSocket, error) {
+	return NewTSocketTimeout(hostPort, 0)
+}
+
+// NewTSocketTimeout creates a net.Conn-backed TTransport, given a host and port
+// it also accepts a timeout as a time.Duration
+func NewTSocketTimeout(hostPort string, timeout time.Duration) (*TSocket, error) {
+	//conn, err := net.DialTimeout(network, address, timeout)
+	addr, err := net.ResolveTCPAddr("tcp", hostPort)
+	if err != nil {
+		return nil, err
+	}
+	return NewTSocketFromAddrTimeout(addr, timeout), nil
+}
+
+// Creates a TSocket from a net.Addr
+func NewTSocketFromAddrTimeout(addr net.Addr, timeout time.Duration) *TSocket {
+	return &TSocket{addr: addr, timeout: timeout}
+}
+
+// Creates a TSocket from an existing net.Conn
+func NewTSocketFromConnTimeout(conn net.Conn, timeout time.Duration) *TSocket {
+	return &TSocket{conn: conn, addr: conn.RemoteAddr(), timeout: timeout}
+}
+
+// Sets the socket timeout
+func (p *TSocket) SetTimeout(timeout time.Duration) error {
+	p.timeout = timeout
+	return nil
+}
+
+func (p *TSocket) pushDeadline(read, write bool) {
+	var t time.Time
+	if p.timeout > 0 {
+		t = time.Now().Add(time.Duration(p.timeout))
+	}
+	if read && write {
+		p.conn.SetDeadline(t)
+	} else if read {
+		p.conn.SetReadDeadline(t)
+	} else if write {
+		p.conn.SetWriteDeadline(t)
+	}
+}
+
+// Connects the socket, creating a new socket object if necessary.
+func (p *TSocket) Open() 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 error
+	if p.conn, err = net.DialTimeout(p.addr.Network(), p.addr.String(), p.timeout); err != nil {
+		return NewTTransportException(NOT_OPEN, err.Error())
+	}
+	return nil
+}
+
+// Retreive the underlying net.Conn
+func (p *TSocket) Conn() net.Conn {
+	return p.conn
+}
+
+// Returns true if the connection is open
+func (p *TSocket) IsOpen() bool {
+	if p.conn == nil {
+		return false
+	}
+	return true
+}
+
+// Closes the socket.
+func (p *TSocket) Close() error {
+	// Close the socket
+	if p.conn != nil {
+		err := p.conn.Close()
+		if err != nil {
+			return err
+		}
+		p.conn = nil
+	}
+	return nil
+}
+
+func (p *TSocket) Read(buf []byte) (int, error) {
+	if !p.IsOpen() {
+		return 0, NewTTransportException(NOT_OPEN, "Connection not open")
+	}
+	p.pushDeadline(true, false)
+	n, err := p.conn.Read(buf)
+	return n, NewTTransportExceptionFromError(err)
+}
+
+func (p *TSocket) Write(buf []byte) (int, error) {
+	if !p.IsOpen() {
+		return 0, NewTTransportException(NOT_OPEN, "Connection not open")
+	}
+	p.pushDeadline(false, true)
+	return p.conn.Write(buf)
+}
+
+func (p *TSocket) Peek() bool {
+	return p.IsOpen()
+}
+
+func (p *TSocket) Flush() error {
+	return nil
+}
+
+func (p *TSocket) Interrupt() error {
+	if !p.IsOpen() {
+		return nil
+	}
+	return p.conn.Close()
+}
diff --git a/lib/go/thrift/tapplication_exception.go b/lib/go/thrift/tapplication_exception.go
deleted file mode 100644
index 6b7a75d..0000000
--- a/lib/go/thrift/tapplication_exception.go
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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
-  INVALID_TRANSFORM              = 8
-  INVALID_PROTOCOL               = 9
-  UNSUPPORTED_CLIENT_TYPE        = 10
-)
-
-
-/**
- * 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
deleted file mode 100644
index d9572f4..0000000
--- a/lib/go/thrift/tapplication_exception_test.go
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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
deleted file mode 100644
index adc52d0..0000000
--- a/lib/go/thrift/tbase.go
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 1c88da6..0000000
--- a/lib/go/thrift/tbinary_protocol.go
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * 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/tcompact_protocol.go b/lib/go/thrift/tcompact_protocol.go
deleted file mode 100644
index 9b780f7..0000000
--- a/lib/go/thrift/tcompact_protocol.go
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * 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
deleted file mode 100644
index da0e39c..0000000
--- a/lib/go/thrift/tcompact_protocol_test.go
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 01fef44..0000000
--- a/lib/go/thrift/tcompare.go
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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/texception.go b/lib/go/thrift/texception.go
deleted file mode 100644
index be6cbd5..0000000
--- a/lib/go/thrift/texception.go
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 50b3cdd..0000000
--- a/lib/go/thrift/texception_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 31d9b89..0000000
--- a/lib/go/thrift/tfield.go
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 52049cb..0000000
--- a/lib/go/thrift/tframed_transport.go
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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/thttp_client.go b/lib/go/thrift/thttp_client.go
deleted file mode 100644
index 2ec4b28..0000000
--- a/lib/go/thrift/thttp_client.go
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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"
-  "strconv"
-  "url"
-)
-
-
-type THttpClient struct {
-  response           *http.Response
-  url                *url.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(urlstr string) (TTransport, os.Error) {
-  parsedURL, err := url.Parse(urlstr)
-  if err != nil {
-    return nil, err
-  }
-  response, err := http.Get(urlstr)
-  if err != nil {
-    return nil, err
-  }
-  return &THttpClient{response: response, url: parsedURL}, nil
-}
-
-func NewTHttpPostClient(urlstr string) (TTransport, os.Error) {
-  parsedURL, err := url.Parse(urlstr)
-  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: "+ strconv.Itoa(response.StatusCode))
-  }
-  p.response = response
-  return nil
-}
diff --git a/lib/go/thrift/tiostream_transport.go b/lib/go/thrift/tiostream_transport.go
deleted file mode 100644
index 5c4beea..0000000
--- a/lib/go/thrift/tiostream_transport.go
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a7425c7..0000000
--- a/lib/go/thrift/tiostream_transport_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 45ab700..0000000
--- a/lib/go/thrift/tjson_protocol.go
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 60f0f2e..0000000
--- a/lib/go/thrift/tjson_protocol_test.go
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 778fc3b..0000000
--- a/lib/go/thrift/tlist.go
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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
deleted file mode 100644
index d042f05..0000000
--- a/lib/go/thrift/tmap.go
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 69b794e..0000000
--- a/lib/go/thrift/tmemory_buffer.go
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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/tmessage.go b/lib/go/thrift/tmessage.go
deleted file mode 100644
index c768cb4..0000000
--- a/lib/go/thrift/tmessage.go
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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/tnonblocking_server.go b/lib/go/thrift/tnonblocking_server.go
deleted file mode 100644
index e234c5a..0000000
--- a/lib/go/thrift/tnonblocking_server.go
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3c9dbaa..0000000
--- a/lib/go/thrift/tnonblocking_server_socket.go
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 9b175b8..0000000
--- a/lib/go/thrift/tnonblocking_socket.go
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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_test.go b/lib/go/thrift/tnonblocking_transport_test.go
deleted file mode 100644
index 7d019db..0000000
--- a/lib/go/thrift/tnonblocking_transport_test.go
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b1f6508..0000000
--- a/lib/go/thrift/tnumeric.go
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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/tprotocol.go b/lib/go/thrift/tprotocol.go
deleted file mode 100644
index dcb27a8..0000000
--- a/lib/go/thrift/tprotocol.go
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2dac97e..0000000
--- a/lib/go/thrift/tprotocol_exception.go
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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_test.go b/lib/go/thrift/tprotocol_test.go
deleted file mode 100644
index 71ef8e9..0000000
--- a/lib/go/thrift/tprotocol_test.go
+++ /dev/null
@@ -1,1825 +0,0 @@
-/*
- * 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/ioutil"
-  "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) {
-  buf, err := ioutil.ReadAll(req.Body)
-  if err != nil {
-    w.WriteHeader(http.StatusBadRequest)
-    w.Write(buf)
-  } else {
-    w.WriteHeader(http.StatusOK)
-    w.Write(buf)
-  }
-}
-
-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)
-    return nil, addr
-  }
-  l, err := net.Listen(addr.Network(), addr.String())
-  if err != nil {
-    t.Fatalf("Unable to setup tcp listener on %s: %s", addr.String(), err)
-    return l, addr
-  }
-  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)
-  defer l.Close()
-  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()
-  //}
-
-}
-
-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/tcontainer.go b/lib/go/thrift/transport.go
similarity index 65%
copy from lib/go/thrift/tcontainer.go
copy to lib/go/thrift/transport.go
index 9ea3cba..44823dd 100644
--- a/lib/go/thrift/tcontainer.go
+++ b/lib/go/thrift/transport.go
@@ -17,12 +17,30 @@
  * under the License.
  */
 
-
 package thrift
 
-type TContainer interface {
-  Len() int
-  Contains(data interface{}) bool
-  Equals(other interface{}) bool
-  CompareTo(other interface{}) (int, bool)
+import (
+	"errors"
+	"io"
+)
+
+var errTransportInterrupted = errors.New("Transport Interrupted")
+
+type Flusher interface {
+	Flush() (err error)
+}
+
+// Encapsulates the I/O layer
+type TTransport interface {
+	io.ReadWriteCloser
+	Flusher
+
+	// Opens the transport for communication
+	Open() error
+
+	// Returns true if the transport is open
+	IsOpen() bool
+
+	// Returns true if there is more data to be read or the remote side is still open
+	Peek() bool
 }
diff --git a/lib/go/thrift/transport_exception.go b/lib/go/thrift/transport_exception.go
new file mode 100644
index 0000000..dbab4d9
--- /dev/null
+++ b/lib/go/thrift/transport_exception.go
@@ -0,0 +1,68 @@
+/*
+ * 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 (
+	"io"
+)
+
+// Thrift Transport exception
+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) Error() string {
+	return p.message
+}
+
+func NewTTransportException(t int, m string) TTransportException {
+	return &tTransportException{typeId: t, message: m}
+}
+
+func NewTTransportExceptionFromError(e error) TTransportException {
+	if e == nil {
+		return nil
+	}
+	if t, ok := e.(TTransportException); ok {
+		return t
+	}
+	if e == io.EOF {
+		return NewTTransportException(END_OF_FILE, e.Error())
+	}
+	return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, e.Error())
+}
diff --git a/lib/go/thrift/ttransport_factory.go b/lib/go/thrift/transport_factory.go
similarity index 68%
rename from lib/go/thrift/ttransport_factory.go
rename to lib/go/thrift/transport_factory.go
index 4ab4dbe..533d1b4 100644
--- a/lib/go/thrift/ttransport_factory.go
+++ b/lib/go/thrift/transport_factory.go
@@ -19,29 +19,21 @@
 
 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)
- *
- */
+// 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
+	GetTransport(trans TTransport) TTransport
 }
 
 type tTransportFactory struct{}
 
-/**
- * Return a wrapped instance of the base Transport.
- *
- * @param trans The base transport
- * @return Wrapped Transport
- */
+// Return a wrapped instance of the base Transport.
 func (p *tTransportFactory) GetTransport(trans TTransport) TTransport {
-  return trans
+	return trans
 }
 
 func NewTTransportFactory() TTransportFactory {
-  return &tTransportFactory{}
+	return &tTransportFactory{}
 }
diff --git a/lib/go/thrift/transport_test.go b/lib/go/thrift/transport_test.go
new file mode 100644
index 0000000..c9f1d56
--- /dev/null
+++ b/lib/go/thrift/transport_test.go
@@ -0,0 +1,120 @@
+/*
+ * 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 (
+	"io"
+	"net"
+	"strconv"
+	"testing"
+)
+
+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() {
+		t.Fatalf("Transport %T not open: %s", writeTrans, writeTrans)
+	}
+	if !readTrans.IsOpen() {
+		t.Fatalf("Transport %T not open: %s", readTrans, readTrans)
+	}
+	_, 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 := io.ReadFull(readTrans, 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)
+	}
+	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, 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("tcp", s)
+		}
+	}
+	return nil, NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, "Could not find available server port")
+}
diff --git a/lib/go/thrift/tserver.go b/lib/go/thrift/tserver.go
deleted file mode 100644
index 6bc3167..0000000
--- a/lib/go/thrift/tserver.go
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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
deleted file mode 100644
index dc3e748..0000000
--- a/lib/go/thrift/tserver_socket.go
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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_transport.go b/lib/go/thrift/tserver_transport.go
deleted file mode 100644
index ef3a462..0000000
--- a/lib/go/thrift/tserver_transport.go
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f868109..0000000
--- a/lib/go/thrift/tset.go
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 569dd9c..0000000
--- a/lib/go/thrift/tsimple_json_protocol.go
+++ /dev/null
@@ -1,1281 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f6f5f48..0000000
--- a/lib/go/thrift/tsimple_json_protocol_test.go
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * 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], ",")
-  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
deleted file mode 100644
index 6c7d656..0000000
--- a/lib/go/thrift/tsimple_server.go
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 3fc6253..0000000
--- a/lib/go/thrift/tsocket.go
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 5eaffae..0000000
--- a/lib/go/thrift/tstruct.go
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f29b0b4..0000000
--- a/lib/go/thrift/ttransport.go
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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"
-  "strconv"
-)
-
-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 " + strconv.Itoa(size) + " bytes, but only got " + strconv.Itoa(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
deleted file mode 100644
index b9fae17..0000000
--- a/lib/go/thrift/ttransport_exception.go
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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_test.go b/lib/go/thrift/ttransport_test.go
deleted file mode 100644
index 4158a74..0000000
--- a/lib/go/thrift/ttransport_test.go
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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("tcp", 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
deleted file mode 100644
index d024b39..0000000
--- a/lib/go/thrift/ttype.go
+++ /dev/null
@@ -1,975 +0,0 @@
-/*
- * 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
-}
diff --git a/lib/go/thrift/type.go b/lib/go/thrift/type.go
new file mode 100644
index 0000000..7c68c2b
--- /dev/null
+++ b/lib/go/thrift/type.go
@@ -0,0 +1,68 @@
+/*
+ * 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 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
+	UTF8   = 16
+	UTF16  = 17
+	BINARY = 18
+)
+
+var typeNames = map[int]string{
+	STOP:   "STOP",
+	VOID:   "VOID",
+	BOOL:   "BOOL",
+	BYTE:   "BYTE",
+	I16:    "I16",
+	I32:    "I32",
+	I64:    "I64",
+	STRING: "STRING",
+	STRUCT: "STRUCT",
+	MAP:    "MAP",
+	SET:    "SET",
+	LIST:   "LIST",
+	UTF8:   "UTF8",
+	UTF16:  "UTF16",
+}
+
+func (p TType) String() string {
+	if s, ok := typeNames[int(p)]; ok {
+		return s
+	}
+	return "Unknown"
+}
