diff --git a/lib/Makefile.am b/lib/Makefile.am
index d26752b..1cc5c6c 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -62,6 +62,10 @@
 SUBDIRS += php
 endif
 
+if WITH_GO
+SUBDIRS += go
+endif
+
 if WITH_D
 SUBDIRS += d
 endif
@@ -73,7 +77,6 @@
 			cocoa \
 			d \
 			delphi \
-			go \
 			javame \
 			js \
 			nodejs \
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"
+}
