diff --git a/test/go/src/bin/stress/go17.go b/test/go/src/bin/stress/go17.go
deleted file mode 100644
index 81f1ad8..0000000
--- a/test/go/src/bin/stress/go17.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// +build go1.7
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package main
-
-import (
-	"context"
-	"sync/atomic"
-)
-
-type handler struct{}
-
-func (h *handler) EchoVoid(ctx context.Context) (err error) {
-	atomic.AddInt64(&counter, 1)
-	return nil
-}
-func (h *handler) EchoByte(ctx context.Context, arg int8) (r int8, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoI32(ctx context.Context, arg int32) (r int32, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoI64(ctx context.Context, arg int64) (r int64, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoString(ctx context.Context, arg string) (r string, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoList(ctx context.Context, arg []int8) (r []int8, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoSet(ctx context.Context, arg map[int8]struct{}) (r map[int8]struct{}, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoMap(ctx context.Context, arg map[int8]int8) (r map[int8]int8, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
diff --git a/test/go/src/bin/stress/main.go b/test/go/src/bin/stress/main.go
index e8e6b2a..f2e0f20 100644
--- a/test/go/src/bin/stress/main.go
+++ b/test/go/src/bin/stress/main.go
@@ -20,6 +20,7 @@
 package main
 
 import (
+	"context"
 	"flag"
 	"fmt"
 	"gen/stress"
@@ -216,3 +217,38 @@
 
 	done.Done()
 }
+
+type handler struct{}
+
+func (h *handler) EchoVoid(ctx context.Context) (err error) {
+	atomic.AddInt64(&counter, 1)
+	return nil
+}
+func (h *handler) EchoByte(ctx context.Context, arg int8) (r int8, err error) {
+	atomic.AddInt64(&counter, 1)
+	return arg, nil
+}
+func (h *handler) EchoI32(ctx context.Context, arg int32) (r int32, err error) {
+	atomic.AddInt64(&counter, 1)
+	return arg, nil
+}
+func (h *handler) EchoI64(ctx context.Context, arg int64) (r int64, err error) {
+	atomic.AddInt64(&counter, 1)
+	return arg, nil
+}
+func (h *handler) EchoString(ctx context.Context, arg string) (r string, err error) {
+	atomic.AddInt64(&counter, 1)
+	return arg, nil
+}
+func (h *handler) EchoList(ctx context.Context, arg []int8) (r []int8, err error) {
+	atomic.AddInt64(&counter, 1)
+	return arg, nil
+}
+func (h *handler) EchoSet(ctx context.Context, arg map[int8]struct{}) (r map[int8]struct{}, err error) {
+	atomic.AddInt64(&counter, 1)
+	return arg, nil
+}
+func (h *handler) EchoMap(ctx context.Context, arg map[int8]int8) (r map[int8]int8, err error) {
+	atomic.AddInt64(&counter, 1)
+	return arg, nil
+}
diff --git a/test/go/src/bin/stress/pre_go17.go b/test/go/src/bin/stress/pre_go17.go
deleted file mode 100644
index 07ae5c6..0000000
--- a/test/go/src/bin/stress/pre_go17.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// +build !go1.7
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package main
-
-import (
-	"sync/atomic"
-
-	"golang.org/x/net/context"
-)
-
-type handler struct{}
-
-func (h *handler) EchoVoid(ctx context.Context) (err error) {
-	atomic.AddInt64(&counter, 1)
-	return nil
-}
-func (h *handler) EchoByte(ctx context.Context, arg int8) (r int8, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoI32(ctx context.Context, arg int32) (r int32, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoI64(ctx context.Context, arg int64) (r int64, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoString(ctx context.Context, arg string) (r string, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoList(ctx context.Context, arg []int8) (r []int8, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoSet(ctx context.Context, arg map[int8]struct{}) (r map[int8]struct{}, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
-func (h *handler) EchoMap(ctx context.Context, arg map[int8]int8) (r map[int8]int8, err error) {
-	atomic.AddInt64(&counter, 1)
-	return arg, nil
-}
diff --git a/test/go/src/bin/testclient/go17.go b/test/go/src/bin/testclient/go17.go
deleted file mode 100644
index a6003a9..0000000
--- a/test/go/src/bin/testclient/go17.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// +build go1.7
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package main
-
-import "context"
-
-var defaultCtx = context.Background()
diff --git a/test/go/src/bin/testclient/main.go b/test/go/src/bin/testclient/main.go
index ab24cbf..20104f9 100644
--- a/test/go/src/bin/testclient/main.go
+++ b/test/go/src/bin/testclient/main.go
@@ -21,6 +21,7 @@
 
 import (
 	"common"
+	"context"
 	"flag"
 	"gen/thrifttest"
 	t "log"
@@ -60,6 +61,7 @@
 }
 
 var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "Xception"}
+var defaultCtx = context.Background()
 
 func callEverything(client *thrifttest.ThriftTestClient) {
 	var err error
diff --git a/test/go/src/bin/testclient/pre_go17.go b/test/go/src/bin/testclient/pre_go17.go
deleted file mode 100644
index 10a6fb8..0000000
--- a/test/go/src/bin/testclient/pre_go17.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// +build !go1.7
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package main
-
-import "golang.org/x/net/context"
-
-var defaultCtx = context.Background()
diff --git a/test/go/src/common/clientserver_test.go b/test/go/src/common/clientserver_test.go
index c4cfd44..cb1abf7 100644
--- a/test/go/src/common/clientserver_test.go
+++ b/test/go/src/common/clientserver_test.go
@@ -20,6 +20,7 @@
 package common
 
 import (
+	"context"
 	"errors"
 	"gen/thrifttest"
 	"reflect"
@@ -95,6 +96,7 @@
 }
 
 var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "some"}
+var defaultCtx = context.Background()
 
 func callEverythingWithMock(t *testing.T, client *thrifttest.ThriftTestClient, handler *MockThriftTest) {
 	gomock.InOrder(
diff --git a/test/go/src/common/context_test.go b/test/go/src/common/context_test.go
new file mode 100644
index 0000000..e64dbb9
--- /dev/null
+++ b/test/go/src/common/context_test.go
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package common
+
+import (
+	"context"
+	"fmt"
+	"net"
+	"net/http"
+	"net/url"
+	"os"
+	"syscall"
+	"testing"
+	"thrift"
+	"time"
+)
+
+type slowHttpHandler struct{}
+
+func (slowHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	time.Sleep(1 * time.Second)
+}
+
+func TestHttpContextTimeout(t *testing.T) {
+	certPath = "../../../keys"
+
+	unit := test_unit{"127.0.0.1", 9096, "", "http", "binary", false}
+
+	server := &http.Server{Addr: unit.host + fmt.Sprintf(":%d", unit.port), Handler: slowHttpHandler{}}
+	go server.ListenAndServe()
+
+	client, trans, err := StartClient(unit.host, unit.port, unit.domain_socket, unit.transport, unit.protocol, unit.ssl)
+	if err != nil {
+		t.Errorf("Unable to start client: %v", err)
+		return
+	}
+	defer trans.Close()
+
+	unwrapErr := func(err error) error {
+		for {
+			switch err.(type) {
+			case thrift.TTransportException:
+				err = err.(thrift.TTransportException).Err()
+			case *url.Error:
+				err = err.(*url.Error).Err
+			case *net.OpError:
+				err = err.(*net.OpError).Err
+			case *os.SyscallError:
+				err = err.(*os.SyscallError).Err
+			default:
+				return err
+			}
+		}
+	}
+
+	serverStartupDeadline := time.Now().Add(5 * time.Second)
+	for {
+		ctx, _ := context.WithTimeout(context.Background(), 50*time.Millisecond)
+		err = client.TestVoid(ctx)
+		err = unwrapErr(err)
+		if err != syscall.ECONNREFUSED || time.Now().After(serverStartupDeadline) {
+			break
+		}
+		time.Sleep(time.Millisecond)
+	}
+
+	if err == nil {
+		t.Errorf("Request completed (should have timed out)")
+		return
+	}
+
+	// We've got to switch on `err.Error()` here since go1.7 doesn't properly return
+	// `context.DeadlineExceeded` error and `http.errRequestCanceled` is not exported.
+	// See https://github.com/golang/go/issues/17711
+	switch err.Error() {
+	case context.DeadlineExceeded.Error(), "net/http: request canceled":
+		// Expected error
+	default:
+		t.Errorf("Unexpected error: %s", err)
+	}
+}
diff --git a/test/go/src/common/go17.go b/test/go/src/common/go17.go
deleted file mode 100644
index 9aca407..0000000
--- a/test/go/src/common/go17.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// +build go1.7
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package common
-
-import "context"
-
-var defaultCtx = context.Background()
diff --git a/test/go/src/common/pre_go17.go b/test/go/src/common/pre_go17.go
deleted file mode 100644
index 6c14579..0000000
--- a/test/go/src/common/pre_go17.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// +build !go1.7
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package common
-
-import "golang.org/x/net/context"
-
-var defaultCtx = context.Background()
diff --git a/test/go/src/common/printing_handler.go b/test/go/src/common/printing_handler.go
index c0a2862..2b22d0c 100644
--- a/test/go/src/common/printing_handler.go
+++ b/test/go/src/common/printing_handler.go
@@ -1,5 +1,3 @@
-// +build !go1.7
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
@@ -22,13 +20,12 @@
 package common
 
 import (
+	"context"
+	"encoding/hex"
 	"errors"
 	"fmt"
-	"encoding/hex"
 	. "gen/thrifttest"
 	"time"
-
-	"golang.org/x/net/context"
 )
 
 var PrintingHandler = &printingHandler{}
@@ -280,11 +277,11 @@
 func (p *printingHandler) TestInsanity(ctx context.Context, argument *Insanity) (r map[UserId]map[Numberz]*Insanity, err error) {
 	fmt.Printf("testInsanity()\n")
 	r = make(map[UserId]map[Numberz]*Insanity)
-	r[1] = map[Numberz]*Insanity {
+	r[1] = map[Numberz]*Insanity{
 		2: argument,
 		3: argument,
 	}
-	r[2] = map[Numberz]*Insanity {
+	r[2] = map[Numberz]*Insanity{
 		6: NewInsanity(),
 	}
 	return
diff --git a/test/go/src/common/printing_handler_go17.go b/test/go/src/common/printing_handler_go17.go
deleted file mode 100644
index 1efae86..0000000
--- a/test/go/src/common/printing_handler_go17.go
+++ /dev/null
@@ -1,386 +0,0 @@
-// +build go1.7
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package common
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"encoding/hex"
-	. "gen/thrifttest"
-	"time"
-)
-
-var PrintingHandler = &printingHandler{}
-
-type printingHandler struct{}
-
-// Prints "testVoid()" and returns nothing.
-func (p *printingHandler) TestVoid(ctx context.Context) (err error) {
-	fmt.Println("testVoid()")
-	return nil
-}
-
-// Prints 'testString("%s")' with thing as '%s'
-// @param string thing - the string to print
-// @return string - returns the string 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestString(ctx context.Context, thing string) (r string, err error) {
-	fmt.Printf("testString(\"%s\")\n", thing)
-	return thing, nil
-}
-
-// Prints 'testBool("%t")' with thing as 'true' or 'false'
-// @param bool thing - the bool to print
-// @return bool - returns the bool 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestBool(ctx context.Context, thing bool) (r bool, err error) {
-	fmt.Printf("testBool(%t)\n", thing)
-	return thing, nil
-}
-
-// Prints 'testByte("%d")' with thing as '%d'
-// @param byte thing - the byte to print
-// @return byte - returns the byte 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestByte(ctx context.Context, thing int8) (r int8, err error) {
-	fmt.Printf("testByte(%d)\n", thing)
-	return thing, nil
-}
-
-// Prints 'testI32("%d")' with thing as '%d'
-// @param i32 thing - the i32 to print
-// @return i32 - returns the i32 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestI32(ctx context.Context, thing int32) (r int32, err error) {
-	fmt.Printf("testI32(%d)\n", thing)
-	return thing, nil
-}
-
-// Prints 'testI64("%d")' with thing as '%d'
-// @param i64 thing - the i64 to print
-// @return i64 - returns the i64 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestI64(ctx context.Context, thing int64) (r int64, err error) {
-	fmt.Printf("testI64(%d)\n", thing)
-	return thing, nil
-}
-
-// Prints 'testDouble("%f")' with thing as '%f'
-// @param double thing - the double to print
-// @return double - returns the double 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestDouble(ctx context.Context, thing float64) (r float64, err error) {
-	fmt.Printf("testDouble(%f)\n", thing)
-	return thing, nil
-}
-
-// Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data
-// @param []byte thing - the binary to print
-// @return []byte - returns the binary 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestBinary(ctx context.Context, thing []byte) (r []byte, err error) {
-	fmt.Printf("testBinary(%s)\n", hex.EncodeToString(thing))
-	return thing, nil
-}
-
-// Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values
-// @param Xtruct thing - the Xtruct to print
-// @return Xtruct - returns the Xtruct 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestStruct(ctx context.Context, thing *Xtruct) (r *Xtruct, err error) {
-	fmt.Printf("testStruct({\"%s\", %d, %d, %d})\n", thing.StringThing, thing.ByteThing, thing.I32Thing, thing.I64Thing)
-	return thing, err
-}
-
-// Prints 'testNest("{%s}")' where thing has been formatted into a string of the nested struct
-// @param Xtruct2 thing - the Xtruct2 to print
-// @return Xtruct2 - returns the Xtruct2 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestNest(ctx context.Context, nest *Xtruct2) (r *Xtruct2, err error) {
-	thing := nest.StructThing
-	fmt.Printf("testNest({%d, {\"%s\", %d, %d, %d}, %d})\n", nest.ByteThing, thing.StringThing, thing.ByteThing, thing.I32Thing, thing.I64Thing, nest.I32Thing)
-	return nest, nil
-}
-
-// Prints 'testMap("{%s")' where thing has been formatted into a string of  'key => value' pairs
-//  separated by commas and new lines
-// @param map<i32,i32> thing - the map<i32,i32> to print
-// @return map<i32,i32> - returns the map<i32,i32> 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestMap(ctx context.Context, thing map[int32]int32) (r map[int32]int32, err error) {
-	fmt.Printf("testMap({")
-	first := true
-	for k, v := range thing {
-		if first {
-			first = false
-		} else {
-			fmt.Printf(", ")
-		}
-		fmt.Printf("%d => %d", k, v)
-	}
-	fmt.Printf("})\n")
-	return thing, nil
-}
-
-// Prints 'testStringMap("{%s}")' where thing has been formatted into a string of  'key => value' pairs
-//  separated by commas and new lines
-// @param map<string,string> thing - the map<string,string> to print
-// @return map<string,string> - returns the map<string,string> 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestStringMap(ctx context.Context, thing map[string]string) (r map[string]string, err error) {
-	fmt.Printf("testStringMap({")
-	first := true
-	for k, v := range thing {
-		if first {
-			first = false
-		} else {
-			fmt.Printf(", ")
-		}
-		fmt.Printf("%s => %s", k, v)
-	}
-	fmt.Printf("})\n")
-	return thing, nil
-}
-
-// Prints 'testSet("{%s}")' where thing has been formatted into a string of  values
-//  separated by commas and new lines
-// @param set<i32> thing - the set<i32> to print
-// @return set<i32> - returns the set<i32> 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestSet(ctx context.Context, thing []int32) (r []int32, err error) {
-	fmt.Printf("testSet({")
-	first := true
-	for k, _ := range thing {
-		if first {
-			first = false
-		} else {
-			fmt.Printf(", ")
-		}
-		fmt.Printf("%d", k)
-	}
-	fmt.Printf("})\n")
-	return thing, nil
-}
-
-// Prints 'testList("{%s}")' where thing has been formatted into a string of  values
-//  separated by commas and new lines
-// @param list<i32> thing - the list<i32> to print
-// @return list<i32> - returns the list<i32> 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestList(ctx context.Context, thing []int32) (r []int32, err error) {
-	fmt.Printf("testList({")
-	for i, v := range thing {
-		if i != 0 {
-			fmt.Printf(", ")
-		}
-		fmt.Printf("%d", v)
-	}
-	fmt.Printf("})\n")
-	return thing, nil
-}
-
-// Prints 'testEnum("%d")' where thing has been formatted into it's numeric value
-// @param Numberz thing - the Numberz to print
-// @return Numberz - returns the Numberz 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestEnum(ctx context.Context, thing Numberz) (r Numberz, err error) {
-	fmt.Printf("testEnum(%d)\n", thing)
-	return thing, nil
-}
-
-// Prints 'testTypedef("%d")' with thing as '%d'
-// @param UserId thing - the UserId to print
-// @return UserId - returns the UserId 'thing'
-//
-// Parameters:
-//  - Thing
-func (p *printingHandler) TestTypedef(ctx context.Context, thing UserId) (r UserId, err error) {
-	fmt.Printf("testTypedef(%d)\n", thing)
-	return thing, nil
-}
-
-// Prints 'testMapMap("%d")' with hello as '%d'
-// @param i32 hello - the i32 to print
-// @return map<i32,map<i32,i32>> - returns a dictionary with these values:
-//   {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, }
-//
-// Parameters:
-//  - Hello
-func (p *printingHandler) TestMapMap(ctx context.Context, hello int32) (r map[int32]map[int32]int32, err error) {
-	fmt.Printf("testMapMap(%d)\n", hello)
-
-	r = map[int32]map[int32]int32{
-		-4: map[int32]int32{-4: -4, -3: -3, -2: -2, -1: -1},
-		4:  map[int32]int32{4: 4, 3: 3, 2: 2, 1: 1},
-	}
-	return
-}
-
-// So you think you've got this all worked, out eh?
-//
-// Creates a the returned map with these values and prints it out:
-//   { 1 => { 2 => argument,
-//            3 => argument,
-//          },
-//     2 => { 6 => <empty Insanity struct>, },
-//   }
-// @return map<UserId, map<Numberz,Insanity>> - a map with the above values
-//
-// Parameters:
-//  - Argument
-func (p *printingHandler) TestInsanity(ctx context.Context, argument *Insanity) (r map[UserId]map[Numberz]*Insanity, err error) {
-	fmt.Printf("testInsanity()\n")
-	r = make(map[UserId]map[Numberz]*Insanity)
-	r[1] = map[Numberz]*Insanity {
-		2: argument,
-		3: argument,
-	}
-	r[2] = map[Numberz]*Insanity {
-		6: NewInsanity(),
-	}
-	return
-}
-
-// Prints 'testMulti()'
-// @param byte arg0 -
-// @param i32 arg1 -
-// @param i64 arg2 -
-// @param map<i16, string> arg3 -
-// @param Numberz arg4 -
-// @param UserId arg5 -
-// @return Xtruct - returns an Xtruct with StringThing = "Hello2, ByteThing = arg0, I32Thing = arg1
-//    and I64Thing = arg2
-//
-// Parameters:
-//  - Arg0
-//  - Arg1
-//  - Arg2
-//  - Arg3
-//  - Arg4
-//  - Arg5
-func (p *printingHandler) TestMulti(ctx context.Context, arg0 int8, arg1 int32, arg2 int64, arg3 map[int16]string, arg4 Numberz, arg5 UserId) (r *Xtruct, err error) {
-	fmt.Printf("testMulti()\n")
-	r = NewXtruct()
-
-	r.StringThing = "Hello2"
-	r.ByteThing = arg0
-	r.I32Thing = arg1
-	r.I64Thing = arg2
-	return
-}
-
-// Print 'testException(%s)' with arg as '%s'
-// @param string arg - a string indication what type of exception to throw
-// if arg == "Xception" throw Xception with errorCode = 1001 and message = arg
-// elsen if arg == "TException" throw TException
-// else do not throw anything
-//
-// Parameters:
-//  - Arg
-func (p *printingHandler) TestException(ctx context.Context, arg string) (err error) {
-	fmt.Printf("testException(%s)\n", arg)
-	switch arg {
-	case "Xception":
-		e := NewXception()
-		e.ErrorCode = 1001
-		e.Message = arg
-		return e
-	case "TException":
-		return errors.New("Just TException")
-	}
-	return
-}
-
-// Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s'
-// @param string arg - a string indication what type of exception to throw
-// if arg0 == "Xception" throw Xception with errorCode = 1001 and message = "This is an Xception"
-// elsen if arg0 == "Xception2" throw Xception2 with errorCode = 2002 and message = "This is an Xception2"
-// else do not throw anything
-// @return Xtruct - an Xtruct with StringThing = arg1
-//
-// Parameters:
-//  - Arg0
-//  - Arg1
-func (p *printingHandler) TestMultiException(ctx context.Context, arg0 string, arg1 string) (r *Xtruct, err error) {
-	fmt.Printf("testMultiException(%s, %s)\n", arg0, arg1)
-	switch arg0 {
-
-	case "Xception":
-		e := NewXception()
-		e.ErrorCode = 1001
-		e.Message = "This is an Xception"
-		return nil, e
-	case "Xception2":
-		e := NewXception2()
-		e.ErrorCode = 2002
-		e.StructThing = NewXtruct()
-		e.StructThing.StringThing = "This is an Xception2"
-		return nil, e
-	default:
-		r = NewXtruct()
-		r.StringThing = arg1
-		return
-	}
-}
-
-// Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d'
-// sleep 'secondsToSleep'
-// Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d'
-// @param i32 secondsToSleep - the number of seconds to sleep
-//
-// Parameters:
-//  - SecondsToSleep
-func (p *printingHandler) TestOneway(ctx context.Context, secondsToSleep int32) (err error) {
-	fmt.Printf("testOneway(%d): Sleeping...\n", secondsToSleep)
-	time.Sleep(time.Second * time.Duration(secondsToSleep))
-	fmt.Printf("testOneway(%d): done sleeping!\n", secondsToSleep)
-	return
-}
